2

Suppose an application myapp.exe is built using g++ and it uses the flag -static-libstdc++ so that it can be installed in enviroments without libstdc++.so. myapp.exe also adds plugin support for some function plugf that can be dynamically loading via dlopen from a shard library.

If libplug.so is such a plugin library that also links to libstdc++, how can it do so in a way to be able to work with myapp.exe?

This is straightforward if libstdc++ is linked in dynamically since both myapp.exe and libplug.so can use the same dynamically loaded standard library, but it's not clear to me how best to do this with statically linked standard libraries.

An approach I'm considering is to have libplug.so also use the flag -static-libstdc++ and then use the version script

{
  global: plugf;
  local: *;
};

to ensure that its version of the standard library is used, but that would mean there would be two copies of libstdc++ loaded into memory. I know this approach wouldn't be blessed by the C++ standard since it would have ORD violations, but is it something that libstdc++ supports in any way? The Multiple ABI testing section of its manual section does reference a scenario that sounds similar.

5
  • 1
    Sadly, you're going to need to distribute a dynamic/static linked libstdc++ to match libplug.so - and yes, two copies would be loaded at runtime. And yes, you might get in trouble if your plugin returns a pointer with one version of libstdc++ and you free it with another version. Commented Dec 16, 2017 at 1:45
  • I don't think that's true. Allocation is handled by the standard c library and -static-libstdc++ doesn't cause libc to be linked in statically so they are both using the same libc.so. Commented Dec 16, 2017 at 1:56
  • I think objects are allocated with __gnu_cxx::new_allocator in libstdc++, perhaps as you point out they both go to the same libc.so. From personal experience I've had the aforementioned problem using MSVC's RT. Commented Dec 16, 2017 at 3:42
  • A standard allocation such as new int{123} calls operator new which in libstdc++ is just a wrapper for malloc. (See here). Commented Dec 18, 2017 at 23:30
  • Yeah, depends on how you build it, for example you might be mixing different version of libc. This is why libraries like those from HDL don't expose memory allocation. Anyways, systems that support dynamic plugins rely on dynamic libraries do avoid duplication. That is why dlls were invented. One way to mitigate the impact of your deployment strategy is to rely heavily on LTO. Commented Dec 19, 2017 at 0:38

1 Answer 1

1

Yes, this solution would work but

  • it introduces certain overhead due to code duplication
  • it may break if you try to pass STL objects between plugin/app due to ABI changes in recent libstdc++

Deleting objects allocated by std::allocator in different C++ runtime should work on Linux although I could not find explicit statement about this in libstdc++ docs. It does fail on Windows as Mikhail pointed out in comments.

Sign up to request clarification or add additional context in comments.

2 Comments

The ABI changes are only between the C++98 and C++11 versions of libstdc++, though, right?
@rnickb No, you'll get new ABI in all post-GCC5 libstdc++ regardless of -std flag (see this page for more details). It kind of makes sense because std::string in code compiled with -std=c++98 and -std=c++11 should better be binary compatible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.