In my Linux application I am using a plugin architecture via dlopen
. Shared objects are being opened with
dlopen(path, RTLD_GLOBAL | RTLD_LAZY)`
The option RTLD_GLOBAL
is necessary since plugins need to access common RTTI information. Ocaisionally it happens that some plugins export the same symbols. This should not normally happen, but when it does it results in random segfaults and that is difficult to debug. So I would like detect duplicate symbols at dlopen and warn about them.
Is there a way to do this?
Here is a simple example to illustrate this. The code of the main executable is
#include <string>
#include <dlfcn.h>
#include <iostream>
#include <cassert>
typedef void (*Function)();
void open(const std::string& soname)
{
void* so = dlopen(soname.c_str(), RTLD_LAZY | RTLD_GLOBAL);
if (!so) {
std::cout << dlerror() << std::endl;
} else {
Function function = reinterpret_cast<Function>(dlsym(so, "f"));
assert(function);
function();
}
}
int main()
{
open("./a.so");
open("./b.so");
return 0;
}
And it is being built by the command g++ main.cpp -o main -ldl
a.so
and b.so
are being built from
#include <iostream>
void g()
{
std::cout << "a.cpp" << std::endl;
}
extern "C" {
void f()
{
g();
}
}
and
#include <iostream>
void g()
{
std::cout << "b.cpp" << std::endl;
}
extern "C" {
void f()
{
g();
}
}
by commands g++ -fPIC a.cpp -share -o a.so
and g++ -fPIC b.cpp -share -o b.so
respectively. Now if I execute ./main
I get
a.cpp
a.cpp
With RTLD_LOCAL
I get
a.cpp
b.cpp
but as I have explained I don't wont RTLD_LOCAL
.