неразрешенный символ __real_malloc при динамической загрузке библиотеки, которая компилируется с —wrap = malloc

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

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

Бег nm в библиотеке видно, что __wrap_malloc определяется, но __real_malloc не является.
Но, согласно man ld а также этот ТАК ответь, 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

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

1

Другие решения


По вопросам рекламы [email protected]