[历史归档]本文原发布于 cstriker1407.info 个人博客,内容为历史存档,仅供参考。
发布时间:2017-05-16| 标题:一个简单的内存检测脚本|分类:编程 / C && C++ |标签:C&&C++·python && jython
一个简单的内存检测脚本
- 函数替换
- Demo代码和输出
- 内存分析
C语言编程中比较麻烦的就是内存问题,泄露,越界等,而且不好测试。如果是在嵌入式环境下,就更麻烦了,不好单步调试。这里作者笔记一个脚本,可以方便的测试出内存泄露。
函数替换
首先根据自己的环境,替换下内存申请和释放函数
#if1typedefunsignedintMEM_UINT;#defineMEM_LOGprintf#defineMEM_TEST_INT0xABCDEF90#defineMalloc(SIZE_M)\({\intSIZE=SIZE_M;\char*tmp=malloc(sizeof(MEM_UINT)+SIZE+sizeof(MEM_UINT));\*((MEM_UINT*)tmp)=(MEM_UINT)SIZE;\*((MEM_UINT*)(tmp+SIZE+sizeof(MEM_UINT)))=MEM_TEST_INT;\MEM_LOG("MEM_Malloc%x @%s:%d",(MEM_UINT)tmp,__FILE__,__LINE__);\(tmp+sizeof(MEM_UINT));\})#defineFree(POINT_M)\{\char*POINT=POINT_M;\if(POINT==NULL)\{MEM_LOG("MEM_Free_NULL @%s:%d", __FILE__,__LINE__);} \ else \ { \ char *tmp = POINT - sizeof(MEM_UINT); \ MEM_UINT size = *((MEM_UINT *)tmp); \ MEM_UINT test_int = *((MEM_UINT *)(POINT + size)); \ if(test_int != MEM_TEST_INT) \ { \ MEM_LOG("MEM_Over_Write%x%x-%x @%s:%d", (MEM_UINT)tmp, test_int, MEM_TEST_INT, __FILE__,__LINE__);\ }else \ { \ MEM_LOG("MEM_Free%x @%s:%d", (MEM_UINT)tmp, __FILE__,__LINE__);\ } \ free(tmp); \ MEM_LOG("SUCCESS ");\}\}#else#defineMallocmalloc#defineFreefree#endifDemo代码和输出
main.c
intmain(intargc,char*argv[]){char*pTest1=Malloc(2);char*pTest2=Malloc(3);char*pTest3=Malloc(4);char*pTest4=Malloc(5);Free(NULL);Free(pTest1);Free(pTest2);Free(pTest3);char*pTest=Malloc(10);pTest[10]=3;Free(pTest);return0;}输出
MEM_Malloc ba469010 @../MemLeakTest/main.c:51 MEM_Malloc ba469440 @../MemLeakTest/main.c:52 MEM_Malloc ba469460 @../MemLeakTest/main.c:53 MEM_Malloc ba469480 @../MemLeakTest/main.c:54 MEM_Free_NULL @../MemLeakTest/main.c:56 MEM_Free ba469010 @../MemLeakTest/main.c:57 SUCCESS MEM_Free ba469440 @../MemLeakTest/main.c:58 SUCCESS MEM_Free ba469460 @../MemLeakTest/main.c:59 SUCCESS MEM_Malloc ba469460 @../MemLeakTest/main.c:61 MEM_Over_Write ba469460 abcdef03-abcdef90 @../MemLeakTest/main.c:63 SUCCESS内存分析
首先讲下面这份python代码保存,比如保存为MemAnalysis.py
#!/usr/bin/python3# -*- coding: UTF-8 -*-malloc_dict=dict();free_null_list=list();over_write_list=list();defhandle_malloc_line(line_buf):buf_arr=line_buf.split(" ");if(buf_arr[1]inmalloc_dict):print("Addr:%d Malloced Before%s%s "%(buf_arr[1],malloc_dict[buf_arr[1]],line_buf));else:malloc_dict[buf_arr[1]]=line_buf;return;defhandle_free_line(line_buf):buf_arr=line_buf.split(" ");if(buf_arr[1]inmalloc_dict):delmalloc_dict];else:print("Release MEM not Malloced %s"%(line_buf));return;defhandle_free_null_line(line_buf):buf_arr=line_buf.split(" ");free_null_list.append(buf_arr[1]);return;defhandle_over_write_line(line_buf):handle_free_line(line_buf);over_write_list.append(line_buf);return;deffinish_log_handle():print("Free NULL:");forfree_nullinfree_null_list:print(free_null);print("Over Write:");forover_writeinover_write_list:print(over_write);mem_leak_keys=malloc_dict.keys();print("Mem Leak:");formem_leakinmem_leak_keys:print(malloc_dict);return;analysis_dict={"MEM_Malloc":handle_malloc_line,"MEM_Free":handle_free_line,"MEM_Free_NULL":handle_free_null_line,"MEM_Over_Write":handle_over_write_line};log_file=open("mem_test.log","r");whileTrue:line_buf=log_file.readline();ifnotline_buf:break;parse_key_list=analysis_dict.keys();forparse_keyinparse_key_list:start_with_parse_key=line_buf.startswith(parse_key);if(start_with_parse_key==True):parse_func=analysis_dict;parse_func(line_buf);break;else:continue;log_file.close();finish_log_handle();讲日志保存为mem_test.log,和python脚本放到同一目录下,然后执行命令:
$ python3 MemAnalysis.py Free NULL: @../MemLeakTest/main.c:56 Over Write: MEM_Over_Write ba469460 abcdef03-abcdef90 @../MemLeakTest/main.c:63 SUCCESS Mem Leak: MEM_Malloc ba469480 @../MemLeakTest/main.c:54可以看到,内存泄露也越界都别识别出来了。