我已经在Linux平台上覆盖了函数malloc
, calloc
和free
函数,如下所示:
#include <stdio.h> #include <dlfcn.h> #include <stdlib.h> typedef void* (*MALLOCFN)(size_t); typedef void* (*CALLOCFN)(size_t, size_t); typedef void* (*CALLOCFN)(size_t, size_t); typedef void (*FREEFN)(void *); MALLOCFN real_malloc = (MALLOCFN) 0; CALLOCFN real_calloc = (CALLOCFN) 0; FREEFN real_free = (FREEFN) 0; void *get_realfn(const char *fnm) { void *pfunc = (void *) NULL; printf("searching for original %s\n", fnm); pfunc = dlsym(RTLD_NEXT, fnm); if (pfunc) printf("found original %s\n", fnm); else printf("not found original %s\n", fnm); return pfunc; } void *malloc(size_t s) { printf("called malloc\n"); if(real_malloc == NULL) real_malloc = (MALLOCFN) get_realfn("malloc"); if (real_malloc) return real_malloc(s); else return NULL; } void *calloc(size_t s1, size_t s2) { printf("called calloc\n"); if(real_calloc == NULL) real_calloc = (CALLOCFN) get_realfn("calloc"); if (real_calloc) return real_calloc(s1, s2); else return NULL; } void free (void * ptr) { printf("called free\n"); if(real_free == NULL) real_free = (FREEFN) get_realfn("free"); if (real_free) real_free(ptr); } int main() { char * c1 = (char *) malloc(400); char * c2 = (char *) malloc(400); free(c2); free(c1); return 0; }
C程序(testalloc.c)是使用g ++ 4.9.2版本的编译器构build的:
g++ -g testalloc.c -ldl -o testalloc;
显示的输出的前几行如下,它进入无限recursion和崩溃:
called malloc searching for original malloc called free searching for original free called free searching for original free called free searching for original free called free searching for original free called free . . . .
请build议如何避免recursion。
printf
函数可能会分配内存。 因此,在“真实”函数指针未分配之前调用printf
时,它会进入插入的函数,导致无限递归。 所以不要在插入函数中使用printf
语句。
如果您确实需要打印某些内容,请使用syscall(2)
,它将绕过stdio库函数。
#include <sys/syscall.h> ... syscall(SYS_write, STDOUT_FILENO, "searching for original\n", sizeof "searching for original\n" - 1);