我有一个Linux上的可执行文件加载libfoo.so.1
(这是一个SONAME
)作为其依赖项之一(通过另一个共享库)。 它还链接到另一个系统库,该库又链接到系统版本libfoo.so.2
。 因此, libfoo.so.1
和libfoo.so.2
都是在执行过程中加载的,本来应该从版本1的库调用函数的代码最终会从具有版本的较新系统库调用(二进制不兼容的)函数2,因为一些符号保持不变。 结果通常是堆栈粉碎和随后的段错误。
现在,与旧版本链接的库是一个封闭的第三方库,我无法控制它编译的libfoo
版本。 假设,剩下的唯一select是重build一系列与libfoo.so.2
链接的系统库来链接libfoo.so.1
。
有没有办法避免用连接到较旧的libfoo
本地副本来replace系统库? 我可以加载这两个库,并有代码调用符号的正确版本? 所以我需要一些特殊的符号级版本?
你可能可以做一些版本脚本技巧:
http://sunsite.ualberta.ca/Documentation/Gnu/binutils-2.9.1/html_node/ld_26.html
这可能要求你在你的lib上编写一个包装器来引入libfoo.so.1,这个libfoo.so.1显式地导出了一些符号,并把所有其他的符号作为本地的。 例如:
MYSYMS {global:foo1; foo2的; 本地:*; };
当你连接这个包装器时使用这个:
gcc -shared -Wl, – version-script,mysyms.map -o mylib wrapper.o -lfoo -L / path / to / foo.so.1
这应该使libfoo.so.1的符号是本地的包装,不可用于主要的exe。
我只能想出一个解决办法。 这将是静态链接您正在使用的“系统库”的一个版本。 对于静态构建,可以使其与第三方库的旧版本链接。 鉴于它不依赖于较新的版本…
也许也可以避免这些问题,不要以普通的方式链接到第三方库。 相反,您的程序可以在执行时加载它。 也许那么它可能会影响其余的。 但是我对此不甚了解。