Segmentation fault in /usr/lib/aarch64-linux-gnu/tegra/libnvidia-eglcore.so.28.2.1

JetPack 3.2.1

I have a TX2 with GLX display output rendering, and also with an off screen Pbuffer renderer, doing some shader based image manipulation, but using EGL.

This seems to work from application start-up quite well. The off screen render creates an output image which is read back using a PBO mapping with memcpy. Further CPU based modifications are then done and the image is passed to the display system, where it outputs exactly what I would expect to see.

The thread doing the Pbuffer rendering is, from time-to-time, killed off as it’s no longer used, but the application keeps running. At this point the threads C++ class cleans up all it’s buffers, textures, surfaces and contexts.

The thread is then rebuilt later and goes through the exact same startup sequence as the first time.

The calls to get the display, initialise EGL, bind the API, choose a pBuffer compatible configuration, create a Pbuffer surface and finally to create a context all return without error (0x3000 = SUCCESS) just like the first time.

But, the the call to make the context current blows up with the below stack trace. I’ve no idea how I can debug this any further. The graphics debugger doesn’t help - since the app uses a mix of EGL and GLX, it stops the session as soon as the first GLX call is made (in the display subsystem).

To be clear, this all works, once, but on the second attempt it segfaults.

Are there any methods I can use to resolve this issue? Is it reasonable to use EGL and GLX in the same application?

Here’s the stack trace:

[Switching to Thread 0x7f499df1e0 (LWP 14164)]
0x0000007f882f1cf8 in ?? () from /usr/lib/aarch64-linux-gnu/tegra/libnvidia-eglcore.so.28.2.1
(gdb) bt
#0 0x0000007f882f1cf8 in ?? () from /usr/lib/aarch64-linux-gnu/tegra/libnvidia-eglcore.so.28.2.1
#1 0x0000007f882f510c in ?? () from /usr/lib/aarch64-linux-gnu/tegra/libnvidia-eglcore.so.28.2.1
#2 0x0000007f883072cc in ?? () from /usr/lib/aarch64-linux-gnu/tegra/libnvidia-eglcore.so.28.2.1
#3 0x0000007f882edf4c in ?? () from /usr/lib/aarch64-linux-gnu/tegra/libnvidia-eglcore.so.28.2.1
#4 0x0000007f883043f8 in ?? () from /usr/lib/aarch64-linux-gnu/tegra/libnvidia-eglcore.so.28.2.1
#5 0x0000007f882ee604 in ?? () from /usr/lib/aarch64-linux-gnu/tegra/libnvidia-eglcore.so.28.2.1
#6 0x0000007f882f66f8 in ?? () from /usr/lib/aarch64-linux-gnu/tegra/libnvidia-eglcore.so.28.2.1
#7 0x0000007f88304c30 in ?? () from /usr/lib/aarch64-linux-gnu/tegra/libnvidia-eglcore.so.28.2.1
#8 0x0000007f8736195c in ?? () from /usr/lib/aarch64-linux-gnu/tegra-egl/libGLESv1_CM_nvidia.so.1
#9 0x0000007f9712b664 in ?? () from /usr/lib/aarch64-linux-gnu/tegra-egl/libEGL_nvidia.so.0
#10 0x0000007f9712c6d8 in ?? () from /usr/lib/aarch64-linux-gnu/tegra-egl/libEGL_nvidia.so.0
#11 0x0000007f97133074 in ?? () from /usr/lib/aarch64-linux-gnu/tegra-egl/libEGL_nvidia.so.0
#12 0x0000007f9735dfbc in eglMakeCurrent () from /usr/lib/aarch64-linux-gnu/tegra-egl/libEGL.so.1
#13 0x0000007f8ef663d4 in cHiddenContextEGL::Create (this=0x7f1829a660, nRequestedWidth=1280, nRequestedHeight=720) at cFusion.cpp:374

I snipped off the stack frames that would mean little to anyone else.

Thanks,
Ratbert.

You may need to share the source. May I know why do you need to mix GLX+ EGL?

I think GLX itself already had something like glXMakeCurrent and glxswapbuffer, why you still need EGL?

The reason for EGL here is that the module might be shared with another embedded platform the only supports EGL. Is there some reason you think mixing EGL/GLX usage is a problem? If the fix is, not to do that then I can change the code of course.

Note that the first EGL setup is before the GLX based display sub-system is brought up. The display is kept until application shutdown, so the second set up of the EGL shader processing is done with the active display system in use. This is why I wondered if mixing and match is expected to be problematic.

The context setup looks like (sorry it’s a bit of a mess while I’m debugging it):

m_eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
std::cerr << "eglGetDisplay failed: " << std::hex << eglGetError() << std::endl;

