這是內置功能,原文見 http://blog.csdn.net/yf210yf/article/details/8022192 ,這裏作下美化。linux
只能分析出malloc、free。ios
#include <iostream> #include <mcheck.h> #include <stdlib.h> using namespace std; int main() { setenv("MALLOC_TRACE","output",1); // stdlib.h ,指定輸出文件名 mtrace(); int *p1=new int; int *p2=new int; // line 11 int *p3=(int*)malloc(sizeof(int)); int *p4=(int*)malloc(sizeof(int)); // line 13 delete p1; free(p3); return 0; }
編譯運行:c++
$ g++ -Wall -g example06.cpp # -g必定要加 $ ./a.out
output文件內容:bash
= Start @ /usr/lib/x86_64-linux-gnu/libstdc++.so.6:(_Znwm+0x1d)[0x7f9a862b2dad] + 0x19e8730 0x4 @ /usr/lib/x86_64-linux-gnu/libstdc++.so.6:(_Znwm+0x1d)[0x7f9a862b2dad] + 0x19e8750 0x4 @ ./a.out:[0x4008c4] + 0x19e8770 0x4 @ ./a.out:[0x4008d2] + 0x19e8790 0x4 @ ./a.out:[0x4008e2] - 0x19e8730 @ ./a.out:[0x4008ee] - 0x19e8770 @ /lib/x86_64-linux-gnu/libc.so.6:(clearenv+0x7a)[0x7f9a85ecafaa] - 0x19e8010 @ /lib/x86_64-linux-gnu/libc.so.6:(tdestroy+0x5d)[0x7f9a85f85a6d] - 0x19e8290 @ /lib/x86_64-linux-gnu/libc.so.6:[0x7f9a85ff400c] - 0x19e82b0
使用mtrace命令分析:函數
mtrace ./a.out ./output - 0x00000000019e8010 Free 8 was never alloc'd 0x7f9a85ecafaa - 0x00000000019e8290 Free 9 was never alloc'd 0x7f9a85f85a6d - 0x00000000019e82b0 Free 10 was never alloc'd 0x7f9a85ff400c Memory not freed: ----------------- Address Size Caller 0x00000000019e8750 0x4 at 0x7f9a862b2dad 0x00000000019e8790 0x4 at /path/to/example06.cpp:13
指出了有兩個地方出現了問題。第一個信息應該是line 11的p2,但並未分析出來。第二處是第13行的變量未被free。spa
下載地址: http://www.linkdata.se/sourcecode/memwatch/.net
參考:http://brantc.blog.51cto.com/410705/116677/code
也是針對free、malloc,對new、delete不起做用。blog
示例代碼:get
#include <iostream> #include <mcheck.h> #include <stdlib.h> #include "memwatch/memwatch.h" using namespace std; int main() { int *p1=new int; int *p2=new int; int *p3=(int*)malloc(sizeof(int)); int *p4=(int*)malloc(sizeof(int)); // line 12 delete p1; free(p3); return 0; }
編譯運行:
$ g++ -g -DMEMWATCH -DMW_STDIO memwatch/memwatch.c example07.cpp $ ./a.out
-D
用來定義宏。
當前目錄下出現memwatch.log文件,內容以下:
============= MEMWATCH 2.71 Copyright (C) 1992-1999 Johan Lindh ============= Started at Tue Oct 4 23:09:23 2016 Modes: __STDC__ 64-bit mwDWORD==(unsigned int) mwROUNDALLOC==8 sizeof(mwData)==56 mwDataSize==56 Stopped at Tue Oct 4 23:09:23 2016 unfreed: <2> example07.cpp(12), 4 bytes at 0x13063b0 {FE FE FE FE .. .. .. .. .. .. .. .. .. .. .. .. ....} Memory usage statistics (global): N)umber of allocations made: 2 L)argest memory usage : 8 T)otal of all alloc() calls: 8 U)nfreed bytes totals : 4
至於memwatch的原理,從memwatch.h中的這兩行代碼能夠看出:
#define malloc(n) mwMalloc(n,__FILE__,__LINE__) // ... #define free(p) mwFree(p,__FILE__,__LINE__)
咱們看下預編譯的效果:
$ g++ -E -DMEMWATCH -DMW_STDIO example07.cpp -o example07.pre.cpp
example07.pre.cpp中main函數以下:
int main() { int *p1=new int; int *p2=new int; int *p3=(int*)mwMalloc(sizeof(int),"example07.cpp",11); int *p4=(int*)mwMalloc(sizeof(int),"example07.cpp",12); delete p1; mwFree(p3,"example07.cpp",15); return 0; }
用malloc hook應該也能實現。
到 http://dmalloc.com/ 下載,解壓、編譯、安裝:
$ ./configure $ make $ sudo make install
編輯~/.bashrc
或者一個新文件 加入:
function dmalloc { eval `command dmalloc -b $*`; }
$ source ~/.bashrc
源碼:
#include <iostream> #include <mcheck.h> #include <stdlib.h> #ifdef DMALLOC #include <dmalloc.h> #endif using namespace std; int main() { int *p1=new int; int *p2=new int; int *p3=(int*)malloc(sizeof(int)); int *p4=(int*)malloc(sizeof(int)); // line 16 delete p1; free(p3); return 0; }
$ dmalloc -b -l logfile -i 100 low $ g++ -Iinclude -Llib -DDMALLOC -DDMALLOC_FUNC_CHECK example08.cpp -ldmalloc $ ./a.out
運行a.out
,當前目錄下生成logfile文件,內容以下:
1475635014: 6: Dmalloc version '5.5.2' from 'http://dmalloc.com/' 1475635014: 6: flags = 0x4e48503, logfile 'logfile' 1475635014: 6: interval = 100, addr = 0, seen # = 0, limit = 0 1475635014: 6: starting time = 1475635014 1475635014: 6: process pid = 11053 1475635014: 6: Dumping Chunk Statistics: 1475635014: 6: basic-block 4096 bytes, alignment 8 bytes 1475635014: 6: heap address range: 0x7ff352638000 to 0x7ff352643000, 45056 bytes 1475635014: 6: user blocks: 1 blocks, 4072 bytes (9%) 1475635014: 6: admin blocks: 10 blocks, 40960 bytes (91%) 1475635014: 6: total blocks: 11 blocks, 45056 bytes 1475635014: 6: heap checked 1 1475635014: 6: alloc calls: malloc 4, calloc 0, realloc 0, free 2 1475635014: 6: alloc calls: recalloc 0, memalign 0, valloc 0 1475635014: 6: alloc calls: new 0, delete 0 1475635014: 6: current memory in use: 8 bytes (2 pnts) 1475635014: 6: total memory allocated: 16 bytes (4 pnts) 1475635014: 6: max in use at one time: 16 bytes (4 pnts) 1475635014: 6: max alloced with 1 call: 4 bytes 1475635014: 6: max unused memory space: 48 bytes (75%) 1475635014: 6: top 10 allocations: 1475635014: 6: total-size count in-use-size count source 1475635014: 6: 4 1 4 1 example08.cpp:16 1475635014: 6: 4 1 0 0 example08.cpp:15 1475635014: 6: 8 2 4 1 Total of 2 1475635014: 6: Dumping Not-Freed Pointers Changed Since Start: 1475635014: 6: not freed: '0x7ff352642fc8|s1' (4 bytes) from 'example08.cpp:16' 1475635014: 6: not freed: '0x7ff352642fe8|s1' (4 bytes) from 'unknown' 1475635014: 6: total-size count source 1475635014: 6: 4 1 example08.cpp:16 1475635014: 6: 4 1 Total of 1 1475635014: 6: ending time = 1475635014, elapsed since start = 0:00:00