0

I'm trying to strip some GLX window/context creation code out of a statically-compiled binary and into a shared lib. The same code which works fine in the static version crashes in the shared lib version on the first call to any glX-prefixed function. As a minimal (non)working example, here's 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);
}

When I compile as an executable

g++ -o miniglx miniglx.cpp -lGL -lX11

and run ./miniglx, it prints glX version 1.4 as expected.

However, when I compile as a shared lib

g++ -fPIC -shared -o libminiglx.so src/miniglx.cpp -lGL -lX11

and try to dlopen it in another program and call print_glx_version, it crashes. Running in gdb shows that the crash occurs in the call to glXQueryVersion and prints the message

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.

The shared lib compiles and links fine, and ldd shows it seems to link to 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)

The one possible difference between the two situations (static vs dynamic) is that in the static lib case I'm not dlopening the lib on the main thread (I have no control over this). Is there some problem with doing glX window/context management stuff on other threads?

I'm on Ubuntu 14.04 LTS, with a NVIDIA Corporation GT200GL [Quadro FX 5800] (rev a1) GPU. The behaviour exist with both the mesa and nvidia graphics drivers. glxinfo | head returns

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, 
Ben
  • 843
  • 8
  • 21

0 Answers0