2015-12-17 92 views
2

我試圖修復一個非常大的項目中的內存泄漏。基準已經證實,內存泄漏是一個重大問題,我正在努力尋找它們的來源。從Valgrind輸出中過濾掉垃圾

在一個非常簡單的案例上運行項目,我得到~850個潛在的內存泄漏報告。他們的所有,但約5的樣子:

==83597== 768 bytes in 3 blocks are possibly lost in loss record 743 of 864 
==83597== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==83597== by 0x548EF93: myproject_malloc (mysourcefile.c:48) 
==83597== by 0x4F13FD5: ??? (in /path/to/project/library-version.so) 
==83597== by 0x1101: ??? 
==83597== by 0xF7: ??? 
==83597== by 0x64D4D87: ??? 
==83597== by 0xFFFFFFFFFFFFFFFD: ??? 
==83597== by 0x6: ??? 
==83597== by 0x4F03BB0: ??? (in /path/to/project/library-version.so) 
==83597== by 0xFFFFFFFFFFFFFFFD: ??? 
==83597== by 0x64D4D87: ??? 


==83597== 920 bytes in 1 blocks are possibly lost in loss record 750 of 864 
==83597== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==83597== by 0x548EF93: myproject_malloc (mysourcefile.c:48) 
==83597== by 0x4F13FD5: ??? (in /path/to/project/library-version.so) 
==83597== by 0xFFEFFFD5F: ??? 
==83597== by 0x38F: ??? 
==83597== by 0xFFEFFFE5F: ??? 
==83597== by 0xF: ??? 
==83597== by 0x54542FF: ??? (in /path/to/project/library-version.so) 
==83597== by 0x4F536CA: ??? (in /path/to/project/library-version.so) 
==83597== by 0x64B981F: ??? 
==83597== by 0xF: ??? 
==83597== by 0x54542FF: ??? (in /path/to/project/library-version.so) 


==83597== 1,360 bytes in 1 blocks are possibly lost in loss record 789 of 864 
==83597== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==83597== by 0x548EF93: myproject_malloc (mysourcefile.c:48) 
==83597== by 0x4F13FD5: ??? (in /path/to/project/library-version.so) 
==83597== by 0x1101: ??? 
==83597== by 0x547: ??? 
==83597== by 0x1F: ??? 
==83597== by 0x6584267: ??? 
==83597== by 0x547: ??? 
==83597== by 0x4F13808: ??? (in /path/to/project/library-version.so) 
==83597== by 0x6584267: ??? 
==83597== by 0x6584527: ??? 
==83597== by 0x65805FF: ??? 

我的工作得到的valgrind給予真實的,有用的輸出,而不是???,但它可能是不可能的,而且我希望能夠從memcheck獲得有用的輸出,直到發生這種情況。

一個有用的報告有一個真實的源文件而不是.so文件報告的函數調用(因爲每個輸出報告myproject_malloc是潛在的泄漏源)。什麼是最簡單的方法,我可以從輸出中刪除所有的垃圾,並將其作爲純文本顯示在我的emacs編譯緩衝區中?

我知道我可以編寫一段長達幾十行的Python腳本,通過檢查每次輸入新錯誤報告並計算我看到「.c:\ d +」的次數來完成這項工作,但我更喜歡簡單的東西。

有沒有一種很好的方式來使用命令行工具來做到這一點?或者我不知道的valgrind選項?

回答

0

正如我在評論中所說的,基於起源的壓制並不是一個合適的技術,因爲我正在使用的庫的奇特屬性(幾乎每個堆棧跟蹤都會經過「壞」庫library-version.so並編譯-g不能解決它)。最後我只是寫一個python腳本,我將張貼在這裏爲未來的用戶:

#!/usr/bin/python 

import fileinput 
import re 

START = re.compile("in loss record") 
STOP = re.compile("^==\d+== $") 
GOOD = re.compile(r"\.c:\d+", re.M) 

def main(): 
    in_line = False 
    current = [] 
    for line in fileinput.input(): 
    if in_line: 
     in_line = not STOP.search(line) 
    else: 
     in_line = START.search(line) 

    if in_line: 
     current.append(line) 
    else: 
     match = GOOD.findall("".join(current)) 
     if len(match) > 2: 
     print "".join(current) 
     current = [] 

if __name__ == "__main__": 
    main() 

現在你可以你的Valgrind的輸出保存到一個文件或直接管它這個腳本,它減少了對殘餘。調整len(match) > FOO行以控制您保留的結果數量。

2

不是一個選項,但配置特徵:的valgrind可以與抑制文件,這告訴它忽略某些堆棧跟蹤進行配置。

有關信息,

是的!使用--gen-suppressions=yes功能爲您自動吐出抑制物。你可以編輯它們,如果你喜歡,例如。結合類似的自動生成抑制使用像'*'的通配符。

如果你真的想用手寫抑制,請仔細閱讀說明書。特別要注意的是,C++函數名稱必須被修改(即不能被去除)。

Valgrind的依賴於符號。這些???用於丟失符號(有些不會出現可能的地址)。據我記得,valgrind在檢查符號之後提供,所以(即使有一個合適的通配符可以將?作爲元字符),您無法明確禁止這些符號。

您的堆棧跟蹤缺少項目庫的行號。如果通過調試(-g)進行編譯並設計適當的幀級別抑制,那似乎是一種改進。

+0

我不想基於源抑制,因爲存在堆棧跟蹤,我關心的是通過有問題的庫以及堆棧跟蹤,這些堆棧跟蹤從那裏開始,但進入正確顯示符號的代碼。 AFAIK保存所有信息的唯一方法是根據輸出中好符號的數量來壓縮,而不是其他的。有沒有辦法做到這一點? –

+0

另外,我已經用'-g'編譯(據我所知,在某個角落可能沒有聽到我的Makefile) - 我需要這樣做的原因是因爲我可以不能讓它工作。 –

+0

我指的是具有'/ path/to/project/library-version.so'的行。如果那些具有調試信息,則可行的抑制文件將能夠更好地引用庫中的行號,並對具有問號的堆棧項目使用幀級抑制。 –