久综合色-久综合网-玖草影视-玖草资源在线-亚洲黄色片子-亚洲黄色片在线观看

Hello! 歡迎來到小浪云!


linux服務器開發—手寫內存泄漏檢測組件


avatar
小浪云 2025-01-05 123

內存泄漏是在不帶有垃圾回收(garbage Collection)機制的語言中,如c/c++,經常出現的問題。由于缺乏垃圾回收,程序員需要自行管理分配的內存并進行釋放。內存泄漏的根本原因在于程序未能釋放申請的內存。

{ void?*p1?=?malloc(10); void?*p2?=?malloc(20);  free(p1); } 

上述代碼片段中,申請了兩塊內存p1和p2,但只釋放了p1,而未釋放p2,導致了內存泄漏。

內存泄漏可能會導致以下后果:

隨著程序運行時間的增長,未釋放的內存會逐漸累積,導致進程中的可用內存越來越少,最終耗盡。這將導致后續的運行時代碼無法成功分配所需的內存空間。

內存泄漏如何解決?

方案一 引入gc,從語言層面解決內存泄漏;

方案二 當發生內存泄漏的時候,能夠精準的定位代碼那個文件、那個函數、哪一行所引起的。

我們實現的是方案二,核心需求有兩個。

需求1:能夠檢測出內存泄漏

需求2:能夠指出是由代碼的哪個文件、哪個函數、哪一行引起的內存泄漏

內存泄漏檢測如何實現?

內存泄漏檢測實現的核心思想就是對系統的malloc/free進行hook,用我們自己的malloc/free代替系統調用,將free的地址和malloc的地址進行匹配,查看最后又哪些malloc沒有進行free,并將沒有free的malloc操作的代碼段地址進行記錄,通過代碼段定位所在的文件、函數、代碼行。

方案一

采用__libc_malloc, libc_free與__builtin_return_address。它們是gcc提供的函數。

__libc_malloc, libc_free用來代替malloc/free。可以用來實現hook。需要注意的是,我們實現的malloc/free函數,內部會有一些函數如printf,fopen,需要防止它們會嵌套調用malloc/free。

__builtin_return_address,能夠返回調用所在函數的代碼段的地址。能夠定位內存泄漏的具體位置。

malloc的時候,創建一個文件,文件名使用申請內存的地址,并記錄申請該內存的代碼段的地址;free的時候,刪除對應的文件。

#include? #include? #include? ? int?enable_malloc_hook?=?1; extern?void?*__libc_malloc(size_t?size); ? int?enable_free_hook?=?1; extern?void?*__libc_free(void?*p); ? void?*malloc(size_t?size)?{ ? ????if?(enable_malloc_hook)?{ ????????enable_malloc_hook?=?0; ? ????????void?*p?=?__libc_malloc(size); ? ????????void?*caller?=?__builtin_return_address(0); ? ????????char?buff[128]?=?{0}; ????????sprintf(buff,?"./mem/%p.mem",?p); ? ????????FILE?*fp?=?fopen(buff,?"w"); ????????fprintf(fp,?"[+%p]malloc?-->?addr:%p?size:%lu ",?caller,?p,?size); ????????fflush(fp); ? ????????enable_malloc_hook?=?1; ????????return?p; ????}?else?{ ? ????????return?__libc_malloc(size); ? ????} ????return?NULL; } ? void?free(void?*p)?{ ? ????if?(enable_free_hook)?{ ????????enable_free_hook?=?0; ????????char?buff[128]?=?{0}; ????????sprintf(buff,?"./mem/%p.mem",?p); ? ????????if?(unlink(buff)?printf("double?free:?%p ",?p); ????????} ? ????????__libc_free(p); ? ? ????????enable_free_hook?=?1; ????}?else?{ ????????__libc_free(p); ????} ? } ? //?gcc?-o?memleak_0?memleak_0.c?-g //?addr2line?-f?-e??memleak_0??-a?0x4006d8 int?main()?{ ? ? ????void?*p1?=?malloc(10); ????void?*p2?=?malloc(20); ? ????free(p1); ? ????void?*p3?=?malloc(30); ????void?*p4?=?malloc(40); ? ????free(p2); ????free(p4); ? ????return?0; } 

linux服務器開發—手寫內存泄漏檢測組件

方案二

使用宏定義, 開啟宏定義使用我們的版本,不開啟就使用系統的。可以方便debug。

內存泄漏檢測使用malloc_hook/free_hook, 定位內存泄漏位置,使用__FILE__, LINE.

#define?malloc(size)?malloc_hook(size,?__FILE__,?__LINE__)  #define?free(p)?free_hook(p,?__FILE__,?__LINE__) 

