Segfault when transferring OpenGL context to another thread

In our application we first create the OpenGL context (through GLFW) in the main thread and initialize a CUDA context with it. We then remove the OpenGL context from the main thread with:

glfwMakeContextCurrent(NULL)

After that the OpenGL context is made current on another thread with:

glfwMakeContextCurrent(window)

This works fine on my PC, but segfaults on the Jetson TX1 inside the glXMakeCurrent function of libGL.so.1. Which makes it seem like a bug in the libGL library.

The backtrace:

0    ??    /usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1        0xf561e0f8   
1    ??    /usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1        0xf55f0fe2   
2    ??    /usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1        0xf55f17e2   
3    ??    /usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1        0xf55ece80   
4    ??    /usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1        0xf55ee4be   
5    glXMakeCurrent    /usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1        0xf55e8618   
6    _glfwPlatformMakeContextCurrent    /usr/local/lib/libglfw.so.3        0xf77c441c   
7    makeCurrentCUDAGLContext    virtcamTegra.cpp    27    0xd2914   
8    std::_Bind<void (*(GLFWwindow*, CuBackend*))(GLFWwindow*, CuBackend*)>::__call<void, , 0u, 1u>(std::tuple<>&&, std::_Index_tuple<0u, 1u>)    functional    1296    0xd5a72   
9    std::_Bind<void (*(GLFWwindow*, CuBackend*))(GLFWwindow*, CuBackend*)>::operator()<, void>()    functional    1355    0xd5626   
10    std::_Function_handler<void (), std::_Bind<void (*(GLFWwindow*, CuBackend*))(GLFWwindow*, CuBackend*)> >::_M_invoke(std::_Any_data const&)    functional    2071    0xd512e   
11    std::function<void ()>::operator()() const    functional    2471    0xdae44   
12    DedicatedTaskPool::thread_run    task.cpp    619    0xda3ac   
13    std::_Mem_fn<void (DedicatedTaskPool::*)()>::operator()<, void>(DedicatedTaskPool*) const    functional    601    0xe0702   
14    std::_Bind<std::_Mem_fn<void (DedicatedTaskPool::*)()> (DedicatedTaskPool*)>::__call<void, , 0u>(std::tuple<>&&, std::_Index_tuple<0u>)    functional    1296    0xe05ac   
15    std::_Bind<std::_Mem_fn<void (DedicatedTaskPool::*)()> (DedicatedTaskPool*)>::operator()<, void>()    functional    1355    0xe04fe   
16    std::_Bind_simple<std::_Bind<std::_Mem_fn<void (DedicatedTaskPool::*)()> (DedicatedTaskPool*)> ()>::_M_invoke<>(std::_Index_tuple<>)    functional    1732    0xe038a   
17    std::_Bind_simple<std::_Bind<std::_Mem_fn<void (DedicatedTaskPool::*)()> (DedicatedTaskPool*)> ()>::operator()()    functional    1720    0xe026c   
18    std::thread::_Impl<std::_Bind_simple<std::_Bind<std::_Mem_fn<void (DedicatedTaskPool::*)()> (DedicatedTaskPool*)> ()> >::_M_run()    thread    115    0xe015e   
19    ??    /usr/lib/arm-linux-gnueabihf/libstdc++.so.6        0xf688c854

Please contact me if you need any more information.

EDIT: It of course was glfwMakeContextCurrent

I assume you mean glfwMakeContextCurrent, not glfwMakeCurrentContext. See:
http://www.glfw.org/docs/latest/group__context.html
http://www.glfw.org/docs/latest/group__context.html#ga1c04dc242268f827290fe40aa1c91157

This is just a shot in the dark, but I see the function normally flushes the pipeline upon release. There is a window hint which might be available and alter this, so how the flushing occurs could change depending on which machine you are working with.

One possibility is that the other thread is using the context prior to the flush completing. Just as a test, perhaps sleep a few seconds before using the recently released context.

The other possibility…check out the window hints and see if there is a difference between the other machine and the TX1 due to this.