16

我在 Linux 上有一个可执行文件,它加载libfoo.so.1(即 a SONAME)作为其依赖项之一(通过另一个共享库)。它还链接到另一个系统库,而后者又链接到系统版本libfoo.so.2. 结果,两者 libfoo.so.1都在执行期间被加载,并且libfoo.so.2本应从版本 1 的库中调用函数的代码最终会从版本 2 的较新系统库中调用(二进制不兼容)函数,因为某些符号保持不变。结果通常是堆栈粉碎和随后的段错误。

现在,链接到旧版本的库是一个封闭源代码的第三方库,我无法控制libfoo它编译的版本。假设剩下的唯一选择是重建一堆当前链接到的系统库libfoo.so.2以链接到libfoo.so.1.

有没有办法避免用链接到旧的本地副本替换系统库libfoo?我可以加载这两个库并让代码调用正确版本的符号吗?所以我需要一些特殊的符号级版本控制?

4

2 回答 2

8

您也许可以做一些版本脚本技巧:

http://sunsite.ualberta.ca/Documentation/Gnu/binutils-2.9.1/html_node/ld_26.html

这可能需要您在 lib 周围编写一个包装器,该包装器会引入 libfoo.so.1,它显式地导出一些符号并将所有其他符号屏蔽为本地符号。例如:

MYSYMS { 全球: foo1; 富二;当地的: *; };

并在您链接该包装器时使用它,例如:

gcc -shared -Wl,--version-script,mysyms.map -o mylib wrapper.o -lfoo -L/path/to/foo.so.1

这应该使 libfoo.so.1 的符号对包装器本地化,并且对主 exe 不可用。

于 2008-10-24T16:15:45.093 回答
0

我只能想出一个变通办法。这将静态链接您正在使用的“系统库”版本。对于您的静态构建,您可以将其链接到与第三方库相同的旧版本。鉴于它不依赖于较新的版本...

或许也可以通过不以普通方式链接到第三方库来避免这些问题。相反,您的程序可以在执行时加载它。也许那时它可能会被其他人所掩盖。但我对此知之甚少。

于 2008-10-23T01:22:48.527 回答