dlsym - получить переопределенный символ - PullRequest
4 голосов
/ 30 ноября 2011

У меня есть приложение, динамически загружающее библиотеки, которое динамически загружает библиотеки, которые ...

В Windows я могу перебирать все загруженные модули в поисках интересующего меня символа.знать, как это сделать в среде Unix / Linux.Я знаю, что могу использовать dlsym(dlopen(0, flag)) или dlsym(RTLD_DEFAULT / RTLD_NEXT) для первых двух символов и знать порядок модулей для поиска - только как я могу углубиться и получить все определения данного символа?

Ответы [ 2 ]

6 голосов
/ 30 ноября 2011

Чтобы найти символ в осколочном объекте, откройте его с помощью dlopen.

 void* foobar = dlopen ("/usr/local/lib/foobar.so", RTLD_NOW);
 void* mysymbol = dlsym (foobar, "mysymbol");

Обновление Вот программа, которая перебирает все символы с именем "foo". Это не POSIX, а GNU libs. Я почти уверен, что POSIX не предоставляет такие возможности.

#define _GNU_SOURCE 
#include <link.h>
#include <dlfcn.h>
#include <stdio.h>

void doit (const char* s)
{
    void* obj = dlopen (s, RTLD_LAZY);
    void* fcn = dlsym (obj, "foo");
    if (fcn)
        printf ("Object %s has 'foo' at addr %p\n", *s ? s : "(exe)", fcn);
}    
int cb (struct dl_phdr_info *info, size_t size, void *data)
{
    doit (info->dlpi_name);
    return 0;
}    
int main ()
{
    dl_iterate_phdr (cb, 0);    
    return 0;
}

Вот вывод:

Object (exe) has 'foo' at addr 0xb76f8418
Object (exe) has 'foo' at addr 0xb76f8418
Object /tmp/libfoo.so has 'foo' at addr 0xb76f8418
Object /tmp/libfoo1.so has 'foo' at addr 0xb76f5418
Object /tmp/libfoo2.so has 'foo' at addr 0xb76f2418

Есть несколько дубликатов, но это небольшая проблема.

2 голосов
/ 05 декабря 2011

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

Windows:MODULEENTRY32, CreateToolhelp32Snapshot, Module32First, Module32Next

Linux:как описано в ответе nm, возвращайте ненулевое значение из обратного вызова, когда найден соответствующий модуль (завершает цикл).

AIX:loadquery (L_GETINFO, буфер, размер), struct ld_info.

HP-UX:dlget, dlgetname (если вам нужен путь к модулю).

Solaris:ldinfo, Link_map.

Кроме того, я бы порекомендовал раздвинуть модули и получить символ из нового дескриптора, чтобы увеличить счетчик ссылок библиотеки, чтобы предотвратить его выгрузку.По крайней мере, в AIX это может иметь побочный эффект от загрузки библиотеки и ее повторной инициализации, но в большинстве случаев это лучше, чем попытка вызова функции из незагруженной библиотеки.

...