This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Shared libraries and visibility
- From: Martin Richtarsky <s at martinien dot de>
- To: <gcc-help at gcc dot gnu dot org>
- Date: Tue, 19 Nov 2013 14:25:55 +0100
- Subject: Shared libraries and visibility
- Authentication-results: sourceware.org; auth=none
Hi,
starting with GCC 4.7 the visibility of template instantiations also
depends on the visibility of the template arguments. So if I am building
a shared library with -fvisibility=hidden and a template class like
std::vector<A>
then std::vector and class A both need to have explicitly declared
default visibility to make std::vector<A> also visible and usable for
library users.
However the upshot is that all calls to std::vector functions that can
not be inlined will be resolved through the PLT. This can introduce
slowdown in hot code paths. I do not need to have the ability to replace
a function through e.g. LD_PRELOAD, so this mechanism is overhead for
me. To workaround it I have tried several solutions:
1) At first it seems like protected visibility is the correct solution.
However, I encountered two problems:
- Mixing protected with default visibility is causing problems quickly
- Replacing default with protected visibility will quickly lead to
strange linker errors. It looks like there are a couple of known bugs
here, and nobody is fixing them because nobody really is using protected
visibility.
2) The -Bsymbolic ld flag also looks very promising:
"When creating a shared library, bind references to global symbols to
the
definition within the shared library, if any."
When building my codebase with this I encountered some strange crashes.
I guess I could debug those but the codebase is rather large...
3) Finally I tried tagging all methods in the class (std::vector in the
example above) with hidden visibility. Thus no more PLT calls are
generated and the code becomes faster.
However this solution is rather cumbersome. #pragma GCC visibility
doesn't work here either.
Are there some best practices how to solve this problem in general?
Is there a way to make solution 3) easier?
Or should I rather try to get solution 2) working?
Thanks and best regards,
Martin