2012-01-24 2 views
4

В моем приложении 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.

+1

Вы проверили, может быть, 'RTLD_DEEPBIND' является альтернативным решением вашей проблемы? – PlasmaHH

+0

@PlasmaHH Это будет использовать функцию из другой библиотеки (или какой-либо другой функции. Я не думаю, что есть решение этого, другое, а не делать это –

+0

@VJovic: Кажется, наоборот, согласно моей странице manpage : «Поместите область поиска символов в этой библиотеке перед глобальной областью. Это означает, что автономная библиотека будет использовать свои собственные символы, предпочитая глобальные символы с тем же именем, что и в уже загруженных библиотеках». – PlasmaHH

ответ

1

Я хотел бы обнаружить дубликаты символов в dlopen и предупредить о них.

не думаю dlopen это можно сделать.

Даже если это возможно, обнаружение этой проблемы во время выполнения, вероятно, слишком поздно. Вы должны обнаруживать эту проблему в сборке времени, и это тривиально сделать это как шаг после сборки:

nm -D your_plugin_dir/*.so | egrep ' [TD] ' | cut -d ' ' -f3 | 
    sort | uniq -c | grep -v ' 1 ' 

Если вы получаете любой вывод, у вас есть повторяющиеся символы (некоторые повторяющиеся символы могут быть фактически хорошо, вам придется отфильтровать «известные хорошие» дубликаты).

+0

На самом деле плагины могут загружать другой общий объект, и в них могут возникать дублирующиеся символы. Структура довольно перепутана, и я не хочу проверять весь общий объект на наличие повторяющихся символов, поскольку некоторые из них «разрешены» для получения повторяющихся символов. Спасибо за подсказку в любом случае. –

Смежные вопросы