2008-09-30 105 views
4

我想調試內存泄漏問題。我使用mtrace()來獲得malloc/free/realloc跟蹤。我跑了我的編,現在有一個巨大的日誌文件。到現在爲止還挺好。但我在解釋文件時遇到問題。看看這些行:GLIBC:調試內存泄漏:如何解釋輸出mtrace()

@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1502570 0x68 
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1502620 0x30 
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa80 
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1501460 0xa64 

奇怪的是,一個調用(相同的返回地址)負責4個分配。

更奇怪:

@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa2c 
… 
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa80 

這兩條線的塊0x2aaab43a1700一直沒有釋放之間。

有誰知道如何解釋這個?一次通話如何導致4次分配?而且malloc如何返回之前已經分配的地址?

編輯2008/09/30: 分析GLIBC(mtrace.pl)提供的mtrace()輸出的腳本在這裏沒有任何幫助。它只會說:Alloc 0x2aaab43a1700重複。但是,這怎麼會發生?

回答

4

分配內存的函數被多次調用。調用者地址指向執行分配的代碼,並且該代碼只是不止一次運行。

這裏是在C語言的例子:

void *allocate (void) 
{ 
    return (malloc(1000)); 
} 

int main() 
{ 
    mtrace(); 
    allocate(); 
    allocate(); 
} 

從命令mtrace的輸出是:

 
Memory not freed: 
----------------- 
      Address  Size  Caller 
0x0000000000601460 0x3e8 at 0x4004f6 
0x0000000000601850 0x3e8 at 0x4004f6 

注意主叫方地址是如何相同?這就是爲什麼mtrace分析腳本說它們是相同的,因爲同樣的錯誤一次被發現,導致了幾次內存泄漏。

 
Memory not freed: 
----------------- 
      Address  Size  Caller 
0x0000000000601460 0x3e8 at /home/andrjohn/development/playground/test.c:6 
0x0000000000601850 0x3e8 at /home/andrjohn/development/playground/test.c:6 
0

一個可能的解釋是,相同的功能是分配不同的緩衝區大小?一個這樣的例子是strdup。

對於第二個問題,運行時可能會分配一些「靜態」臨時區域,該區域在流程終止之前不會被釋放。在那個時候,操作系統會在這個過程之後進行清理。

想想這樣:在Java中,沒有析構函數,也沒有保證終結將被稱爲任何對象。

+0

它不僅是一個函數調用malloc()幾次,這是acually因爲一個調用的malloc/realloc的/釋放calloc:如果你能

與(1)調試標誌(-g)編譯是有幫助返回地址是一樣的。 如果運行時正在分配臨時區域,爲什麼它返回的指針是由於第二個malloc()? – 2008-09-30 22:05:18

0

嘗試在valgrind下運行您的應用程序。它可能會讓您更好地瞭解實際泄露的內容。

+0

我的經驗是:valgrind不喜歡java。它很容易崩潰。 – 2008-09-30 22:06:21

7

你正在尋找mtrace的直接輸出,這是非常混亂和違反直覺的。幸運的是,有一個perl腳本(稱爲mtrace,可在glibc-utils中找到),它可以非常輕鬆地幫助解析此輸出。

與調試上編譯您的構建和運行命令mtrace像這樣:

$ gcc -g -o test test.c 
$ MALLOC_TRACE=mtrace.out ./test 
$ mtrace test mtrace.out 

Memory not freed: 
----------------- 
    Address  Size  Caller 
0x094d9378 0x400 at test.c:6 

輸出應該是一個很多更容易消化。

+0

我檢查了這個skript已經。它會給我像我的skript一樣的輸出:Alloc X重複。 – 2008-09-30 22:08:55