2008-10-23 160 views
15

我对Linux的加载libfoo.so.1一个可执行文件(这是一个SONAME)作为它的一个依赖(通过另一个共享库)。它也链接到另一个系统库,这反过来,链接到系统版本,libfoo.so.2。因此,均为libfoo.so.1libfoo.so.2在执行期间被加载,并且应该从版本为1的库调用函数的代码最终会从具有版本2的较新系统库调用(二进制不兼容)函数,因为某些符号保留一样。结果通常是堆栈粉碎和随后的段错误。加载多个共享库

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

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

+0

Alex:你是怎么解决这个问题的?你可以和我们分享吗? – Nawaz 2017-12-29 11:07:29

回答

0

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

或许也有可能避免与未链接到第三方库普通的方式这些问题。相反,您的程序可以在执行时加载它。也许那么它可能会影响其他人。但我对此不甚了解。

7

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

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

这可能需要你写在你的lib的包装,在libfoo.so.1的是出口一些符号明确和口罩拉所有其他地方。例如:

MYSYMS全球: foo1; foo2; local: *; };

,当你链接,包装像这样使用:

的gcc -shared -Wl, - 版本脚本,mysyms.map -o MYLIB wrapper.o -lfoo -L /路径/到/ foo中。 so.1

这应该使在libfoo.so.1的符号本地的包装,而不是提供给主要的exe文件。