Created attachment 36802 [details] Minimal reproducer Loading two shared libraries compiled with identical flags and the same compiler into the same process using dlopen breaks the use of std::stringstream (and probably more) when they link libstdc++ statically using "-static-libstdc++". This was reproducible for me using gcc 5.1.1 (old abi), gcc 5.2.1 (Ubuntu 15.10, new abi) and gcc-5-branch (r230629, new abi) with the attached minimal reproducer and did not occur in gcc 4.9. The reproducer consists of a small C program (no C++ dependencies) which uses dlopen to load two practically identical .so's which perform a trivial stringstream operation. The reproducer .so's do this operation on-load but that's not relevant for the issue. I'm unsure on whether this kind of breakage is expected or if this is an actual bug with libstdc++. I originally encountered it when loading multiple .so's using System.loadLibrary into a JVM. Below is the README of the reproducer with some more information: Requires: - g++-5 - Some gcc (5 is fine) How to reproduce: - Run ./build.sh - Run ./test Expected: $ ./test dlopen x.so X0 dlopen y.so X1 What happens: $ ./test dlopen x.so X0 dlopen y.so terminate called after throwing an instance of 'std::bad_cast' what(): std::bad_cast Aborted (core dumped) Does not occur when: * Linking libstdc++ dynamically * Not dynloading the .so's but instead using gcc to link them in * LD_PRELOAD'ing libstdc++ * Building the .so's with gcc 4.9 instead of 5.1.1
Confirmed. I don't think this is intended to work when you re-export the libstdc++ symbols. Not sure if there is an easy way to make them hidden with --begin-group/--end-group and a linker flag. So you'd need to provide a version script to the link of x.so and y.so.
Interesting. So this breakage is expected behavior? I wasn't sure as there were so many ways to load it differently that didn't seem to exhibit the problems. I assume the ones I listed (except linking libstdc++ dynamically everywhere to begin with) are equally forbidden? Or in other words: Never use -static-libstdc++ in combination with -shared if you actually need C++ objects shared between the so's and hence cannot hide or version the symbols? Would be very useful if libstdc++ could somehow make such conflicts more explicit when they occur (e.g. ideally making the dynamic linker fail or even terminating the program outright). I naively assumed I would be fine as long as I didn't start mixing libstdc++ versions and all I would incur was some duplicate code that simply wouldn't be used and did so until I starting seing very strange runtime breakages.
I think there is another bug about this that was closed as invalid as you need to use the version script to hide all of libstdc++ symbols.