Question on DSO and visibility
Paul Smith
paul@mad-scientist.net
Wed Sep 14 14:27:00 GMT 2016
On Wed, 2016-09-14 at 10:13 +0100, Jonathan Wakely wrote:
> On 11 September 2016 at 22:38, Paul Smith wrote:
> > I wonder if someone can comment on this situation: I'll do some testing
> > but I likely can't test everything.
> >
> > I'm creating DSO's for GNU/Linux with GCC 4.9.2 right now. I want to
> > upgrade to GCC 6.2.0. My code is written in C++. I'm aware of the C++
> > STL ABI break in GCC 5.x.
>
> Based on the solution you outlined, I'm not sure you've fully
> understood the ABI change in GCC 5.
There's little doubt you're correct about that :)
> See https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
Thanks. Â That is relatively clear.
> > 3. Use a linker map to make all symbols in my DSO hidden except the
> > specific ones I want to be public. I use a linker map and not just
> > -fvisibility=hidden, so that all the symbols I've statically linked
> > from libstdc++.a will also be marked hidden (since libstdc++.a was
> > not compiled with -fvisibility=hidden).
>
> The different ABIs coexist automatically. Affected symbols mangle
> differently so they don't collide.
Aha. Â Yes, this is the critical point I was glossing over.
> > In other words, I can use std::basic_string and std::list in my library
> > and get the C++11 ABI from GCC 6.2 that I've statically linked, and
> > users can use std::basic_string and std::list in their code and get
> > their version of the libstdc++.so (presumably that is provided by their
> > GNU/Linux distribution) and all will work properly.
>
> You don't necessarily need two version of libstdc++ in the process.
> The newer libstdc++.so is compatible with the users' code.
>
> If all you're worried about is the ABI change then just build your
> library with _GLIBCXX_USE_CXX11_ABI defined to 0 (or build your gcc
> with --with-default-libstdcxx-abi=gcc4-compatible)
I could do that. Â The problem is: I actually create two different
binaries from my code: one is the shared library which users can link
and the other is a standalone application. Â They contain almost all the
same code (the idea is that users may want to embed the application or
run it stand-alone). Â I really don't want to have to compile the entire
project twice.
And all things being equal, I'd like to use the newer ABI (since 99% of
my users actually use the stand-alone binary).
But maybe the complexity of both having my cake and eating it is not
worth it.
> The real problem is that your library will depend on a newer libstdc++
> but that's orthogonal to the ABI changes. Statically linking it is one
> solution, deploying the newer libstdc++.so with your library is
> another.
Yes, again good point. Â So, as long as I don't pass objects of the
problematic types across the ABI all is fine assuming a sufficient
libstd++ library is available.
There's one question: what about exceptions? Â std::exception::what()
returns a const char*; I don't know if that's stored internally as a
std::string which might have problematic types. Â If I throw an exception
from my code (new GCC/ABI) and it's caught by the caller's code (old
GCC/ABI) is there a problem? Â I'm assuming this is not an issue.
One reason all this came up was that a user was linking with my shared
library and got a crash in their own code, and saw my version of
std::string in the stacktrace (because I linked libstdc++ statically)
even though my code was not involved. Â Even though it all was working
fine, seeing this stack trace concerned them. Â I was thinking that if I
ensured that my static libstdc++ was marked hidden, they would get their
own dynamically linked libstdc++ and use that from their code and I
could avoid this "appearance of impropriety".
Thanks for the response Jonathan!
More information about the Gcc
mailing list