问题:主程序中使用了静态库A,主程序使用的动态库B中也使用了静态库A。程序运行时先加载了主程序静态库A的符号,动态库B在运行到静态库A的代码时(错误地运行了主程序静态库A的符号)出现crash。
解决:动态库B在编译时添加-Wl,-Bsymbolic选项,这是个链接选项,连接器ld会使so优先使用库内符号
-Bsymbolic
When creating a shared library, bind references to global symbols to the definition within the shared library, if any. Normally, it is possible for a program linked against a shared library to override the definition within the shared library. This option is only meaningful on ELF platforms which support shared libraries.
译文:在创建共享库时,将对全局符号的引用绑定到共享库中的定义(如果有的话)。通常,链接到共享库的程序可以覆盖共享库中的定义。这个选项只在支持共享库的ELF平台上有意义。
如果动态库B先加载,需要保证自身不会覆盖其他库或程序的符号,因此在编译动态库时需要添加-fvisibility=hidden选项,该选项会隐藏动态库的所有符号,所以需要在源码中对需要导出的函数和变量前加上__attribute__ ((visibility ("default")))属性
拓展:隐藏静态库的符号
选项:-Wl,--exclude-libs,ALL