我正在尝试从静态编译的二进制文件中剥离一些 GLX 窗口/上下文创建代码并放入共享库中。glX
在第一次调用任何带前缀的函数时,在静态版本中运行良好的相同代码在共享库版本中崩溃。作为一个最小(非)工作示例,这里是 miniglx.cpp
:
#include <stdio.h>
#include <stdlib.h>
#include <GL/glx.h>
extern "C"{
void print_glx_version();
int main(int argc, char* argv[]);
}
void print_glx_version()
{
const char displayID[] = ":0.0";
Display *display = XOpenDisplay(displayID);
if (!display)
{
printf("Failed to open X display\n");
}
int glx_major, glx_minor;
int res = glXQueryVersion(display, &glx_major, &glx_minor);
{
printf("glX version %d.%d\n", glx_major, glx_minor);
}
}
int main(int argc, char* argv[]){
print_glx_version();
exit(0);
}
当我编译为可执行文件时
g++ -o miniglx miniglx.cpp -lGL -lX11
并运行,它按预期./miniglx
打印。glX version 1.4
但是,当我编译为共享库时
g++ -fPIC -shared -o libminiglx.so src/miniglx.cpp -lGL -lX11
并尝试dlopen
在另一个程序中调用
print_glx_version
它,它崩溃了。运行中gdb
显示崩溃发生在调用glXQueryVersion
并打印消息
Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffecdf6700 (LWP 8774)]
0x00007ffff69a6bb9 in __GI_raise (sig=sig@entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
共享库编译和链接很好,并ldd
显示它似乎链接到libGL.so
and libX11.so
:
bash$ ldd libminiglx.so
linux-vdso.so.1 => (0x00007ffff774f000)
libGL.so.1 => /usr/lib/nvidia-340/libGL.so.1 (0x00007f94c835a000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f94c8025000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f94c7c5e000)
libnvidia-tls.so.340.32 => /usr/lib/nvidia-340/tls/libnvidia-tls.so.340.32 (0x00007f94c7a5b000)
libnvidia-glcore.so.340.32 => /usr/lib/nvidia-340/libnvidia-glcore.so.340.32 (0x00007f94c4e48000)
libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f94c4c35000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f94c4a31000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f94c4812000)
/lib64/ld-linux-x86-64.so.2 (0x00007f94c88c4000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f94c450b000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f94c4307000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f94c4101000)
两种情况(静态与动态)之间的一个可能区别是,在静态库的情况下,我没有dlopen
在主线程上运行库(我无法控制这一点)。在其他线程上做 glX 窗口/上下文管理有什么问题吗?
我在带有NVIDIA Corporation GT200GL
[Quadro FX 5800] (rev a1)
GPU 的 Ubuntu 14.04 LTS 上。mesa 和 nvidia 图形驱动程序都存在这种行为。glxinfo | head
返回
name of display: :0
display: :0 screen: 0
direct rendering: Yes
server glx vendor string: NVIDIA Corporation
server glx version string: 1.4
server glx extensions:
GLX_ARB_create_context, GLX_ARB_create_context_profile,
GLX_ARB_create_context_robustness, GLX_ARB_fbconfig_float,
GLX_ARB_multisample, GLX_EXT_buffer_age,
GLX_EXT_create_context_es2_profile, GLX_EXT_create_context_es_profile,