c++linkersegmentation-faulthydra

Segfault due to name collision from third party library


I'm trying to use a proprietary sdk from sixense (driver for a game controller). It looks like they statically link to boost::thread. My application and some of its dependencies also use boost::thread, and I get a segfault.

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7bd1bb5 in boost::thread::start_thread() () from /usr/lib/libboost_thread.so.1.42.0
(gdb) bt
#0  0x00007ffff7bd1bb5 in boost::thread::start_thread() () from /usr/lib/libboost_thread.so.1.42.0
#1  0x00007ffff79869bb in USBDetector::start_hotplug_thread() ()
   from /home/joschu/Downloads/sixenseSDK_linux_OSX/samples/linux_x64/sixense_simple3d/libsixense_x64.so
#2  0x00007ffff7986c7e in USBDetector::start(std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<std::vector<unsigned int, std::allocator<unsigned int> >, std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > >, std::vector<unsigned int, std::allocator<unsigned int> >) () from /home/joschu/Downloads/sixenseSDK_linux_OSX/samples/linux_x64/sixense_simple3d/libsixense_x64.so
#3  0x00007ffff7987298 in USBManagerLinux::start(std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<std::vector<unsigned int, std::allocator<unsigned int> >, std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > >, std::vector<unsigned int, std::allocator<unsigned int> >, int) () from /home/joschu/Downloads/sixenseSDK_linux_OSX/samples/linux_x64/sixense_simple3d/libsixense_x64.so
#4  0x00007ffff79842f3 in USBManager::start(std::vector<unsigned int, std::allocator<unsigned int> >, std::vector<std::vector<unsigned int, std::allocator<unsigned int> >, std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > >, std::vector<unsigned int, std::allocator<unsigned int> >, int) () from /home/joschu/Downloads/sixenseSDK_linux_OSX/samples/linux_x64/sixense_simple3d/libsixense_x64.so
#5  0x00007ffff79a03d6 in DriverMain::start(int) ()
   from /home/joschu/Downloads/sixenseSDK_linux_OSX/samples/linux_x64/sixense_simple3d/libsixense_x64.so
#6  0x00007ffff79a1e32 in sixenseInit ()
   from /home/joschu/Downloads/sixenseSDK_linux_OSX/samples/linux_x64/sixense_simple3d/libsixense_x64.so
#7  0x0000000000400d0d in main () at /home/joschu/bulletsim/src/hydra/hi.cpp:6

If I switch around the way the project is linked, I found that my other libraries end up calling sixense's boost::thread.

Is there any way around this issue?


Solution

  • It looks like they statically link to boost::thread

    You didn't say what they statically linked boost::thread into. I'll assume they linked it into libsixense_x64.so.

    There are several general ways to avoid the name collision:

    1. Ask the sdk developers to clean up their act. What they should have done is link boost in statically and hide that fact, e.g. by compiling with -fvisibility=hidden, and only exporting their intended interface, rather than exporting everything (which is what it sounds they did).
    2. If you can't force the sdk developers to clean up, you can load their sdk library via dlopen with RTLD_LOCAL binding. This makes it a little awkward to use the sdk, but should keep its symbols from the global dynamic linker namespace.
    3. Finally, for completeness: if you are on Linux (which your message suggests but does not state), you can use dlmopen to load the sdk into a completely separate dynamic linker namespace. I don't see any advantage compared to option 2, and there are several disadvantages.