0

我正在尝试从静态编译的二进制文件中剥离一些 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.soand 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, 
4

0 回答 0