2012-09-27 40 views
9

我需要知道如何找出共享庫中的內存泄漏,這些內存泄漏將被加載到發佈二進制文件中。我的意思是我用-g選項構建的共享庫,但加載共享庫的二進制文件不是用-g選項構建的。valgrind - 在共享庫中查找內存泄漏

我得到泄漏報告如下。

==739== at 0x4A05809: malloc (vg_replace_malloc.c:149) 
==739== by 0x84781B1: ??? 
==739== by 0x87507F5: ??? 
==739== by 0x874CF47: ??? 
==739== by 0x874E657: ??? 
==739== by 0x874F7C2: ??? 
==739== by 0x8779C0C: ??? 

請讓我知道如何從共享庫中獲取泄漏的堆棧跟蹤?

回答

6

假設泄漏確實來自您的共享庫,那麼我認爲這個問題並不是主要可執行文件中缺少調試。

更可能是您的問題是,可執行文件在完成之前通過調用dlclose來卸載共享庫。這意味着,當valgrind檢查泄漏時,庫的所有符號信息都不再加載。

如果您可以重建可執行文件,那麼最簡單的解決方案可能是暫時停止調用dlclose,以便庫保持加載直到結束。

如果你不能做到這一點,那麼請嘗試使用LD_PRELOAD保持庫加載,這樣的:

LD_PRELOAD="/path/to/library.so" valgrind my-executable 

,希望這將欺騙動態鏈接到保持甚至它已被關閉後加載庫。

+0

有一個補丁提供了一個選項來禁用卸載dlclose後的符號。該補丁的工作原理和我已經使用過很多次。但補丁是舊版本,我想現在它已經爛了。 https://bugs.kde.org/show_bug.cgi?id=79362 – k0n3ru

+0

@TomH:讓我指出,「omit dlclose」解決方法可能會導致大量誤報。如果堆棧中存在銷燬堆中元素的對象,那麼這些元素會在輸出中顯示爲泄漏,因爲dlclose會首先完成銷燬。 – newhouse

+0

而第二個不工作,如果valgrind是64位,但你調試32 – newhouse

2

正如前面的答案所示,這是因爲您在程序終止之前關閉了庫,因此符號信息不可用於valgrind。

使用LD_PRELOAD不適用於我;我現在有兩個版本;一個明確不會調用dlclose();在這個版本上,valgrind會正確地報告行號信息,就像您期望的動態鏈接一樣。