linux中記憶體洩漏的檢測(二)定製化的malloc/free
《linux中記憶體洩漏的檢測(一)最簡單的方法》介紹了最簡單的記憶體洩漏檢測方法,這種方法雖然簡單,卻有很多現實的問題,導致它不能用於實際的生產中。
直接使用這種方法肯定是不現實的,因為:
(1)把整個工程裡所有呼叫malloc/free的地方都改成my_malloc/my_free,程式碼改動很大。
(2)通常動態庫和靜態庫的程式碼是沒有許可權修改的。
今天就來解決這個問題,動態地決定讓程式使用自己的還是系統的記憶體管理介面。
wrap選項
不希望修改產品程式碼,那麼用於申請/釋放記憶體的介面還是malloc/free。
又想在介面中增加計數的功能,就要再實現一套用於申請/釋放記憶體的介面。新介面不能和malloc/free重名。這太矛盾了。
如果能自己定製一個malloc/free就好了。
幸好GCC也想到了這一點,給我們提供了wrap選項。
這是man ld得到的說明:
–wrap=symbol
Use a wrapper function for symbol. Any undefined reference to symbol will be resolved to
__wrap_symbol
. Any undefined reference to__real_symbol
will be resolved to symbol.This can be used to provide a wrapper for a system function. The wrapper function should be called
__wrap_symbol
. If it wishes to call the system function, it should call__real_symbol
.Here is a trivial example:
>
void * __wrap_malloc (size_t c)
{
printf ("malloc called with %zu\n", c);
return __real_malloc (c);
}
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
If you link other code with this file using –wrap malloc, then all calls to
malloc
will call the function__wrap_malloc
instead. The call to__real_malloc
in__wrap_malloc
will call the real “malloc” function.You may wish to provide a
__real_malloc
function as well, so that links without the –wrap option will succeed. If you do this, you should not put the definition of__real_malloc
in the same file as__wrap_malloc
; if you do, the assembler may resolve the call before the linker has a chance to wrap it tomalloc
.
我把這一大坨英文解釋一下(英語好的同學可以跳過):
wrapper在英文中是包裝的意思,也就是在已經存在無法修改的符號(通常是系統符號)的外面加一層定製化的包裝,這樣我們既可以重用原來的程式碼,又可以加入新的功能。
當你對一個名為symbol
符號使用wrap功能時,任何要用到symbol
的地方實際使用的是__wrap_symbol
符號
考慮到你的__wrap_symbol
只是為了對symbol
加一層包裝,有可能還是要用到真正的symbol
,只需要要你的__wrap_symbol
裡呼叫__real_symbol
即可,因為任何用到__real_symbol
的地方實際使用的是真正的symbol
也就是說,當你對一個名為symbol
符號使用wrap功能時,會得到這樣的效果:
(1)當你呼叫symbol
時實際呼叫的是__wrap_symbol
(2)當你呼叫__real_symbol
時實際呼叫的是symbol
(3)可以把對symbol
包裝的操作當在__wrap_symbol
中,然後再讓__wrap_symbol
呼叫__real_wrap
,就相當於在使用symbol
之前做了自己訂製的附加功能。
定製自己的malloc/free
看上去這個wrap功能正好符合我們的需求,我們來看看具體是怎麼使用。
(1)wrap既可以用於變數符號,也可以用於函式符號,但我們現在要用的只是函式符號,準確地說,就是malloc和free這兩個符號。
(2)這是一個在連結過程中起作用的選項,在連結選項中加上-Wl,--wrap,malloc -Wl,--wrap,free
(3)__wrap_malloc/__wrap_free
函式實現
void * __wrap_malloc(int size)
{
malloc_count++;
return __real_malloc(size);
}
void __wrap_free(void *ptr)
{
free_count++;
__real_free(ptr);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
(4)測試
int main()
{
malloc_count = 0;
free_count = 0;
int *p1 = (int *)malloc(sizeof(int));
int *p2 = (int *)malloc(sizeof(int));
free( p1);
if(malloc_count != free_count)
printf("memory leak!\n");
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
(5)執行
gcc -o test main.c -Wl,--wrap,malloc -Wl,--wrap,free
- 1
- 1
分析
- 優點
(1)使用方便 — 不需要改產品程式碼,只需要修改編譯選項即可完成。
(2)範圍全面 — wrap是個連結選項,對所有通過__wrap_malloc和__wrap_free連結到一起的檔案都起作用,不論是靜態庫還是動態庫。
- 缺點
(1)該方法要求執行結束時對執行中產生的列印分析才能知道結果。
(2)只對C語言適用,不能應用於C++
(3)只能檢測是否洩漏,卻沒有具體資訊,比如洩漏了多少空間
(4)不能說明是哪一行程式碼引起了洩漏
改進
檢測方法有了初步改進,但不能滿足與此,預知下一步改進,且看下回分解
相關文章
- linux中記憶體洩漏的檢測(三)定製化的new/deleteLinux記憶體delete
- MFC 檢測記憶體洩漏的方法記憶體
- iOS檢測記憶體洩漏iOS記憶體
- 如何檢測記憶體洩漏記憶體
- VC++6.0中記憶體洩漏檢測C++記憶體
- linux中記憶體洩漏的檢測(一)最簡單的方法Linux記憶體
- Android 效能優化之記憶體洩漏檢測以及記憶體優化(中)Android優化記憶體
- 如何在 Linux 下檢測記憶體洩漏Linux記憶體
- JavaScript記憶體洩漏檢測工具JavaScript記憶體
- 如何檢查Javascript中的記憶體洩漏JavaScript記憶體
- 使用 Instruments 檢測記憶體洩漏記憶體
- 檢測並排除記憶體洩漏 (轉)記憶體
- 請教 關於記憶體洩漏的檢測方法記憶體
- Android 效能優化之記憶體洩漏檢測以及記憶體優化(上)Android優化記憶體
- Android 效能優化之記憶體洩漏檢測以及記憶體優化(下)Android優化記憶體
- C++ 程式記憶體洩漏檢測方法C++記憶體
- C/C++記憶體洩漏及檢測C++記憶體
- Android檢測記憶體洩漏之leakcanaryAndroid記憶體
- malloc_stats---檢查記憶體洩露的神器記憶體洩露
- vue使用中的記憶體洩漏Vue記憶體
- [譯] Swift 中的記憶體洩漏Swift記憶體
- Android中的記憶體洩漏Android記憶體
- vs中檢測記憶體洩漏的方法記憶體
- iOS記憶體洩漏自動檢測工具PLeakSnifferiOS記憶體
- 記憶體洩漏的原因記憶體
- 急!請教用optimizeit檢測記憶體洩漏的問題?記憶體
- 如何避免JavaScript中的記憶體洩漏?JavaScript記憶體
- Android中的記憶體洩漏模式Android記憶體模式
- Swift 閉包中的記憶體洩漏Swift記憶體
- 介紹Java中的記憶體洩漏Java記憶體
- 關於java中的記憶體洩漏Java記憶體
- 記憶體洩漏記憶體
- 如何檢測記憶體洩漏——過載new和delete記憶體delete
- 【轉】java中的記憶體溢位和記憶體洩漏Java記憶體溢位
- Node.js 應用的記憶體洩漏問題的檢測方法Node.js記憶體
- 1.記憶體優化(一)記憶體洩漏記憶體優化
- WebView引起的記憶體洩漏WebView記憶體
- ARC下的記憶體洩漏記憶體