В моем приложении Linux я использую архитектуру плагина через dlopen
. Общие объекты открываются сОбнаружение дубликатов символов в dlopen
dlopen (путь, RTLD_GLOBAL | RTLD_LAZY) `
Опция RTLD_GLOBAL
необходимо, так как плагины должны получить доступ к общей информации RTTI. Иногда бывает, что некоторые плагины экспортируют одни и те же символы. Это обычно не должно происходить, но когда это происходит, это приводит к случайным segfaults, и это трудно отлаживать. Поэтому я хотел бы обнаружить дубликаты символов в dlopen и предупредить о них.
Есть ли способ сделать это?
Вот простой пример, чтобы проиллюстрировать это. Код главного исполняемого
#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;
}
И она строится с помощью команды g++ main.cpp -o main -ldl
a.so
и b.so
строятся из
#include <iostream>
void g()
{
std::cout << "a.cpp" << std::endl;
}
extern "C" {
void f()
{
g();
}
}
и
#include <iostream>
void g()
{
std::cout << "b.cpp" << std::endl;
}
extern "C" {
void f()
{
g();
}
}
по команды g++ -fPIC a.cpp -share -o a.so
a d g++ -fPIC b.cpp -share -o b.so
соответственно. Теперь, если я исполню ./main
я получаю
a.cpp
a.cpp
С RTLD_LOCAL
я
a.cpp
b.cpp
но, как я объяснил, что я не обыкновение RTLD_LOCAL
.
Вы проверили, может быть, 'RTLD_DEEPBIND' является альтернативным решением вашей проблемы? – PlasmaHH
@PlasmaHH Это будет использовать функцию из другой библиотеки (или какой-либо другой функции. Я не думаю, что есть решение этого, другое, а не делать это –
@VJovic: Кажется, наоборот, согласно моей странице manpage : «Поместите область поиска символов в этой библиотеке перед глобальной областью. Это означает, что автономная библиотека будет использовать свои собственные символы, предпочитая глобальные символы с тем же именем, что и в уже загруженных библиотеках». – PlasmaHH