1. 程式人生 > >【linux】Valgrind工具集詳解(三):列印資訊說明

【linux】Valgrind工具集詳解(三):列印資訊說明

一、列印資訊格式

Valgrind列印資訊的格式如下,很容易和程式輸出資訊區分出來

== 程序ID ==Valgrind的列印資訊

二、列印到何處

1、列印到檔案描述符中

主要是設定列印到終端上,預設情況下為2(stderr標準錯誤輸出)。如果要想列印到其他檔案描述符(例如編號9),則可以指定 --log-fd=9。

2、列印到指定檔案中

使用選項:–log-file=filename
若filename是空,則會引發終止。filename中可有三種格式資訊;

  1. %p將被替換為當前程序的ID。當—trace-children=yes,而沒用%p時,所有程序的資訊都輸向同一個檔案,會比較混亂,資訊也可能不全,最好檔名中包含%p。
  2. %q{FOO}被環境變數FOO的值代替,若FOO的內容奇怪的話也可能引發異常。一般不用這種格式,除了極少情況,如基於MPI(一種並行程式開發庫)的程式。若用了此種格式,FOO不能為空,否則也引發異常。一些shell裡面,”{””}”可能需要反斜槓轉義。
  3. %%被代替為%,%不能後接任何其他字元,否則會引發異常。
3、列印到網路套接字(網路)

使用選項:–log-socket=IP:埠號
接收端使用valgrind-listener,valgrind-listener可以接受來自多達50個Valgrinded流程的同時連線。在每行輸出前面,它在圓括號中列印當前活動連線數。
valgrind-listener [–exit-at-zero|-e] [port-number]
valgrind-listener 接受三個命令列選項:

  1. -e --exit-at-zero
    當連線的程序數量回落到零時,退出。沒有它,它將永遠執行,使用Ctrl+c來停止;
  2. –max-connect=INTEGER
    預設情況下,偵聽器最多可以連線50個程序。偶爾,這個數字太小了。使用此選項可提供不同的限制。例如 --max-connect=100。
  3. portnumber
    從預設值(1500)更改它偵聽的埠。指定的埠必須在1024到65535之間。相同的限制適用於由–log-socketValgrind本身指定的埠號 。

如果Valgrinded程序無法連線到偵聽器,無論出於何種原因(偵聽器未執行,無效或無法訪問的主機或埠等),Valgrind將切換回寫入stderr。

三、錯誤資訊分析

Memcheck報告錯誤資訊的一個例子:

==25832== Invalid read of size 4
==25832==    at 0x8048724: BandMatrix::ReSize(int, int, int) (bogon.cpp:45)
==25832==    by 0x80487AF: main (bogon.cpp:66)
==25832==  Address 0xBFFFF74C is not stack'd, malloc'd or free'd

錯誤資訊分析:
程式在地址 0xBFFFF74C處非法讀取了4位元組。在程式原始碼bogon.cpp檔案的第45行 ,ReSize(int, int, int),在程式原始碼bogon.cpp檔案的第66行呼叫,等等。

Valgrind記得所有錯誤報告。檢測到錯誤時,會將其與舊報告進行比較,以檢視它是否重複。如果是,則記錄錯誤,但不會發出進一步的評論。這可以避免被大量的重複錯誤報告所淹沒。

如果想知道每個錯誤發生了多少次,請使用該-v選項執行。執行完成後,所有報告都會打印出來,並按其出現次數排序。這樣可以輕鬆檢視最常出現的錯誤。

通常,應該按照報告的順序嘗試修復錯誤。例如,在Memcheck上執行時,將未初始化的值複製到多個記憶體位置並稍後使用它們的程式將生成多個錯誤訊息。第一個這樣的錯誤訊息可能會給出問題根本原因的最直接線索。

檢測重複錯誤的過程非常昂貴,如果程式產生大量錯誤,可能會成為顯著的效能開銷。為避免出現嚴重問題,Valgrind將在看到1,000種不同的錯誤或者總共10,000,000個錯誤之後停止收集錯誤。在這種情況下,要停止程式並修復它,因為Valgrind在此之後不再輸出任何有價值的資訊。

如果不想受到上述的限制(1,000種不同的錯誤或者發現10,000,000個錯誤後停止收集錯誤)可以使用該 --error-limit=no選項。然後Valgrind將始終顯示錯誤,無論有多少。但是這將會對效能產生不良影響。