拦截malloc、free等库函数(malloc钩子)

拦截malloc、free等库函数(malloc钩⼦)
注意,以下⽅法对于多线程来说不管⽤。如,A线程调⽤到malloc_hook 函数,把malloc_hook函数还原为libc malloc函数,此时B线程调⽤到malloc函数便是libc malloc函数,根本不会进⼊到我们的malloc_hook设定的my_malloc函数。因此,多线程下是不能使⽤此⽅法,需要⽤__wrap_malloc⽅式解决。
五轴联动雕刻机__malloc_hook是⼀组glibc提供的malloc调试变量中的⼀个,这组变量包括:
void *(*__malloc_hook)(size_t size, const void *caller);
void *(*__realloc_hook)(void *ptr, size_t size, const void *caller);
void *(*__memalign_hook)(size_t alignment, size_t size, const void *caller);
void (*__free_hook)(void *ptr, const void *caller);
void (*__malloc_initialize_hook)(void);
void (*__after_morecore_hook)(void);
何谓钩⼦函数,当⼀个函数挂载了钩⼦函数后,你执⾏这个函数时,实际执⾏的是钩⼦函数
只要你在程序中写上”__malloc_hook= my_malloc_hook;”,之后的malloc调⽤都会使⽤my_malloc_hook函数,⽅便易⾏。但是这组调试变量不是线程安全的,当你想⽤系统malloc的时候不得不把他们改回来,多线程调⽤就得上锁。
#include <stdio.h>
#include <malloc.h>
#define THREAD_AUTOLOCK
cgwstatic void (*old_free)(void *ptr, const void *caller);
static void *(*old_malloc)(size_t size, const void *caller);
static void my_free(void *ptr, const void *caller);
static void *my_malloc(size_t size, const void *caller);
static void hook_back()
{
old_malloc = __malloc_hook;
old_free = __free_hook;
}
static void hook_init()
{
__malloc_hook = my_malloc;
__free_hook = my_free;
}
static void hook_restore()
{
__malloc_hook = old_malloc;
__free_hook = old_free;
}
static void my_free(void *ptr, const void *caller)
{
THREAD_AUTOLOCK;
hook_restore();// 这⾥必须,不然会死循环
printf("free address: %x\n", ptr);
电脑热管散热器
free(ptr);
hook_init();
return;
}
static void *my_malloc(size_t size, const void *caller)
{
THREAD_AUTOLOCK;
void *p = NULL;
hook_restore();// 这⾥必须,不然会死循环
重力加速度的测量printf("malloc size: %d\n", size);
回铃音p = malloc(size);
hook_init();
return p;
}
static void my_mempool_destroy()
{
hook_restore();
}
static void my_mempool_init()
{
hook_back();
hook_init();
atexit(my_mempool_destroy);
}
void (*__MALLOC_HOOK_VOLATILE __malloc_initialize_hook) (void) = my_mempool_init;
int main(int argc, char **argv)
{
void *p = malloc(12);
if (p != NULL)
free(p);
return 0;
}
int atexit(void(*func)(void));
其中,atexit的参数是⼀个函数地址,当调⽤此函数时⽆须传递任何参数,该函数也不能返回值,atexit函数称为终⽌处理程序注册程序,注册完成以后,当函数终⽌是exit()函数会主动的调⽤前⾯注册的各个函数,但是exit函数调⽤这些函数的顺序于这些函数登记的顺序是相反的,我认为这实质上是参数压栈造成的,参数由于压栈顺序⽽先⼊后出。同时如果⼀个函数被多次登记,那么该函数也将多次的执⾏。
#include<stdio.h>
#include<stdlib.h>
void func1(void)
{
printf("in func1\n");
}
void func2(void)
{
printf("in func2\n");
}
void func3(void)
{
printf("in func3\n");
}
假牙生产int main()
{
atexit(func3);
atexit(func2);
atexit(func1);
printf("In main\n");
return 0;
}
exit()和_exit()以及_Exit()函数的本质区别是是否⽴即进⼊内核,_exit()以及_Exit()函数都是在调⽤后⽴即进⼊内核,⽽不会执⾏⼀些清理处理,但是exit()则会执⾏⼀些清理处理,这也是为什么会存在atexit()函数的原因,因为exit()函数需要执⾏清理处理,需要执⾏⼀系列的操作,这些终⽌处理函数实际上就是完成各种所谓的清除操作的实际执⾏体。atexit函数的定义也给了程序员⼀种运⽤exit执⾏⼀些清除操作的⽅法,⽐如有⼀些程序需要额外的操作,具体的清除操作可以采⽤这种⽅法对特殊操作进⾏清除等。

本文发布于:2024-09-25 18:26:30,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/311135.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:函数   参数   注册   顺序   变量   操作   清除   完成
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议