在程序中設(shè)置鉤子,用來在malloc, realloc,free的時候,對其進行檢查,可以看到對應(yīng)的函數(shù)調(diào)用后的地址是什么。這個有時候可以用在debug的時候使用。
幾個變量
- __malloc_hook
這是一個函數(shù)指針變量,指向的是:
void * function(size_t size, void * caller)
其中caller是表示在棧中調(diào)用malloc的函數(shù)的時候的函數(shù)地址,%p可以打印出他的地址。
- __free_hook
同樣這個也是一個函數(shù)指針變量,指向的是:
void function(void * ptr, void * caller)
- __realloc_hook
這也是指向一個函數(shù)指針變量,指向的是:
void * function(void * ptr ,size_t size, void * caller)
__memalign_hook
這個函數(shù)是指向的一個函數(shù)指針,不過是:
aligned_alloc, memalign, posix_memalign and valloc__malloc_initialize_hook
void (*__malloc_initialize_hook) (void) = my_init_hook;
這是一個弱類型,只是在初始化的時候使用一次。
使用原理
hook函數(shù)只是對malloc realloc以及free等函數(shù)有一個包裝,即每當(dāng)調(diào)用了這些函數(shù)后,利用hook函數(shù),可以得到我們想要的結(jié)果,比如當(dāng)前調(diào)用的動態(tài)分配內(nèi)存函數(shù)的地址,hook變量的值等等
這樣在debug的時候,可以知道內(nèi)存泄漏的地點,當(dāng)然使用valgrind也是可以的。
例子
/*prototype define for us*/
static void my_init_hook(void);
static void *my_malloc_hook(size_t, const void *);
static void *my_free_hook(void *,const void *);
/*some temp variable*/
static void *(*old_malloc_hook)(size_t, const void *);
static void (*old_free_hook)(void *, const void *)
/*initialize hook*/
void (*__malloc_initialize_hook) (void) = my_init_hook;
/*init function*/
static void
my_init_hook(void){
old_malloc_hook = __malloc_hook;
old_free_hook = __free_hook;
__malloc_hook = my_malloc_hook;
__free_hook = my_free_hook;
}
/*my alloc hook*/
static void *
my_malloc_hook(size_t size, const void * caller)
{
void *result; /*malloc's return*/
/*restore all old hooks*/
__malloc_hook = old_malloc_hook;
__free_hook = old_free_hook;
/*call recursively*/
result = malloc(size);
/*save underlying hooks*/
old_malloc_hook = __malloc_hook;
old_free_hook = __free_hook;
/*printf might call malloc, so protect it too*/
printf("malloc(%u) call from %p, return %p\n",(unsigned int)size, caller, result);
/*restore our own hooks*/
__malloc_hook = my_malloc_hook;
__free_hook = my_free_hook;
return result;
}
/*free hook is same like malloc*/
static void
my_free_hook(void *ptr,const void *caller)
{
.....
}
/*main*/
int main(void)
{
char *p;
p = malloc(10);
free(p);
return 0;
}
執(zhí)行后會輸出如下的:
1:__malloc_hook =0 old_malloc_hook = 0
2:__malloc_hook =0 old_malloc_hook = 0
3:__malloc_hook =0 old_malloc_hook = 0
malloc(10) caled from 0x4007b0 returns 0x1d253010
4:__malloc_hook =400620 old_malloc_hook = 0
freed pointer 0x1d253010
輸出內(nèi)容是可以自定制的,也就是hook的用途所在了。更多的內(nèi)容可以參閱GCC的相關(guān)文檔。