EGLint major, minor;
eglInitialize(m_eglDpy, &major, &minor);
std::cerr << "eglInitialize failed: " << std::hex << eglGetError() << std::endl;

eglBindAPI(EGL_OPENGL_API);
std::cerr << "eglBindAPI failed: " << std::hex << eglGetError() << std::endl;

EGLint numConfigs;
EGLConfig eglCfg;

EGLint pConfigAttribs = {
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_CONFORMANT, EGL_OPENGL_ES2_BIT,
EGL_NONE,
};
eglChooseConfig(m_eglDpy, pConfigAttribs, &eglCfg, 1, &numConfigs);
std::cout << "EGL configs: " << numConfigs << std::endl;
std::cerr << "eglChooseConfig failed: " << std::hex << eglGetError() << std::endl;

EGLint configAttribs = {
EGL_WIDTH, 2048,
EGL_HEIGHT, 2048,
EGL_NONE
};
m_eglSurf = eglCreatePbufferSurface(m_eglDpy, eglCfg, configAttribs);
if (m_eglSurf == EGL_NO_SURFACE) std::cerr << "Surface failed: " << std::hex << eglGetError() << std::endl;

EGLint contextAttribs = {
EGL_CONTEXT_MAJOR_VERSION, 2,
EGL_CONTEXT_MINOR_VERSION, 0,
EGL_CONTEXT_OPENGL_DEBUG, EGL_TRUE,
EGL_CONTEXT_OPENGL_ROBUST_ACCESS, EGL_TRUE,
EGL_NONE
};
m_eglCtx = eglCreateContext(m_eglDpy, eglCfg, EGL_NO_CONTEXT, contextAttribs);
if (m_eglCtx == EGL_NO_CONTEXT) throw std::runtime_error(“No Context for Fusion”);

std::cerr << "Check failed: " << std::hex << eglGetError() << std::endl;
if (!eglMakeCurrent(m_eglDpy, m_eglSurf, m_eglSurf, m_eglCtx))
throw std::runtime_error(WAYPOINT + “context not set”);

The tear down looks like:

eglMakeCurrent(m_eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
std::cerr << "eglMakeCurrent failed: " << std::hex << eglGetError() << std::endl;

if (m_eglSurf)
{
eglDestroySurface(m_eglDpy, m_eglSurf);
std::cerr << "eglDestroySurface failed: " << std::hex << eglGetError() << std::endl;
}

if (m_eglCtx)
{
eglDestroyContext(m_eglDpy, m_eglCtx);
std::cerr << "eglDestroyContext failed: " << std::hex << eglGetError() << std::endl;
}

eglTerminate(m_eglDpy);
std::cerr << "eglTerminate failed: " << std::hex << eglGetError() << std::endl;

Thanks,
Ratbert

I don’t see the usage of GLX in your code snippet. Could you refer to our multimedia API sample (MMAPI sample) to see if you could leverage anything?

That’s true, but it is the eglMakeCurrent above that fails second time though. The display render is based on glew and glfw:

glfwSetErrorCallback(glfwErrorCallback);

if (!glfwInit())
{
std::cerr << “display system init failed” << std::endl;
return false;
}

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

if (stDisplay.bFullScreen)
{

  m_monitor = glfwGetPrimaryMonitor();
  if (!m_monitor)
  {
     std::cerr << "get monitor failed" << std::endl;
     return false;
  }

  const GLFWvidmode* mode = glfwGetVideoMode(m_monitor);
  if (!mode)
  {
     std::cerr << "get video mode failed" << std::endl;
     return false;
  }

  m_ctxWidth = mode->width;
  m_ctxHeight = mode->height;

  glfwWindowHint(GLFW_RED_BITS, mode->redBits);
  glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits);
  glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits);
  glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate);

}
else
{
m_ctxWidth = stDisplay.stSize.X;
m_ctxHeight = stDisplay.stSize.Y;
}

glfwWindowHint(GLFW_AUTO_ICONIFY, 0);
glfwWindowHint(GLFW_DECORATED, 0);

m_ctxWindow = glfwCreateWindow(m_ctxWidth, m_ctxHeight, stDisplay.sName.c_str(), m_monitor, nullptr);
if (!m_ctxWindow)
{
std::cerr << “create window failed” << std::endl;
return false;
}

glfwMakeContextCurrent(m_ctxWindow);

glewExperimental = GL_TRUE; // to enable GL 3.2+ core context needed for shader code
glErr = glewInit();
if (glErr != GL_NO_ERROR)
{
std::cerr << "glewInit failed: " << glErr << " " << glewGetErrorString(glErr) << std::endl;
unlockContext();
return false;
}

glfwMakeContextCurrent(nullptr);