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.
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)
.
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)?
Thanks! Matt
Edited 2009-12-3
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).
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.
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>
).