2014-08-29 1 views
1

Как упоминалось в других ответах SO, я использую механизм обертывания GNU ld для перехвата вызовов на malloc в Linux (см. Пример here). Используемый флаг компоновщика - -Wl,--wrap=malloc и соответствующий void __wrap_malloc(size_t). Это хорошо работает в тестовом приложении, где весь блок компиляции связан с одним и тем же двоичным кодом.неразрешенный символ __real_malloc при динамической загрузке библиотеки, которая скомпилирована с помощью --wrap = malloc

Теперь мне нужно изменить динамически связанную библиотеку, которая загружается в основную программу через dlopen(). Связывание библиотеки преуспевает, но загрузка ее в основную программу завершается с undefined symbol: __real_malloc.

Запуск nm в библиотеке показывает, что __wrap_malloc определен, но __real_malloc нет. Но в соответствии с man ld и this Ответ на вопрос malloc должен быть заменен на __wrap_malloc, а __real_malloc должен указывать на malloc при использовании этой техники.

В тестовом приложении я вижу, что __real_malloc не определено в скомпилированных объектных файлах, но разрешен после соединения с исполняемым файлом.

Итак, почему символ разрешен в тестовом приложении, но не в динамической библиотеке? В обоих случаях выполняется заключительный этап ссылки, который должен разрешить этот символ. Или требуется добавить другую библиотеку во время этапа ссылки динамической библиотеки, чтобы получить разрешение __real_malloc?

На всякий случай, невозможно изменить целевое приложение, которое загружает динамическую библиотеку через dlopen.

ответ

1

Он должен работать и требует внесения небольших изменений в код в связанном с вами вопросе.

testapp.c

#include <stdio.h> 
#include <stdlib.h> 
#include <dlfcn.h> 

typedef void f_t(void); 

int main() 
{ 
    void* h = dlopen("./malloc_wrapper.so", RTLD_NOW); 
    if (h == NULL) 
    { 
     puts(dlerror()); 
     exit(1); 
    } 

    f_t* f = (f_t*)dlsym(h, "test"); 

    if (f == NULL) 
    { 
     puts(dlerror()); 
     exit(1); 
    } 

    (*f)(); 

    return 0; 
} 

malloc_wrapper.c

#include <stdlib.h> /* added */ 
#include <stdio.h> 
void *__real_malloc (size_t); 

/* This function wraps the real malloc */ 
void *__wrap_malloc(size_t size) 
{ 
    void *lptr = __real_malloc(size); 
    printf("Malloc: %lu bytes @%p\n", size, lptr); 
    return lptr; 
} 

void test(void) /* added */ 
{ 
    free(malloc(1024)); 
} 

компилировать и запускать.

gcc -Wl,-wrap,malloc -shared -fpic malloc_wrapper.c -o malloc_wrapper.so 
gcc testapp.c -o testapp -ldl 
./testapp 
Malloc: 1024 bytes @0x1d44680 

Компиляция malloc_wrapper.so как это воспроизводит ошибки вы описываете:

gcc -shared -fpic malloc_wrapper.c -o malloc_wrapper.so 
./testapp 
./malloc_wrapper.so: undefined symbol: __real_malloc 

Возможно, вы использовали обертку при компиляции и компоновки исполняемого файла вместо общего объекта?

+0

Спасибо за пример и извините за возвращение так поздно. После добавления 'extern 'C'' деклараций к функциям, изменение включает в эквивалент 'C++' и компиляцию файлов с помощью 'g ++', это работает для этого примера. К сожалению, проект, над которым я работаю, намного сложнее. Так что это проблема в процессе сборки. Может быть, я обновлю вопрос, если у меня появятся подробности об этой проблеме. – MKroehnert

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