Valgrind快速入门指南
Valgrind快速入門指南
介紹
Valgrind工具套件提供了許多調試和分析工具,可幫助您更快更準確地完成程序。這些工具中最受歡迎的名為Memcheck。它可以檢測C和C ++程序中常見的許多與內存相關的錯誤,并可能導致崩潰和不可預測的行為。
本指南的其余部分提供了使用Memcheck開始檢測程序中的內存錯誤所需的最少信息。有關Memcheck和其他工具的完整文檔,請閱讀用戶手冊。
準備你的程序
編譯您的程序-g以包含調試信息,以便Memcheck的錯誤消息包含確切的行號。使用-O0也是一個好主意,如果你能忍受減速。隨著?-O1錯誤消息的行號可能不準確,但總體上說,在上編譯代碼運行MEMCHECK?-O1作品還算不錯,并且與運行速度的提高-O0是相當顯著。-O2不建議使用?以上內容,因為Memcheck偶爾會報告不真實存在的未初始化值錯誤。
3.在Memcheck下運行程序
如果你通常運行這樣的程序:
myprog arg1 arg2使用此命令行:
valgrind --leak-check = yes myprog arg1 arg2Memcheck是默認工具。該--leak-check?選項打開詳細的內存泄漏檢測器。
您的程序運行速度要比正常速度慢(例如20到30次),并且使用更多的內存。Memcheck將發出關于內存錯誤和它檢測到的泄漏的消息。
4.解釋Memcheck的輸出
這是一個C程序,在一個名為ac的文件中,內存錯誤和內存泄漏。
#include <stdlib.h>void f(void){int * x = malloc(10 * sizeof(int));x [10] = 0; //問題1:堆塊超載} //問題2:內存泄漏 - x未釋放int main(void){F();返回0;}大多數錯誤消息如下所示,其中描述了問題1,堆塊溢出:
== 19182 ==無效的寫入大小4== 19182 == at 0x804838F:f(example.c:6)== 19182 == by 0x80483AB:main(example.c:11)== 19182 ==地址0x1BA45050是大小為40的塊后的0個字節== 19182 == at 0x1B8FF5CD:malloc(vg_replace_malloc.c:130)== 19182 == by 0x8048385:f(example.c:5)== 19182 == by 0x80483AB:main(example.c:11)注意事項:
-
每個錯誤信息中有很多信息;?仔細閱讀
-
19182是進程ID;?通常不重要。
-
第一行(“無效寫入...”)告訴您是什么樣的錯誤。在這里,程序寫入一些內存,它不應該由于堆塊超載。
-
第一行下方是堆棧跟蹤,告訴您發生問題的位置。堆棧跟蹤可能會變得相當大,并且令人困惑,尤其是在使用C ++ STL時。從底部讀取它們可以幫助。如果堆棧跟蹤不夠大,請使用該--num-callers選項使其更大。
-
代碼地址(例如,0x804838F)通常不重要,但是對于跟蹤惡意錯誤,偶爾至關重要。
-
一些錯誤消息有一個第二個組件描述所涉及的內存地址。這一個表明,寫入的內存剛剛超過了在example.c的第5行分配了malloc()的塊的結尾。
這是按照報告的順序修復錯誤,因為以前的錯誤可能是由早期錯誤引起的。沒有這樣做是Memcheck的常見原因。
內存泄漏消息如下所示:
== 19182 == 1個塊中的40個字節絕對丟失在1中的損失記錄1中== 19182 == at 0x1B8FF5CD:malloc(vg_replace_malloc.c:130)== 19182 == by 0x8048385:f(ac:5)== 19182 == by 0x80483AB:main(ac:11)堆棧跟蹤告訴您泄漏內存被分配的位置。Memcheck不能告訴你為什么內存泄漏,不幸的是。(忽略“vg_replace_malloc.c”,這是一個實現細節。)
有幾種泄漏;?兩個最重要的類別是:
-
“絕對丟失”:你的程序泄漏記憶 - 修復它!
-
“可能丟失”:你的程序泄漏記憶,除非你用指針來做有趣的事情(比如把它們指向堆塊的中間)。
Memcheck還報告未初始化值的使用,最常見的消息是“有條件跳轉或移動取決于未初始化的值”。確定這些錯誤的根本原因可能很困難。嘗試使用--track-origins=yes以獲取額外的信息。這使Memcheck運行速度更慢,但是您獲得的額外信息通常可以節省大量時間來確定未初始化值的來源。
如果你不理解的錯誤信息,請參閱?從MEMCHECK錯誤消息的說明中Valgrind的用戶手冊?擁有所有錯誤信息MEMCHECK產生的例子。
注意事項
Memcheck不完美;?它偶爾會產生誤報,并且存在抑制這些功能的機制(請參閱?禁止Valgrind用戶手冊中的錯誤)。但是,99%的時間通常是正確的,所以你應該謹防忽略其錯誤信息。畢竟,你不會忽略編譯器生成的警告信息,對吧?如果Memcheck報告不能更改的庫代碼中的錯誤,則抑制機制也很有用。默認抑制集隱藏了很多,但您可能會遇到更多。
Memcheck無法檢測您的程序所具有的每個內存錯誤。例如,它無法檢測到靜態或堆棧上分配的數組的超范圍讀取或寫入。但它應該會檢測到可能會導致程序崩潰的許多錯誤(例如導致分段錯誤)。
嘗試使您的程序如此干凈,Memcheck報告沒有錯誤。一旦你達到這個狀態,更容易看出,當程序更改導致Memcheck報告新的錯誤。Memcheck使用幾年的經驗表明,可以使甚至巨大的程序運行Memcheck-clean。例如,KDE,OpenOffice.org和Firefox的大部分都是Memcheck-clean,或者非常接近它。
總結
以上是生活随笔為你收集整理的Valgrind快速入门指南的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网站访问慢体系
- 下一篇: LeetCode 221 最大正方形