Функция взаиморасположения работает только для malloc и не свободна
Я столкнулся с небольшой проблемой при мониторинге malloc и free через использование функции interposition.
При выполнении вставки функции для просто malloc, она работает как исключено. Тем не менее, когда вы пытаетесь вставить свободное, оно оказывается в цикле; мне кажется, что бесплатно вызывается рекурсивно, но я просто не знаю почему.
Это код для malloc и свободных функций. (Mod_malloc_free.c)
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>
void* malloc(size_t size) {
static void* (*real_malloc)(size_t) = NULL;
printf("%s\n", "inside shared malloc");
if(!real_malloc)
real_malloc = dlsym(RTLD_NEXT, "malloc");
void * p = real_malloc(size);
printf("malloc(%d) = %p\n",size, p );
printf("%s\n", "returning from shared malloc");
return p;
}
void free(void* ap ) {
static void (*real_free)(void*) = NULL;
printf("inside shared free...\n");
if(!real_free)
real_free = dlsym(RTLD_NEXT, "free");
printf("free = %p\n", ap);
real_free(ap);
}
Основное просто состоит из:
#include <stdio.h>
#include <malloc.h>
int main(void) {
void * p = malloc(123);
printf("p = %p\n",p );
free(p);
return 0;
}
Составлено как:
gcc -shared -ldl -fPIC mod_malloc_free.c -o libcustom.so
gcc -o smallMain -Wall smallMain.c
LD_PRELOAD =. / Libcustom.so ./smallMain
С наилучшими пожеланиями
Nyfiken
3 ответа
glibc обеспечивает реальный символ (не слабый) __
префикс. Так что попробуйте поискать символ __malloc
а также __free
,
И просто для предотвращения рекурсии, не используйте printf() или любые другие функции, которые могут потребоваться для выделения памяти внутри вашей обертки.
Скорее всего printf
звонит free
, Конечно, это подразумевает, что он также выполняет выделение памяти, поэтому возникает вопрос, почему вы не видите рекурсивные вызовы в malloc
, Скорее всего printf
называет альтернативу, такую как calloc
или же realloc
,
Чтобы вставить только свой собственный код, используйте макросы для замены вызовов или свяжите свой код отдельно и используйте функции компоновщика для удаления malloc
а также free
перед связыванием с внешними библиотеками (такими как -unexported_symbol
переключатель для версии Apple ld).
Вставить во весь код, удалить printf
из вашей рутины. Вызовите более простые процедуры, такие как fputs
вместо. В качестве альтернативы используйте статический флаг для подавления рекурсии:
void free(void *ap)
{
static void (*RealFree)(void *) = 0;
If (!RealFree)
RealFree = dlsym(RTLD_NEXT, "free");
static int InsideCall = 0;
if (!InsideCall)
{
InsideCall = 1;
… Do stuff…
InsideCall = 0;
}
}
(Если у вас есть несколько потоков или обработчиков исключений, которые выполняют выделение памяти, необходимо предпринять дополнительные шаги.)
Я бы посоветовал вам использовать макрос для замены malloc/free своими собственными функциями вместо использования указателей на функции.
Примерно так должно это сделать:
#ifdef REPLACE_MALLOC
#define malloc(x) my_mallc(x)
#define free(x) my_free(x)
#endif
Не забудьте сделать:
#undef malloc
#undef free
до вашей фактической реализации.
Однако обратите внимание, что технически это не "правильно" - вы не должны использовать макросы для вещей, которые являются частью стандартной библиотеки, поэтому, пожалуйста, не стоните здесь, если она перестает работать - в частности, Microsoft уже делает что-то подобное заменить malloc
с его отладочной версией в сборках отладки.