7

I'm trying to figure out how to load two different versions of libstdc++.so on a SLES10 machine. My client has a process Foo, which is built with GCC 4.1.2, and thus uses the 6.0.8 version of libstdc++.so. We are also building shared library called libBar.so. This library will be dynamically loaded by Foo at runtime. libBar.so is compiled using GCC 4.3.6, and libstdc++ version 6.0.10.

Currently, when I try to have Foo load libBar.so, I get the following error.

error: unable to load shared object '/usr/lib64/libBar.so': /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by /usr/lib64/libBar.so)

At the moment, the only way that I can get this to work is to change my library load order (via ld.so.conf) so that Foo and libbar.so both load the same (6.0.10) libstdc++.so. However, this isn't a vialbe solution, since it requires that I modify the client's system.

What I'd like to do is have Foo load it's verions of libstdc++.so and libBar.so link to it's own version of libstdc++.so, but I can't figure out how to write my Makefile to make that happen. Here's what I have so far, for my LIBADD line in Makefile.am...

libBar_la_LIBADD = ../../vendor/SLES10/lib/libstdc++.so.6.0.10

Which I would assume would like to that SPECIFIC version of libstdc++.so. However, when I run ldd against the fully compiled and linked libBar.so, this is the line I see...

libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002aaaaeac5000)

Why isn't it linking specifically to libstdc++.so.6.0.10? What should I be doing instead?

jmartenstein
  • 71
  • 1
  • 3
  • 1
    You don't want to load 2 versions of libstdc++ in the same process, the goal really is to make sure the version loaded is the newer one. – Marc Glisse Feb 14 '14 at 16:20
  • I had the same problem with exact same versions (RHEL 5, no?) and the comment by @MadScientist worked for me. – Michael Fox Jul 10 '15 at 17:29

1 Answers1

11

I had a similar issue with a 3rd-party library that used an obsolete version of libstdc++.

I solved it by pre-linking the 3rd-party library statically with that old version of libstdc++. The end result was another shared library that did not have unresolved libstdc++ symbols. The command line was something like this:

ld --relocatable -o lib3rd-party-prelinked.so lib3rd-party.so /usr/lib64/libstdc++.a.6

And then I used lib3rd-party-prelinked.so instead of lib3rd-party.so. (Lookup --relocatable in man ld).

It was possible in my case because the 3rd-party library exposed a C API, no C++ standard library components were used in its interface.

If your 3rd-party library exposes C++ standard library classes in its interface whose ABIs are different between these libstdc++ versions, that is not going to work. E.g. your application passes a std::list<> with the new ABI to the 3rd-party library that expects a std::list<> with the old ABI version. Even if it links, that will cause undefined behaviour at run-time.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • 4
    This is very good info. One additional note: if you're building your own library using GCC, you can add `-static-libgcc -static-libstdc++` to your link line to have GCC pull in static versions of these into your shared library. However as Maxim says, this ONLY works if you don't need to pass STL objects across the shared library boundary. If you do, and the two STL implementations are not compatible, you're SOL. Luckily the GCC STL had not had an ABI compatibility break in a very long time. – MadScientist Feb 14 '14 at 18:49
  • So the C-ABI worked as a kind of barrier between the two versions of the lib? Is there also a solution while keeping the shared libs? I imagine to have heard something like this many years ago, and I have some weak memory that they also used a C-library as border. Would it also work with dlopen() ? – karsten Jun 01 '18 at 14:34
  • @karsten Heavy questions for a comment, you may like to post your own question. – Maxim Egorushkin Jun 01 '18 at 14:51