可以使用fclose,沒有double free的問題了

#include? #include? #include? ? void?*malloc_hook(size_t?size,?const?char?*file,?int?line)?{ ? ????void?*p?=?malloc(size); ? ????char?buff[128]?=?{0}; ????sprintf(buff,?"./mem/%p.mem",?p); ? ????FILE?*fp?=?fopen(buff,?"w"); ????fprintf(fp,?"[+%s:%d]malloc?-->?addr:%p?size:%lu ",?file,?line,?p,?size); ????fflush(fp); ? ????fclose(fp); ? ????return?p; ? } ? void?free_hook(void?*p,??const?char?*file,?int?line)?{ ? ????char?buff[128]?=?{0}; ????sprintf(buff,?"./mem/%p.mem",?p); ? ????if?(unlink(buff)?printf("double?free:?%p ",?p); ????????return; ????} ? ????free(p); ? } ? #define?malloc(size)???malloc_hook(size,?__FILE__,?__LINE__) ? #define?free(p)????free_hook(p,?__FILE__,?__LINE__) ? ? //?gcc?-o?memleak_0?memleak_0.c?-g //?addr2line?-f?-e??memleak_0??-a?0x4006d8 int?main()?{ ? ? ????void?*p1?=?malloc(10); ????void?*p2?=?malloc(20); ? ????free(p1); ? ????void?*p3?=?malloc(30);???//?memory?leak ????void?*p4?=?malloc(40); ? ????free(p2); ????free(p4); ????free(p4);?//?double?free ? ????return?0; ? } 

檢測出兩個問題,一次內存泄漏 p3,一次double free p4。結果OK。

linux服務器開發—手寫內存泄漏檢測組件

方案三

使用malloc.h中提供的hook: __malloc_hook, __free_hook.

這兩個hook,默認是malloc,free。

參考mtrace的做法,通過改變這兩個值來進行檢測。

#include? #include? #include? #include? ? typedef?void?*(*malloc_hoot_t)(size_t?size,?const?void?*caller); malloc_hoot_t?malloc_f; ? typedef?void?(*free_hook_t)(void?*p,?const?void?*caller); free_hook_t?free_f; ? void?mem_trace(void); void?mem_untrace(void); ? void?*malloc_hook_f(size_t?size,?const?void?*caller)?{ ? ????mem_untrace(); ????void?*ptr?=?malloc(size); ????//?printf("+%p:?addr[%p] ",?caller,?ptr); ????char?buff[128]?=?{0}; ????sprintf(buff,?"./mem/%p.mem",?ptr); ? ????FILE?*fp?=?fopen(buff,?"w"); ????fprintf(fp,?"[+%p]malloc?-->?addr:%p?size:%lu ",?caller,?ptr,?size); ????fflush(fp); ? ????fclose(fp); ???? ????mem_trace(); ????return?ptr; ? } ? void?free_hook_f(void?*p,?const?void?*caller)?{ ????mem_untrace(); ????//?printf("-%p:?addr[%p] ",?caller,?p); ? ????char?buff[128]?=?{0}; ????sprintf(buff,?"./mem/%p.mem",?p); ? ????if?(unlink(buff)?printf("double?free:?%p ",?p); ????} ???? ????free(p); ????mem_trace(); ? } ? void?mem_trace(void)?{ ? ????malloc_f?=?__malloc_hook; ????free_f?=?__free_hook; ? ????__malloc_hook?=?malloc_hook_f; ????__free_hook?=?free_hook_f; } ? void?mem_untrace(void)?{ ? ????__malloc_hook?=?malloc_f; ????__free_hook?=?free_f; ? } ? ? //?gcc?-o?memleak_0?memleak_0.c?-g //?addr2line?-f?-e??memleak_0??-a?0x4006d8 int?main()?{ ? ????mem_trace(); ????void?*p1?=?malloc(10); ????void?*p2?=?malloc(20); ? ????free(p1); ? ????void?*p3?=?malloc(30); ????void?*p4?=?malloc(40); ? ????free(p2); ????free(p4); ????mem_untrace(); ? ????return?0; ? } 

linux服務器開發—手寫內存泄漏檢測組件

方案四

使用mtrace

#include? #include? #include? #include? #include? ? //?gcc?-o?memleak_0?memleak_0.c?-g //?addr2line?-f?-e??memleak_0??-a?0x4006d8 int?main()?{ ? //?export?MALLOC_TRACE=./test.log ????mtrace(); ????void?*p1?=?malloc(10); ????void?*p2?=?malloc(20); ? ????free(p1); ? ????void?*p3?=?malloc(30); ????void?*p4?=?malloc(40); ? ????free(p2); ????free(p4); ????muntrace(); ? #endif ????return?0; ? } 

