在Linux/GCC/C++中,每次調用malloc/free/new/delete時,我都會記錄stderr的內容。我試圖理解一個庫的內存分配,所以我想在運行單元測試時生成這個輸出。我使用valgrind進行mem泄漏檢測,但是我找不到一個讓它只記錄分配的選項。每當調用malloc/free時輸出到stderr
任何想法?我正在尋找最簡單的解決方案。重新編譯庫不是一個選項。
在Linux/GCC/C++中,每次調用malloc/free/new/delete時,我都會記錄stderr的內容。我試圖理解一個庫的內存分配,所以我想在運行單元測試時生成這個輸出。我使用valgrind進行mem泄漏檢測,但是我找不到一個讓它只記錄分配的選項。每當調用malloc/free時輸出到stderr
任何想法?我正在尋找最簡單的解決方案。重新編譯庫不是一個選項。
malloc_hook(3)
允許您全局介入您自己的malloc
函數。 (有__realloc_hook
__free_hook
等爲好,我剛剛離開他們出去的簡單性。)
#include <stdio.h>
#include <malloc.h>
static void *(*old_malloc_hook)(size_t, const void *);
static void *new_malloc_hook(size_t size, const void *caller) {
void *mem;
__malloc_hook = old_malloc_hook;
mem = malloc(size);
fprintf(stderr, "%p: malloc(%zu) = %p\n", caller, size, mem);
__malloc_hook = new_malloc_hook;
return mem;
}
static void init_my_hooks(void) {
old_malloc_hook = __malloc_hook;
__malloc_hook = new_malloc_hook;
}
void (*__malloc_initialize_hook)(void) = init_my_hooks;
$ cat >mem.c <<'EOF' (the code above) EOF $ cc -fPIC -shared -o mem.so mem.c $ LD_PRELOAD=./mem.so ls 0x7ffc14931adc: malloc(5) = 0xb40010 0x7ffc1492c6b0: malloc(120) = 0xb40030 0x7ffc1497f61a: malloc(12) = 0xb40010 0x7ffc1492be38: malloc(776) = 0xb400b0 …
printf
可以稱之爲malloc
,這就是爲什麼我們暫時取消了鉤。如果您以任何方式掛住malloc
,請注意這一點。
This article(向下滾動至底部)提供瞭如何覆蓋全局new
和delete
運營商在C非常清晰和簡潔的描述++(請注意,它不會爲new[]
提供一個例子,但它在概念上類似於) 。
就覆蓋malloc和free而言,由於您正在Linux和GCC上工作,最簡單的方法是使用malloc_hook
和free_hook
。 Here是對這些功能如何工作的非常好的描述。
我沒有這個測試自己,但我敢肯定這會工作:
既然你不想重新編譯庫,讓有意義的輸出(相對於只是「新要求23字節「)可能需要獲取堆棧跟蹤。我記得使用函數來導航堆棧,但我現在找不到它們。也許對system()和pstack(1)的調用可以做到這一點。
您可以重新定義運算符new和delete,並將此新定義放在std C++庫之前。這可能無法捕獲相關庫正在使用的容器和標準組件的調用。這需要重新鏈接。
使用可以使用LD_PRELOAD來更改運算符new和delete動態。如果您的應用程序是動態鏈接的,則不需要重新鏈接。
希望這些指針幫助,我很抱歉,我沒有食譜。
您可以跟蹤到的malloc /電話免費與ltrace:
#include <stdlib.h>
int main (void)
{
void *ptr = malloc(10);
free(ptr);
return 0;
}
$ g++ test.cpp -o test
$ ltrace -e malloc,free ./test
malloc(10) = 0x804a008
free(0x804a008) = <void>
+++ exited (status 0) +++
要跟蹤新/不需要重新編譯,你可能會需要使用像LD_PRELOAD來超越自己的版本的電話刪除呼叫,這是正是什麼LeakTracer做什麼,可能會做你想做的。
這兩種解決方案似乎都需要重新編譯相關庫。 – 2008-11-15 14:56:52