Valgrind學習總結
1.Memcheck 工具主要檢查下面的程式錯誤
Use of uninitialised memory:使用未初始化記憶體
Reading/writing memory after it has been free’d :使用已經釋放了的記憶體
Reading/writing off the end of malloc’d blocks:使用超過 malloc配置設定的記憶體空間
Reading/writing inappropriate areas on the stack:對堆棧的非法通路
Memory leaks – where pointers to malloc’d blocks are lost forever:申請的空間是否有釋放
malloc/free/new/delete申請和釋放記憶體的比對(Mismatched use of malloc/new/new [] vs free/delete/delete [])
src和dst的重疊(Overlapping src and dst pointers in memcpy() and related functions)
2.Callgrind
Callgrind收集程式運作時的一些資料,函數調用關系等資訊,還可以有選擇地進行cache模拟。在運作結束時,它會把分析資料寫入一個檔案。callgrind_annotate可以把這個檔案的内容轉化成可讀的形式。
3.Cachegrind
它模拟 CPU中的一級緩存I1,D1和L2二級緩存,能夠精确地指出程式中 cache的丢失和命中。如果需要,它還能夠為我們提供cache丢失次數,記憶體引用次數,以及每行代碼,每個函數,每個子產品,整個程式産生的指令數。這對優化程式有很大的幫助。
4.Helgrind
它主要用來檢查多線程程式中出現的競争問題。Helgrind尋找記憶體中被多個線程通路,而又沒有一貫加鎖的區域,這些區域往往是線程之間失去同步的地方,而且會導緻難以發掘的錯誤。Helgrind實作了名為” Eraser” 的競争檢測算法,并做了進一步改進,減少了報告錯誤的次數。
5.Massif
堆棧分析器,它能測量程式在堆棧中使用了多少記憶體,告訴我們堆塊,堆管理塊和棧的大小。
Massif能幫助我們減少記憶體的使用,在帶有虛拟記憶體的現代系統中,它還能夠加速我們程式的運作,減少程式停留在交換區中的幾率。
安裝:http://valgrind.org/downloads/current.html
源碼下載下傳
解壓:tar -jxvf valgrind-3.15.0.tar.bz2
<1>在root下面解壓:
cd valgrind-3.15.0
./autogen.sh
./configure(可指定安裝路徑 --prefix=/home/zl/opt/valgrind)
make
make install
<2>配置環境變量
編輯.bashrc 檔案添加環境變量
應用
1.檢查記憶體錯誤
1.編譯源程式加上-g 參數
2.使用記憶體檢測工具使用下面方法調用:
#valgrind --leak-check=full --show-reachable=yes --trace-children= yes ./a.out
(其中–leak-check=full指的是完全檢查記憶體洩漏,–show-reachable=yes是顯示記憶體洩漏的地點,–trace-children=yes是跟入子程序。)
如果你的程式是會正常退出的程式,那麼當程式退出的時候valgrind自然會輸出記憶體洩漏的資訊。如果程式是個守護程序,我們 隻要在别的終端下殺死memcheck程序(因為valgrind預設使用memcheck工具,就是預設參數—tools=memcheck):
#killall memcheck
這樣我們的程式(./a.out)就被kill了
2、檢查代碼覆寫和性能瓶頸:
valgrind --tool=callgrind ./a.out
會在目前路徑下生成callgrind.out.pid(目前生産的是callgrind.out.19689),如果我們想結束程式,可以:
#killall callgrind
檢視結果:
#callgrind_annotate --auto=yes callgrind.out.19689 >log
#vim log
可使用的工具如下:
cachegrind是一個緩沖模拟器。它可以用來标出你的程式每一行執行的指令數和導緻的緩沖不命中數。
callgrind在cachegrind基礎上添加調用追蹤。它可以用來得到調用的次數以及每次函數調用的開銷。作為對cachegrind的補充,callgrind可以分别标注各個線程,以及程式反彙編輸出的每條指令的執行次數以及緩存未命中數。
helgrind能夠發現程式中潛在的條件競争。
lackey是一個示例程式,以其為模版可以建立你自己的工具。在程式結束後,它列印出一些基本的關于程式執行統計資料。
massif是一個堆剖析器,它測量你的程式使用了多少堆記憶體。
memcheck是一個細粒度的的記憶體檢查器。
none沒有任何功能。它一般用于Valgrind的調試和基準測試。
基本選項:這些選項對所有工具都有效。
h --help
顯示所有選項的幫助,包括核心和標明的工具兩者。
–help-debug
和–help相同,并且還能顯示通常隻有Valgrind的開發人員使用的調試選項。
–version
顯示Valgrind核心的版本号。工具可以有他們自已的版本号。這是一種保證工具隻在它們可以運作的核心上工作的一種設定。這樣可以減少在工具和核心之間版本相容性導緻奇怪問題的機率。
-q --quiet
安靜的運作,隻列印錯誤資訊。在進行回歸測試或者有其它的自動化測試機制時會非常有用。
-v --verbose
顯示詳細資訊。在各個方面顯示你的程式的額外資訊,例如:共享對象加載,使用的重置,執行引擎和工具的程序,異常行為的警告資訊。重複這個标記可以增加詳細的級别。
-d
調試Valgrind自身發出的資訊。通常隻有Valgrind開發人員對此感興趣。重複這個标記可以産生更詳細的輸出。如果你希望發送一個bug報告,通過-v -v -d -d生成的輸出會使你的報告更加有效。
–tool= [default: memcheck]
運作toolname指定的Valgrind,例如,Memcheck, Addrcheck, Cachegrind,等等。
–trace-children= [default: no]
當這個選項打開時,Valgrind會跟蹤到子程序中。這經常會導緻困惑,而且通常不是你所期望的,是以預設這個選項是關閉的。
–track-fds= [default: no]
當這個選項打開時,Valgrind會在退出時列印一個打開檔案描述符的清單。每個檔案描述符都會列印出一個檔案是在哪裡打開的棧回溯,和任何與此檔案描述符相關的詳細資訊比如檔案名或socket資訊。
–time-stamp= [default: no]
當這個選項打開時,每條資訊之前都有一個從程式開始消逝的時間,用天,小時,分鐘,秒和毫秒表示。
–log-fd= [default: 2, stderr]
指定Valgrind把它所有的消息都輸出到一個指定的檔案描述符中去。預設值2, 是标準錯誤輸出(stderr)。注意這可能會幹擾到用戶端自身對stderr的使用, Valgrind的輸出與客戶程式的輸出将穿插在一起輸出到stderr。
–log-file=
指定Valgrind把它所有的資訊輸出到指定的檔案中。實際上,被建立檔案的檔案名是由filename、’.'和程序号連接配接起來的(即.),進而每個程序建立不同的檔案。
–log-file-exactly=
類似于–log-file,但是字尾".pid"不會被添加。如果設定了這個選項,使用Valgrind跟蹤多個程序,可能會得到一個亂七八糟的檔案。
–log-file-qualifier=
當和–log-file一起使用時,日志檔案名将通過環境變量$VAR來篩選。這對于MPI程式是有益的。更多的細節,檢視手冊2.3節 “注解”。
–log-socket=
指定Valgrind輸出所有的消息到指定的IP,指定的端口。當使用1500端口時,端口有可能被忽略。如果不能建立一個到指定端口的連接配接,Valgrind将輸出寫到标準錯誤(stderr)。這個選項經常和一個Valgrind監聽程式一起使用。更多的細節,檢視手冊2.3節 “注解”。
錯誤相關選項:這些選項适用于所有産生錯誤的工具,比如Memcheck, 但是Cachegrind不行。
–xml= [default: no]
當這個選項打開時,輸出将是XML格式。這是為了使用Valgrind的輸出做為輸入的工具,例如GUI前端更加容易些。目前這個選項隻在Memcheck時生效。
–xml-user-comment=
在XML開頭 附加使用者注釋,僅在指定了–xml=yes時生效,否則忽略。
–demangle= [default: yes]
打開/關閉C++的名字自動解碼。預設打開。當打開時,Valgrind将嘗試着把編碼過的C++名字自動轉回初始狀态。這個解碼器可以處理g++版本為2.X,3.X或4.X生成的符号。
一個關于名字編碼解碼重要的事實是,禁止檔案中的解碼函數名仍然使用他們未解碼的形式。Valgrind在搜尋可用的禁止條目時不對函數名解碼,因為這将使禁止檔案内容依賴于Valgrind的名字解碼機制狀态, 會使速度變慢,且無意義。
–num-callers= [default: 12]
預設情況下,Valgrind顯示12層函數調用的函數名有助于确定程式的位置。可以通過這個選項來改變這個數字。這樣有助在嵌套調用的層次很深時确定程式的位置。注意錯誤資訊通常隻回溯到最頂上的4個函數。(目前函數,和它的3個調用者的位置)。是以這并不影響報告的錯誤總數。
這個值的最大值是50。注意高的設定會使Valgrind運作得慢,并且使用更多的記憶體,但是在嵌套調用層次比較高的程式中非常實用。
–error-limit= [default: yes]
當這個選項打開時,在總量達到10,000,000,或者1,000個不同的錯誤,Valgrind停止報告錯誤。這是為了避免錯誤跟蹤機制在錯誤很多的程式下變成一個巨大的性能負擔。
–error-exitcode= [default: 0]
指定如果Valgrind在運作過程中報告任何錯誤時的退出傳回值,有兩種情況;當設定為預設值(零)時,Valgrind傳回的值将是它模拟運作的程式的傳回值。當設定為非零值時,如果Valgrind發現任何錯誤時則傳回這個值。
在Valgrind做為一個測試工具套件的部分使用時這将非常有用,因為使測試工具套件隻檢查Valgrind傳回值就可以知道哪些測試用例Valgrind報告了錯誤。
–show-below-main= [default: no]
預設地,錯誤時的棧回溯不顯示main()之下的任何函數(或者類似的函數像glibc的__libc_start_main(),如果main()沒有出現在棧回溯中);這些大部分都是令人厭倦的C庫函數。如果打開這個選項,在main()之下的函數也将會顯示。
–suppressions= [default: $PREFIX/lib/valgrind/default.supp]
指定一個額外的檔案讀取不需要理會的錯誤;你可以根據需要使用任意多的額外檔案。
–gen-suppressions= [default: no]
當設定為yes時,Valgrind将會在每個錯誤顯示之後自動暫停并且列印下面這一行:
---- Print suppression ? --- [Return/N/n/Y/y/C/c] ----
這個提示的行為和–db-attach選項(見下面)相同。
如果選擇是,Valgrind會列印出一個錯誤的禁止條目,你可以把它剪切然後粘帖到一個檔案,如果不希望在将來再看到這個錯誤資訊。
當設定為all時,Valgrind會對每一個錯誤列印一條禁止條目,而不向使用者詢問。
這個選項對C++程式非常有用,它列印出編譯器調整過的名字。
注意列印出來的禁止條目是盡可能的特定的。如果需要把類似的條目歸納起來,比如在函數名中添加通配符。并且,有些時候兩個不同的錯誤也會産生同樣的禁止條目,這時Valgrind就會輸出禁止條目不止一次,但是在禁止條目的檔案中隻需要一份拷貝(但是如果多于一份也不會引起什麼問題)。并且,禁止條目的名字像<在這兒輸入一個禁止條目的名字>;名字并不是很重要,它隻是和-v選項一起使用列印出所有使用的禁止條目記錄。
–db-attach= [default: no]
當這個選項打開時,Valgrind将會在每次列印錯誤時暫停并打出如下一行:
---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ----
按下回車,或者N、回車,n、回車,Valgrind不會對這個錯誤啟動調試器。
按下Y、回車,或者y、回車,Valgrind會啟動調試器并設定在程式運作的這個點。當調試結束時,退出,程式會繼續運作。在調試器内部嘗試繼續運作程式,将不會生效。
按下C、回車,或者c、回車,Valgrind不會啟動一個調試器,并且不會再次詢問。
注意:–db-attach=yes與–trace-children=yes有沖突。你不能同時使用它們。Valgrind在這種情況下不能啟動。
2002.05:這是一個曆史的遺留物,如果這個問題影響到你,請發送郵件并投訴這個問題。
2002.11:如果你發送輸出到日志檔案或者到網絡端口,我猜這不會讓你有任何感覺。不須理會。
–db-command= [default: gdb -nw %f %p]
通過–db-attach指定如何使用調試器。預設的調試器是gdb.預設的選項是一個運作時擴充Valgrind的模闆。 %f會用可執行檔案的檔案名替換,%p會被可執行檔案的程序ID替換。
這指定了Valgrind将怎樣調用調試器。預設選項不會因為在構造時是否檢測到了GDB而改變,通常是/usr/bin/gdb.使用這個指令,你可以指定一些調用其它的調試器來替換。
給出的這個指令字串可以包括一個或多個%p %f擴充。每一個%p執行個體都被解釋成将調試的程序的PID,每一個%f執行個體都被解釋成要調試的程序的可執行檔案路徑。
–input-fd= [default: 0, stdin]
使用–db-attach=yes和–gen-suppressions=yes選項,在發現錯誤時,Valgrind會停下來去讀取鍵盤輸入。預設地,從标準輸入讀取,是以關閉了标準輸入的程式會有問題。這個選項允許你指定一個檔案描述符來替代标準輸入讀取。
–max-stackframe= [default: 2000000]
棧的最大值。如果棧指針的偏移超過這個數量,Valgrind則會認為程式是切換到了另外一個棧執行。
如果在程式中有大量的棧配置設定的數組,你可能需要使用這個選項。
valgrind保持對程式棧指針的追蹤。如果棧指針的偏移超過了這個數量,Valgrind假定你的程式切換到了另外一個棧,并且Memcheck行為與棧指針的偏移沒有超出這個數量将會不同。通常這種機制運轉得很好。然而,如果你的程式在棧上申請了大的結構,這種機制将會表現得愚蠢,并且Memcheck将會報告大量的非法棧記憶體通路。這個選項允許把這個閥值設定為其它值。
應該隻在Valgrind的調試輸出中顯示需要這麼做時才使用這個選項。在這種情況下,它會告訴你應該指定的新的閥值。
普遍地,在棧中配置設定大塊的記憶體是一個壞的主意。因為這很容易用光你的棧空間,尤其是在記憶體受限的系統或者支援大量小堆棧的線程的系統上,因為Memcheck執行的錯誤檢查,對于堆上的資料比對棧上的資料要高效很多。如果你使用這個選項,你可能希望考慮重寫代碼在堆上配置設定記憶體而不是在棧上配置設定。
原文連結:https://blog.csdn.net/andylauren/article/details/93189740