Shared libraries and visibility

Martin Richtarsky
Tue Nov 19 13:36:00 GMT 2013


 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


 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 

 2) The -Bsymbolic ld flag also looks very promising:
 "When creating a shared library, bind references to global symbols to 
  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,

More information about the Gcc-help mailing list