Segfault在C ++插件库与重复符号 [英] Segfault on C++ Plugin Library with Duplicate Symbols

查看:115
本文介绍了Segfault在C ++插件库与重复符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个跨平台C ++应用程序,它分成几个共享库,并从插件共享库中加载额外的功能。插件库应该是自包含和自己的功能,不知道或依赖于调用应用程序。

I have a cross platform C++ application that is broken into several shared libraries and loads additional functionality from plugin shared libraries. The plugin libraries are supposed to be self contained and function by themselves, without knowledge of or dependency on the calling application.

其中一个插件包含来自主应用程序的复制代码,因此包含与引擎中的符号名称重复的符号名称。 (是的,我知道这通常是一个没有,但在插件编写时,引擎是一个单片的二进制文件,不能共享库。)在Windows上,一切运行正常。在Linux上,我们得到了segfaults。通过查看错误的堆栈跟踪,当在重复类名称中调用函数时,它出现在插件中。它似乎是引擎和插件具有略微不同的共享代码版本的结果(一些类功能已在插件中注释掉)。这就像插件得到它的符号运行时链接到引擎,而不是自己的。我们通过将 dlopen 的参数更改为 dlopen(pFilepath,RTLD_LAZY | RTLD_LOCAL)来修复问题。

One of the plugins contains copied code from the main application, so contains symbol names that are duplicate to those in the engine. (Yes I know that's generally a no-no, but at the time the plugin was written the engine was a monolithic binary and couldn't share libraries.) On Windows, everything runs fine. On Linux we were getting segfaults. By looking at the stack trace of the error, it was occurring in the plugin when calling functions in the duplicate class name. It appeared to be a result of the engine and plugin having slightly different versions of the shared code (some class functionality was commented out in the plugin). It was as if the plugin was getting it's symbols runtime linked to the engine's instead of its own. We "fixed" the issue by changing the dlopen's parameters to be dlopen(pFilepath, RTLD_LAZY | RTLD_LOCAL).

但是当我们重新编写引擎分割成共享库(为了最终的目的,在插件中重用),我们再次得到segfault错误。并查看堆栈跟踪,它从引擎 - >插件 - >引擎。

But when we rewrote the engine to be split into shared libraries (for the eventual purpose of reuse in the plugins), we get the segfault error again. And looking at the stack trace, it goes from the engine -> plugin -> engine.

有一种方法来指定运行时链接器不映射插件到引擎(特别是如果他们在插件中定义)?

Is there a way to specify for the runtime linker to not map symbols of the plugin to the engine (especially if they are defined in the plugin)?

谢谢!
Matt

Thanks! Matt



编辑2009-12-3


Edited 2009-12-3

试图将插件的代码包装在自己的命名空间中。这没有工作,因为它静态链接到一个库,也链接到引擎。静态库的版本是不同的,所以segfault!

I first tried to wrap the plugin's code in it's own namespace. That didn't work because it is statically linked to a library that is also linked to the engine. The versions of the static library are different, so segfault!

然后我改变了引擎的构建和它的库被静态链接。当我运行它,我不再有这个问题。所以它似乎是导出共享库符号,然后在打开时动态重定位到插件中的结果。但是当所有引擎的代码都在一个可执行文件中时,它不会导出其符号(所以它不会尝试将插件的符号重新定位到引擎中)。

Then I changed the build of the engine and it's libraries to be statically linked. And when I run it, I no longer have the issue. So it appears it was a result of having the shared library symbols exported and then being dynamically relocated into the plugin when it was opened. But when all of the engine's code is in a single executable, it doesn't export its symbols (so it doesn't try to relocate the plugin's symbols into the engine).

我仍然有一个问题,因为有一个并行版本的程序(使用Open-MPI),仍然得到segfault。它似乎仍然导出引擎的符号和重定位插件。这可能与Open-MPI如何执行应用程序有关。

I still have an issue though, as there is a parallelized version of the program (using Open-MPI) and that still gets the segfault. It appears in that it's still exporting the engine's symbols and relocating the plugin's. That might have to do with how Open-MPI executes the application.

有没有可以在插件共享库上使用的链接器标志,它会告诉它不动态在运行时重新定位符号?或者隐藏它的符号,使他们不被重新安置?我尝试了 -s (省略所有符号信息),但是显然没有改变动态符号(使用 nm -D< ; plugin> )。

Are there any linker flags that could be used on the plugin shared library that would tell it not to dynamically relocate the symbols at runtime? Or to hide it's symbols so they don't get relocated? I've tried -s ("Omit all symbol information") but that apparently didn't change the dynamic symbols (checked using nm -D <plugin>).

推荐答案

我想我找到了解决方案, code> -Bsymbolic 。本质上,此标志在共享库中添加一个标志,以告知运行时连接器首先尝试并解析自身内部的符号名称。当插件与该标志链接时,引擎能够在所有情况下运行(整体exe,exe w /共享库,插件w和包装命名空间)。

I think I've found the solution, the linker flag -Bsymbolic. Essentially this flag adds a flag in the shared library to tell the runtime linker to try and resolve symbol names within itself first. The engine was able to run with the plugin just fine in all cases (monolithic exe, exe w/ shared libs, plugin w/ and w/o wrapping the namespace) when the plugin was linked with that flag.

似乎有一些批评者对 -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/

There does seem to be a few detractors with warnings about -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/

但考虑到他们的警告和插件的意图,我认为这是我正确的选择。至少现在。

But considering their warnings and what the intention of the plugin is, I think it's the right option for me. At least for now.

这篇关于Segfault在C ++插件库与重复符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