Я создаю небольшое быстрое приложение, которое обнаруживает утечки памяти в других приложениях. Я использую LD_PRELOAD для переопределения по умолчанию malloc
и используя это, хранящиеся в памяти, каждый вызов в malloc
в вашей программе. Проблема в том, что некоторые библиотечные функции C также используют malloc
. Кроме того, существуют библиотечные функции, которые не освобождают выделенную память. Продемонстрируем:
MyApp.cpp
Переопределение malloc с помощью LD_PRELOAD и вызов malloc в библиотечных функциях
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
static void * (* LT_MALLOC)(size_t) = 0;
static void (* LT_FREE)(void *) = 0;
static void init_malloc()
{
char *error;
*(void **) (<_MALLOC) = dlsym (RTLD_NEXT, "malloc");
dlerror();
if ((error = dlerror()) != NULL)
{
fprintf (stderr, "%s\n", error);
_exit(1);
}
}
static void init_free()
{
char *error;
*(void **) (<_FREE) = dlsym (RTLD_NEXT, "free");
dlerror();
if ((error = dlerror()) != NULL)
{
fprintf (stderr, "%s\n", error);
_exit(1);
}
}
extern "C"
void * malloc (size_t size) throw()
{
if (LT_MALLOC == 0)
init_malloc();
printf ("malloc(%ld) ", size);
void *p = LT_MALLOC(size);
printf ("p = %p\n", p);
return p;
}
extern "C"
void free (void *p) throw()
{
if (LT_FREE == 0)
init_free();
printf ("free(%p)\n", p);
LT_FREE(p);
}
И test.c
. (Предположим, что исходный код не доступен на начальном этапе, и у меня есть только программы.)
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main (void)
{
printf ("test start\n");
int *a = (int *)malloc(3 * sizeof (int));
if (a)
printf ("Allocated 3 int - %p\n", a);
time_t t = time(NULL);
a[0] = 1;
printf ("time - %s", ctime(&t));
printf ("a[0] = %d\n", a[0]);
free (a);
printf ("CALL FREE(a)\n");
printf ("test done\n");
return 0;
}
$ g++ -g -fPIC -c MyApp.cpp -o MyApp.o
$ g++ -g -shared MyApp.o -o MyApp.so -ldl
$ gcc -g test.c -o test
$ export LD_PRELOAD=./MyApp.so
Запуск программы ./test
и посмотреть:
malloc(72704) p = 0x8aa040
test start
malloc(12) p = 0x6a0c50
Allocated 3 int - 0x6a0c50
free((nil))
malloc(15) p = 0x6a0c70
malloc(552) p = 0x6a0c90
free((nil))
malloc(1014) p = 0x6a0ec0
free(0x6a0c90)
malloc(20) p = 0x6a0c90
malloc(20) p = 0x6a0cb0
malloc(20) p = 0x6a0cd0
malloc(21) p = 0x6a0cf0
malloc(20) p = 0x6a0d10
malloc(20) p = 0x6a0d30
malloc(20) p = 0x6a0d50
malloc(20) p = 0x6a0d70
malloc(21) p = 0x6a0d90
free((nil))
time - Mon Mar 14 18:30:14 2016
a[0] = 1
free(0x6a0c50)
CALL FREE(a)
test done
Но я хочу посмотреть:
test start
malloc(12) p = 0x6a0c50
Allocated 3 int - 0x6a0c50
time - Mon Mar 14 18:30:14 2016
a[0] = 1
free(0x6a0c50)
CALL FREE(a)
test done
Я хочу, чтобы мое приложение избегало скинов malloc
в библиотечных функциях. Но у меня нет идей, как это сделать.
Может ли malloc
узнать, какая функция называется: библиотека или ваша? Или мы можем сделать, чтобы вызывать по умолчанию не переопределять malloc
в библиотечных функциях? Или что-то другое?
P.S. Прошу прощения за мой плохой английский.
Почему вы не просто используете valgrind? – chqrlie
Valgrind не так быстро. –