dmalloc是一個簡單易用的C/C++內存leak檢查工具,以一個運行庫的方式發佈。能夠檢查出直到程序運行結束還沒有釋放的內存,並且能夠精確指出在哪個源文件的第幾行。
dmalloc 主頁: http://dmalloc.com
根據官方網址描述支持常見平臺:AIX, BSD/OS, DG/UX, Free/Net/OpenBSD, GNU/Hurd, HPUX, Irix, Linux, MS-DOG, NeXT, OSF, SCO, Solaris, SunOS, Ultrix, Unixware, Windoze, and even Unicos on a Cray T3E
目前最新版本: dmalloc-5.5.2.tgz
下載,解壓,編譯,安裝,關於編譯安裝可參考
#linux# gdb交叉編譯arm-linux-gnueabihf-gdb
https://blog.csdn.net/xiaoting451292510/article/details/105166739
編譯過程中可能會提示以下錯誤
dmalloc.h:484:7: error: expected identifier or ‘(’ before ‘__extension__’ char *strndup(const char *string, const DMALLOC_SIZE len);
#ifndef DMALLOC_STRDUP_MACRO
/*
* DMALLOC_PNT strdup
*
* DESCRIPTION:
*
* Overload of strdup(3). Allocate and return an allocated block of
* memory holding a copy of a string.
*
* RETURNS:
*
* Success - Valid pointer.
*
* Failure - 0L
*
* ARGUMENTS:
*
* string -> String we are duplicating.
*/
extern
char *strdup(const char *string);
/*
* DMALLOC_PNT strndup
*
* DESCRIPTION:
*
* Overload of strndup(3). Allocate and return an allocated block of
* memory holding a copy of a string with a maximum length.
*
* RETURNS:
*
* Success - Valid pointer.
*
* Failure - 0L
*
* ARGUMENTS:
*
* string -> String we are duplicating.
*
* len -> Length of the string to duplicate.
*/
extern
char *strndup(const char *string, const DMALLOC_SIZE len);
#endif /* ifndef DMALLOC_STRDUP_MACRO */
請將源碼中的宏DMALLOC_STRDUP_MACRO範圍將strndup包裹起來,一般情況下也不建議使用。#linux# #字符串處理# strdup、strndup、strndupa、strdupa
ubuntu16.04-x86-64 安裝到默認路徑(一般不建議安裝到默認路徑,請儘量進行指定路徑安裝)
./configure
make threadscxx
make installthcxx
ubuntu16.04-x86-64安裝到當前路徑
./configure --prefix=/home/cll/99_temp/memory_leak/dmalloc/dmalloc-5.5.2_ubuntu16.04-x86-64
make threadscxx
make installthcxx
arm-linux-gnueabihf安裝到當前路徑
./configure --target=arm-linux-gnueabihf --host=arm-linux-gnueabihf --program-prefix=arm-linux-gnueabihf- CC=arm-linux-gnueabihf-gcc --prefix=/home/cll/99_temp/memory_leak/dmalloc/dmalloc-5.5.2_arm-linux-gnueabihf
make threadscxx
make installthcxx
./configure --prefix=/home/cll/99_temp/memory_leak/dmalloc/dmalloc-5.5.2_ubuntu16.04-x86-64
根據相關提示可以編譯不同的相應版本
To make the thread version of the library type 'make threads'
To make the C++ version of the library type 'make cxx'
To make the shared version of the library type 'make shlib'
將庫xx.a嵌入運行程序,makefile裏面增加:-DDMALLOC -DDMALLOC_FUNC_CHECK -ldmallocthcxx。如果是C程序把-ldmallocthcxx修改爲-ldmalloc即可,如加入以下紅色部分
g++ -Wall -g -DDMALLOC -DDMALLOC_FUNC_CHECK -ldmallocthcxx memleak_test.cpp memleak_test1.cpp memleak_test2.cpp -o memleak_test
執行dmalloc,獲取環境變量信息,並把它設置爲環境變量。
$ ./dmalloc -b -l logfile -i 100 low
DMALLOC_OPTIONS=debug=0x4e48503,inter=100,log=logfile
export DMALLOC_OPTIONS
執行需要檢測的程序,會在同一個目錄下生成一個logfile文件,裏面就是內存泄漏的信息。
./memleak_test
對於任何非malloc/free情況下所發生的內存泄露問題,mtrace並不能找出來。也就是對於new的內存,只能檢測出有泄露,但不能定位。
dmalloc支持兩種使用方式。
- 調試程序只進行dmalloc靜態庫的編譯鏈接(上面介紹的就是這種方式),這種方式的好處是對於代碼量比較大的現有程序,無需要關心每個.c文件的編譯細節,只需要將dmalloc靜態庫放在程序依賴的最後面即可。但缺點是針對不同CPU體系需要了解基本的函數返回地址彙編實現,同時即使得到了泄露源的地址變量,但也需要藉助gdb、objdump或map文件等手段得到該泄露源的真正文件/行號或函數範圍。
- 使用dmalloc靜態庫編譯鏈接外,還需要在每個要調試的.c程序文件中加入dmalloc.h文件的引用,這種方式的原理是使用dmalloc.h頭文件的宏定義將需要調試的.c程序文件中的malloc替換爲dmalloc_malloc,這種方式的好處和上面方式正好相反,不需要了解不同CPU體系的彙編,不需要藉助gdb等工具,因爲編譯宏的替換可以直接使用__FILE__、__LINE__宏,所以得到的調試信息直接是可以看到的文件名/行號。但缺點也很明顯,需要保證所有需要調試的.c程序文件,都要引用了dmalloc.h頭文件。
只進行dmalloc靜態庫的編譯鏈接
內存泄露信息如下:
1588152214: 107: Dumping Not-Freed Pointers Changed Since Start:
1588152214: 107: not freed: '0x7fb6d1608f08|s1' (36 bytes) from 'unknown'
1588152214: 107: not freed: '0x7fb6d1608f48|s1' (32 bytes) from 'unknown'
1588152214: 107: not freed: '0x7fb6d1608f88|s1' (28 bytes) from 'unknown'
1588152214: 107: not freed: '0x7fb6d1608fc8|s1' (24 bytes) from 'unknown'
1588152214: 107: not freed: '0x7fb6d160bf48|s1' (20 bytes) from 'unknown'
使用dmalloc靜態庫編譯鏈接外,還需要在每個要調試的.c程序文件中加入dmalloc.h文件的引用
內存泄露信息如下:
1588151651: 107: 200 1 0 0 memleak_test.cpp:72
1588151651: 107: 100 1 0 0 memleak_test.cpp:71
1588151651: 107: 100 1 0 0 memleak_test.cpp:68
1588151651: 107: 100 1 100 1 memleak_test.cpp:65
1588151651: 107: 100 1 100 1 memleak_test.cpp:67
1588151651: 107: 100 1 0 0 memleak_test.cpp:74
1588151651: 107: 100 1 0 0 memleak_test.cpp:66
1588151651: 107: 100 1 0 0 memleak_test.cpp:64
1588151651: 107: 50 1 0 0 memleak_test.cpp:70
1588151651: 107: 961 11 201 3 Total of 11
1588151651: 107: Dumping Not-Freed Pointers Changed Since Start:
1588151651: 107: not freed: '0x7f1bc74d9f08|s1' (36 bytes) from 'unknown'
1588151651: 107: not freed: '0x7f1bc74d9f48|s1' (32 bytes) from 'unknown'
1588151651: 107: not freed: '0x7f1bc74d9f88|s1' (28 bytes) from 'unknown'