linux服務器開發—手寫內存泄漏檢測組件

方案五

使用dlsym對malloc,free進行hook。

#define?_GNU_SOURCE #include? ? #include? #include? #include? ? typedef?void?*(*malloc_t)(size_t?size); malloc_t?malloc_f; ? typedef?void?(*free_t)(void?*p); free_t?free_f; ? ? int?enable_malloc_hook?=?1; ? int?enable_free_hook?=?1; ? void?*malloc(size_t?size)?{ ? ????if?(enable_malloc_hook)?{ ????????enable_malloc_hook?=?0; ? ????????void?*p?=?malloc_f(size); ? ????????void?*caller?=?__builtin_return_address(0); ? ????????char?buff[128]?=?{0}; ????????sprintf(buff,?"./mem/%p.mem",?p); ? ????????FILE?*fp?=?fopen(buff,?"w"); ????????fprintf(fp,?"[+%p]malloc?-->?addr:%p?size:%lu ",?caller,?p,?size); ????????fflush(fp); ? ????????enable_malloc_hook?=?1; ????????return?p; ????}?else?{ ? ????????return?malloc_f(size); ? ????} ????return?NULL; } ? void?free(void?*p)?{ ? ????if?(enable_free_hook)?{ ????????enable_free_hook?=?0; ????????char?buff[128]?=?{0}; ????????sprintf(buff,?"./mem/%p.mem",?p); ? ????????if?(unlink(buff)?printf("double?free:?%p ",?p); ????????} ? ????????free_f(p); ? ? ????????enable_free_hook?=?1; ????}?else?{ ????????free_f(p); ????} ? } ? static?int?init_hook()?{ ? ????malloc_f?=?dlsym(RTLD_NEXT,?"malloc"); ? ????free_f?=?dlsym(RTLD_NEXT,?"free"); ? } ? //?gcc?-o?memleak_0?memleak_0.c?-ldl?-g //?addr2line?-f?-e??memleak_0??-a?0x4006d8 int?main()?{ ? ????init_hook(); ? ????void?*p1?=?malloc(10); ????void?*p2?=?malloc(20); ? ????free(p1); ? ????void?*p3?=?malloc(30); ????void?*p4?=?malloc(40); ? ????free(p2); ????free(p4); ? ????return?0; ? } 

linux服務器開發—手寫內存泄漏檢測組件

共享內存

mmap方法1

匿名mmap

#include? #include? #include? ? ? ? void?*shm_mmap_alloc(int?size)?{ ? ????void?*addr?=?mmap(NULL,?size,?PROT_READ|PROT_WRITE,? ????????MAP_ANON?|?MAP_SHARED,?-1,?0); ????if?(addr?==?MAP_FAILED)?{ ????????return?NULL; ????} ? ????return?addr; ? } ? int?shm_mmap_free(void?*addr,?int?size)?{ ? ????return?munmap(addr,?size); ? } ? ? int?main()?{ ? ????char?*addr?=?(char?*)shm_mmap_alloc(1024); ? ????pid_t?pid?=?fork(); ????if?(pid?==?0)?{ ????????//?child ????????int?i?=?0; ? ????????while(i?'a'?+?i++; ????????????addr[i]?=?'

主站蜘蛛池模板:
91av小视频|
精品免费国产
|
亚洲毛片一级巨乳
|
久久久www成人免费精品
|
国产日韩视频在线观看
|
成人网18免费网站
|
小明台湾成人永久免费看看
|
久久成人免费视频
|
91成人国产福利
|
白嫩美女一级毛片免费看
|
亚洲国产一
|
最新国产精品视频免费看
|
亚洲国产成人在线视频
|
农村寡妇女人一级毛片
|
日本特黄特色
|
国产真实女人一级毛片
|
色本道|
亚洲日本高清
|
国产精品一区二区三区久久
|
一级a毛片免费观看久久精品
|
波多野结衣手机视频一区
|
国产美女91视频
|
直接在线观看的三级网址
|
成熟性xxxxx|
中国国产一国产一级毛片视频
|
成人免费网站在线观看
|
久久国产视频网
|
99亚洲自拍
|
亚洲素人在线
|
欧美成人免费一级人片
|
看色网站|
黄录像欧美片在线观看
|
国产福利拍拍拍
|
久久这里有精品视频
|
午夜影院h
|
国产成人自拍在线
|
在线观看的毛片
|
亚洲久草|
日韩黄色一级毛片
|
热99re久久国超精品首页
|
中国一级特黄剌激爽毛片
|