2

谁能建议我们可以限制将符号导出到全局符号表的某种方式?

提前致谢


你好,

感谢回复...

实际上,我有一个静态链接到第三方库的可执行文件,例如“ver1.a”,并且还使用第三方“.so”文件,该文件再次与相同的库链接,但不同的版本说“ver2.a”。问题是这两个版本的实现是不同的。一开始,当加载可执行文件时,“ver1.a”中的符号将被导出到全局符号表中。现在,无论何时加载“.so”,它都会尝试引用来自 ver2.a 的符号,最终将引用来自“ver1.a”的符号,这些符号之前已加载。从而使我们的二进制文件崩溃。

我们想到了一个解决方案,我们不会将可执行文件的符号导出到全局符号表,因此当“.so”被加载并尝试使用来自 ver2.a 的符号时,它不会在全局符号表中找到它,它将使用它的自己的符号,即来自 ver2.a 的符号

我找不到任何方法可以限制将符号导出到全局符号表。我尝试使用--version-script 和retain-symbol-file,但是没有用。对于 -fvisibility=hidden 选项,它给出的错误是“-f 选项只能与 -shared 一起使用”。所以我想,这也像“--version-script”一样只适用于共享库而不适用于可执行二进制文件。

代码在 c++、OS-Linux、gcc version-3.2 中。可能无法重新编译任何第三方库和“.so”。因此,排除了使用 bsymbolic 标志重新编译“so”文件的选项。

任何帮助,将不胜感激。

4

3 回答 3

2

使用 dlopen 拉入 3rd 方库。

您可以通过创建自己的共享库来避免这种情况,该库隐藏所有第三方符号并只向它们公开您自己的 API,但如果所有其他方法都失败,dlopen 会给您完全控制权。

于 2009-11-26T16:33:41.990 回答
1

我有一个类似的问题/问题: Segfault on C++ Plugin Library with Duplicate Symbols

如果您可以重建 3rd 方库,则可以尝试添加链接器标志-Bsymbolic(gcc/g++ 的标志将是-Wl,-Bsymbolic)。这可能会解决你的问题。这完全取决于您的代码和内容的组织,因为使用它有一些注意事项:
http ://www.technovelty.org/code/c/bsymbolic.html
http://software.intel.com/en-us /articles/performance-tools-for-software-developers-bsymbolic-can-cause-dangerous-side-effects/

如果你不能重建它,根据第一个警告链接:

事实上,在构建共享库时,-Bsymbolic 标志唯一要做的就是在二进制文件的动态部分添加一个名为 DT_SYMBOLIC 的标志。

那么也许有一种方法可以在DT_SYMBOLIC链接后将标志添加到动态部分?

于 2009-12-04T16:39:16.367 回答
0

最简单的解决方案是重命名可执行文件中的符号(通过更改源代码),这样它们就不会与共享库发生冲突。

下一个最简单的事情是使用 . 本地化“问题”符号'objcopy -L problem_symbol'

最后,如果您不直接与第三方库链接(而是 dlopen 它,正如 bmargulies 所建议的那样),并且您的其他共享库都没有使用定义“问题”符号,并且您不与 -rdynamic 链接或其等效项之一,则不应将该符号导出到可执行文件的动态符号表中,因此您不应该有冲突。

注意:'nm a.out'will still,将符号显示为全局定义,但这对于动态链接无关紧要。您想查看with的动态符号表。a.out'nm -D a.out'

于 2009-11-27T04:52:47.580 回答