Cup*_*ppM 7 c++ linker gcc runtime shared-libraries
我有一个跨平台的C++应用程序,它被分成几个共享库并从插件共享库中加载其他功能.插件库应该是自包含的,并且在不知道或不依赖于调用应用程序的情况下自行运行.
其中一个插件包含来自主应用程序的复制代码,因此包含与引擎中的代码名称重复的符号名称.(是的,我知道这通常是禁止的,但在插件编写时,引擎是单片二进制文件,无法共享库.)在Windows上,一切运行正常.在Linux上我们得到了段错误.通过查看错误的堆栈跟踪,在调用重复类名中的函数时,它在插件中发生.它似乎是由于引擎和插件具有略微不同版本的共享代码(某些类功能在插件中被注释掉).就好像插件将它的符号运行时链接到引擎而不是它自己.我们通过改变dlopen参数来"修复"这个问题dlopen(pFilepath, RTLD_LAZY | RTLD_LOCAL).
但是当我们重写引擎被拆分为共享库时(为了最终在插件中重用),我们再次得到了段错误.看看堆栈跟踪,它来自引擎 - >插件 - >引擎.
有没有办法指定运行时链接器不将插件的符号映射到引擎(特别是如果它们在插件中定义)?
谢谢!马特
我首先尝试将插件的代码包装在它自己的命名空间中.这不起作用,因为它静态链接到也链接到引擎的库.静态库的版本不同,所以段错误!
然后我改变了引擎的构建,它的库是静态链接的.当我运行它时,我不再有问题.因此,它似乎是导出共享库符号然后在打开时动态重定位到插件中的结果.但是当所有引擎的代码都在一个可执行文件中时,它不会导出其符号(因此它不会尝试将插件的符号重定位到引擎中).
我仍然有一个问题,因为有一个并行版本的程序(使用Open-MPI),仍然会得到段错误.它似乎仍在导出引擎的符号并重新定位插件.这可能与Open-MPI如何执行应用程序有关.
是否有任何链接器标志可以在插件共享库上使用,它会告诉它不要在运行时动态重定位符号?或者隐藏它的符号,以便它们不被重新定位?我试过-s("省略所有符号信息"),但显然没有改变动态符号(使用检查nm -D <plugin>).
我想我已经找到了解决方案,链接器标志-Bsymbolic。本质上,此标志在共享库中添加一个标志,以告诉运行时链接器首先尝试解析自身内部的符号名称。当插件与该标志链接时,引擎能够在所有情况下(整体 exe、带共享库的 exe、带和不包装命名空间的插件)与插件一起运行。
似乎确实有一些批评者发出警告-Bsymbolic:
http://www.technovelty.org/code/c/bsymbolic.html
http://software.intel.com/en-us/articles/performance-tools-for -软件开发人员-bsymbolic-可能导致危险的副作用/
但考虑到他们的警告以及该插件的意图是什么,我认为这对我来说是正确的选择。最起码到现在。
| 归档时间: |
|
| 查看次数: |
1107 次 |
| 最近记录: |