我不了解其他平台,但在 GNU/Linux 上,您可以使用 LD_PRELOAD 环境变量预加载一个小型内存跟踪库,其中定义了您自己的 malloc 和 free。
您自己的malloc 可能希望使用真正的malloc 函数分配内存,因此这里可能存在递归问题。要解决此问题,dlsym 函数可以使用 RTLD_NEXT 参数来获取指向下一个(即“真实”)malloc 函数的指针。
对此的一个非常小的测试可能如下所示:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
void *malloc(size_t size)
{
static void *(*real_malloc)(size_t size) = 0;
if (!real_malloc)
real_malloc = dlsym(RTLD_NEXT, "malloc");
void *result = real_malloc(size);
fprintf(stderr, "malloc(%d) = %p\n", (int)size, result);
return result;
}
void free(void *ptr)
{
static void (*real_free)(void *ptr) = 0;
if (!real_free)
real_free = dlsym(RTLD_NEXT, "free");
real_free(ptr);
fprintf(stderr, "free(%p)\n", ptr);
}
如果我们称这个文件为fakemalloc.c,可以用命令编译成fakemalloc.so共享对象
gcc -fPIC -shared -Wl,-soname,fakemalloc.so -o fakemalloc.so fakemalloc.c -ldl
作为测试,要查看在调用 ls 命令时发生了哪些 malloc 和 free 调用,您需要执行
LD_PRELOAD=/path/to/fakemalloc.so ls
编辑:正如评论中提到的,在 glibc-systems 上,您可以通过使用函数 __libc_malloc 和 __libc_free 来避免使用 RTLD_NEXT 方法。这将产生以下代码:
#include <stdio.h>
void *__libc_malloc(size_t size);
void *__libc_free(void *ptr);
void *malloc(size_t size)
{
void *result = __libc_malloc(size);
fprintf(stderr, "malloc(%d) = %p\n", (int)size, result);
return result;
}
void free(void *ptr)
{
__libc_free(ptr);
fprintf(stderr, "free(%p)\n", ptr);
}