简单说说Linux中valgrind进行内存检测
目錄
1. 內存泄漏的產生
2. Valgrind使用的目的
3. 安裝 Valgrind 的命令
4. 如何使用Valgrind
5.valgrind 基本選項
6.valgrind錯誤相關選項。
7.valgrind還能干什么
1. 內存泄漏的產生
內存泄漏(Memory Leak) 是指程序中己動態(tài)分配的堆內存由于某種原因程序未釋放或無法釋放,造成系統(tǒng)內存的浪費,導致程序運行速度減慢甚至系統(tǒng)崩潰等嚴重后果!
2. Valgrind使用的目的
Valgrind 是一款用于內存調試、內存泄漏檢測以及性能分析的軟件開發(fā)工具。在人為編寫代碼不能預防消除內存泄漏的情況下,使用該工具對代碼進行檢測。
3. 安裝 Valgrind 的命令
sudo apt-get install valgrind
4. 如何使用Valgrind
使用示例程序 malloc.c?
#include <stdlib.h> int main() {void *p;p = malloc(20);return 0; }malloc申請內存以后沒有釋放內存
然后輸入命令 gcc –g malloc.c -o?malloc編譯,加入 -g 參數(shù)的目的是為了定位在第幾行.
執(zhí)行 valgrind --tool=memcheck --leak-check=full ./malloc,其中 --leak-check=full 指的是完全檢查內存泄漏,
得到查詢的結果:
==4339== Memcheck, a memory error detector ==4339== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==4339== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==4339== Command: ./a.out ==4339== ==4339== ==4339== HEAP SUMMARY: ==4339== in use at exit: 20 bytes in 1 blocks //退出時使用:1塊中20字節(jié) ==4339== total heap usage: 1 allocs, 0 frees, 20 bytes allocated //總堆使用量:1個分配,0個釋放,20個字節(jié)分配 ==4339== ==4339== 20 bytes in 1 blocks are definitely lost in loss record 1 of 1 //1塊中的20個字節(jié)肯定在1的丟失記錄中丟失 ==4339== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==4339== by 0x10865B: main (main.c:6) ==4339== ==4339== LEAK SUMMARY: ==4339== definitely lost: 20 bytes in 1 blocks //確認丟失:1塊中20字節(jié) ==4339== indirectly lost: 0 bytes in 0 blocks ==4339== possibly lost: 0 bytes in 0 blocks ==4339== still reachable: 0 bytes in 0 blocks ==4339== suppressed: 0 bytes in 0 blocks ==4339== ==4339== For counts of detected and suppressed errors, rerun with: -v ==4339== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)檢測到內存泄漏
其中的含義分別是:
de?nitely lost:確認丟失。 程序中存在內存泄露,應盡快修復。當程序結束時如果一塊動態(tài)分配的內存沒有被釋放且通過程序內的指針變量均無法訪問這塊內存則會報這個錯誤。
indirectly lost:間接丟失。 當使用了含有指針成員的類或結構時可能會報這個錯誤。這類錯誤無需 直接修復,他們總是與”de?nitely lost”一起出現(xiàn),只要修復”de?nitely lost”即可。例子可參考我的例程。
possibly lost:可能丟失。 大多數(shù)情況下應視為與”de?nitely lost”一樣需要盡快修復,除非你的程序 讓一個指針指向一塊動態(tài)分配的內存(但不是這塊內存起始地址),然后通過運算得到這塊內存起始地 址,再釋放它。當程序結束時如果一塊動態(tài)分配的內存沒有被釋放且通過程序內的指針變量均無法訪問這塊內存的起始地址,但可以訪問其中的某一部分數(shù)據(jù),則會報這個錯誤。
still reachable:可以訪問,未丟失但也未釋放。 如果程序是正常結束的,那么它可能不會造成程序崩 潰,但長時間運行有可能耗盡系統(tǒng)資源,因此筆者建議修復它。如果程序是崩潰(如訪問非法的地址而 崩潰)而非正常結束的,則應當暫時忽略它,先修復導致程序崩潰的錯誤,然后重新檢測。
suppressed:已被解決。 出現(xiàn)了內存泄露但系統(tǒng)自動處理了。暫時先無視這類錯誤。
5.valgrind 基本選項
-h --help 顯示所有選項的幫助,包括內核和選定的工具兩者。
--help-debug 和–help相同,并且還能顯示通常只有Valgrind的開發(fā)人員使用的調試選項。
--version 顯示Valgrind內核的版本號。
-q --quiet 安靜的運行,只打印錯誤信息。 在進行回歸測試或者有其它的自動化測試機制時會非常有用。
-v --verbose 顯示詳細信息。 在各個方面顯示你的程序的額外信息,例如:共享對象加載,使用的重置,執(zhí)行引擎和工具的進程,異常行為的警告信息。重復這個標記可以增加詳細的級別。
-d 調試Valgrind自身發(fā)出的信息。 通常只有Valgrind開發(fā)人員對此感興趣。重復這個標記可以產生更詳細的輸出。如果你希望發(fā)送一個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把它所有的信息輸出到指定的文件中。 實際上,被創(chuàng)建文件的文件名是由filename、’.'和進程號連接起來的(即.),從而每個進程創(chuàng)建不同的文件。
--log-socket= 指定Valgrind輸出所有的消息到指定的IP,指定的端口。 當使用1500端口時,端口有可能被忽略。如果不能建立一個到指定端口的連接,Valgrind將輸出寫到標準錯誤(stderr)。這個選項經常和一個Valgrind監(jiān)聽程序一起使用。
6.valgrind錯誤相關選項。
--num-callers= [default: 12] 默認情況下,Valgrind顯示12層函數(shù)調用的函數(shù)名有助于確定程序的位置。 可以通過這個選項來改變這個數(shù)字。這樣有助在嵌套調用的層次很深時確定程序的位置。注意錯誤信息通常只回溯到最頂上的4個函數(shù)。(當前函數(shù),和它的3個調用者的位置)。所以這并不影響報告的錯誤總數(shù)。
( 這個值的最大值是50。注意高的設置會使Valgrind運行得慢,并且使用更多的內存,但是在嵌套調用層次比較高的程序中非常實用。)
--error-limit= [default: yes] 當這個選項打開時,在總量達到10,000,000,或者1,000個不同的錯誤,Valgrind停止報告錯誤。 這是為了避免錯誤跟蹤機制在錯誤很多的程序下變成一個巨大的性能負擔。
--error-exitcode= [default: 0] 指定如果Valgrind在運行過程中報告任何錯誤時的退出返回值,有兩種情況;當設置為默認值(零)時,Valgrind返回的值將是它模擬運行的程序的返回值。當設置為非零值時,如果Valgrind發(fā)現(xiàn)任何錯誤時則返回這個值。
( 在Valgrind做為一個測試工具套件的部分使用時這將非常有用,因為使測試工具套件只檢查Valgrind返回值就可以知道哪些測試用例Valgrind報告了錯誤。)
--show-below-main= [default: no] 默認地,錯誤時的棧回溯不顯示main()之下的任何函數(shù)(或者類似的函數(shù)像glibc的__libc_start_main(),如果main()沒有出現(xiàn)在棧回溯中);這些大部分都是令人厭倦的C庫函數(shù)。如果打開這個選項,在main()之下的函數(shù)也將會顯示。
--suppressions= [default: $PREFIX/lib/valgrind/default.supp] 指定一個額外的文件讀取不需要理會的錯誤; 你可以根據(jù)需要使用任意多的額外文件。
--gen-suppressions= [default: no] 當設置為yes時,Valgrind將會在每個錯誤顯示之后自動暫停并且打印這一行:----Print suppression ? --- [Return/N/n/Y/y/C/c] ----
( 如果選擇是,Valgrind會打印出一個錯誤的禁止條目,你可以把它剪切然后粘帖到一個文件,如果不希望在將來再看到這個錯誤信息。)
( 當設置為all時,Valgrind會對每一個錯誤打印一條禁止條目,而不向用戶詢問。)
( 這個選項對C++程序非常有用,它打印出編譯器調整過的名字。)
--db-attach= [default: no] 當這個選項打開時,Valgrind將會在每次打印錯誤時暫停并打出這一行:---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ----
( 注意:–db-attach=yes與–trace-children=yes有沖突。你不能同時使用它們。Valgrind在這種情況下不能啟動。)
--db-command= [default: gdb -nw %f %p] 通過–db-attach 指定如何使用調試器。 默認的調試器是gdb.默認的選項是一個運行時擴展Valgrind的模板。 %f會用可執(zhí)行文件的文件名替換,%p會被可執(zhí)行文件的進程ID替換。
( 這指定了Valgrind將怎樣調用調試器。默認選項不會因為在構造時是否檢測到了GDB而改變,通常是/usr/bin/gdb.使用這個命令,你可以指定一些調用其它的調試器來替換。)
( 給出的這個命令字串可以包括一個或多個%p %f擴展。每一個%p實例都被解釋成將調試的進程的PID,每一個%f實例都被解釋成要調試的進程的可執(zhí)行文件路徑。 )
--input-fd= [default: 0, stdin] 使用 --db-attach=yes 和 --gen-suppressions=yes 選項,在發(fā)現(xiàn)錯誤時,Valgrind會停下來去讀取鍵盤輸入。 默認地,從標準輸入讀取,所以關閉了標準輸入的程序會有問題。這個選項允許你指定一個文件描述符來替代標準輸入讀取。
--max-stackframe= [default: 2000000] 棧的最大值。 如果棧指針的偏移超過這個數(shù)量,Valgrind則會認為程序是切換到了另外一個棧執(zhí)行。
( 如果在程序中有大量的棧分配的數(shù)組,需要使用這個選項。)
( 普遍地,在棧中分配大塊的內存是一個壞的主意。因為這很容易用光你的棧空間,尤其是在內存受限的系統(tǒng)或者支持大量小堆棧的線程的系統(tǒng)上,因為Memcheck執(zhí)行的錯誤檢查,對于堆上的數(shù)據(jù)比對棧上的數(shù)據(jù)要高效很多。如果你使用這個選項,你可能希望考慮重寫代碼在堆上分配內存而不是在棧上分配。)
7.valgrind還能干什么
Memcheck。 這是valgrind應用最廣泛的工具,一個重量級的 內存檢查器,能夠發(fā)現(xiàn)開發(fā)中絕大多數(shù)內存錯誤使用情況,比如:使用未初始化的內存,使用已經釋放了的內存,內存訪問越界等。
Callgrind。 它主要用來檢查程序中 函數(shù)調用 過程中出現(xiàn)的問題。
Cachegrind。 它主要用來檢查程序中 緩存使用 出現(xiàn)的問題。
Helgrind。 它主要用來檢 查多線程程序中出現(xiàn)的競爭問題。
Massif。 它主要用來檢查程序中 堆棧使用 中出現(xiàn)的問題。
Extension。 可以 利用core提供的功能,自己編寫特定的內存調試工具。
總結
以上是生活随笔為你收集整理的简单说说Linux中valgrind进行内存检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hive 导出json格式 文件_hiv
- 下一篇: 一台服务器最多能创建多少个 TCP 连接