#內存泄露# #dmalloc# dmalloc

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'

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章