我在 Linux 上有一个可执行文件,它加载 libfoo.so.1
(这是一个 SONAME
)作为其依赖项之一(通过另一个共享库)。它还链接到另一个系统库,后者又链接到一个系统版本,libfoo.so.2
。结果,同时 libfoo.so.1
和 libfoo.so.2
在执行过程中被加载,而本应调用函数的代码来自版本 1 的库最终会调用来自版本 2 的较新系统库的(二进制不兼容)函数,因为某些符号保持不变。结果通常是堆栈粉碎和随后的段错误。
现在,链接到旧版本的库是一个闭源的第三方库,我无法控制它编译的 libfoo
版本。假设,剩下的唯一其他选择是重建一堆当前与 libfoo.so.2
链接的系统库以与 libfoo.so.1
链接。
有什么方法可以避免用链接到旧版 libfoo
的本地副本替换系统库?我可以加载两个库并让代码调用正确版本的符号吗?所以我需要一些特殊的符号级版本控制?
最佳答案
您可以使用一些版本脚本技巧:
http://sunsite.ualberta.ca/Documentation/Gnu/binutils-2.9.1/html_node/ld_26.html
这可能需要您在 lib 周围编写一个包装器,以引入 libfoo.so.1,显式导出一些符号并将所有其他符号屏蔽为本地符号。例如:
我的系统{ 全局的: foo1; foo2; 本地的: *; };
并在链接包装器时使用它,例如:
gcc -shared -Wl,--version-script,mysyms.map -o mylib wrapper.o -lfoo -L/path/to/foo.so.1
这应该使 libfoo.so.1 的符号在包装器中是本地的,并且对主 exe 不可用。
关于linux - 加载多个不同版本的共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/228117/