1. 程式人生 > >【linux】Valgrind工具集詳解(八):Memcheck命令列引數詳解

【linux】Valgrind工具集詳解(八):Memcheck命令列引數詳解

【linux】Valgrind工具集詳解(五):命令列詳解中不夠全,在此專門針對Memcheck工具中的命令列引數做一次詳細的解釋。

Memcheck命令列選項

–leak-check=<no|summary|yes|full> [default: summary]
程式執行完畢後,搜尋記憶體洩漏。預設值為summary,只統計發生了多少次洩漏。如果設定為full或 yes,則每個單獨的洩漏將被詳細顯示或計為錯誤。

–leak-resolution=<low|med|high> [default: high]
在進行洩漏檢查時,確定Memcheck有多大意願將不同的回溯視為相同,以便將多個洩漏合併到單個洩漏報告中。設定為時low,只有前兩個條目需要匹配。什麼時候med,四個條目必須匹配。何時high,所有條目都需要匹配。
對於硬核洩漏除錯,您可能希望 --leak-resolution=high與–num-callers=40一些如此大的數字一起使用 。
請注意,該–leak-resolution設定不會影響Memcheck查詢洩漏的能力。它只會改變結果的呈現方式。

–show-leak-kinds=<set> [default: definite,possible]
在指定–leak-check=full後,設定需要顯示的洩漏型別,具體方法如下:
以逗號分隔的一個或多個列表 definite indirect possible reachable。
all指定完整集(所有洩漏種類)。它相當於 --show-leak-kinds=definite,indirect,possible,reachable。
none 為空集。

–errors-for-leak-kinds=<set> [default: definite,possible]
在指定–leak-check=full後,設定需要計為錯誤的洩漏型別 。與–show-leak-kinds類似。

–leak-check-heuristics=<set> [default: all]
通過啟發式檢測(heuristics),Memcheck可以識別3~4的情況,不把這些報告成記憶體洩漏。Memcheck會把一部分"possibly lost"識別成"still reachable"。啟發式集以下列方式之一指定:
以逗號分隔的一個或多個列表 stdstring length64 newarray multipleinheritance。
all啟用整套啟發式演算法。它相當於 --leak-check-heuristics=stdstring,length64,newarray,multipleinheritance。
none 為空集。

–show-reachable=<yes|no> , --show-possibly-lost=<yes|no>
這些選項提供了另一種指定要顯示的洩漏型別的方法:
–show-reachable=no --show-possibly-lost=yes相當於 --show-leak-kinds=definite,possible。
–show-reachable=no --show-possibly-lost=no相當於 --show-leak-kinds=definite。
–show-reachable=yes相當於 --show-leak-kinds=all。

–xtree-leak=<no|yes> [no]
如果設定為yes,則在退出時執行的洩漏搜尋的結果將以“Callgrind格式”執行樹檔案輸出。請注意,這會自動設定該選項–leak-check=full。生成的檔案將包含以下事件:
RB :可達位元組
PB :可能丟失位元組
IB :間接丟失位元組
DB :絕對丟失位元組(直接加間接)
DIB :絕對間接丟失位元組(DB的子集)
RBk :可達塊
PBk :可能會丟失塊
IBk :間接失去了積木
DBk :絕對丟失了塊
上述所有事件的增加或減少也將在檔案中輸出,以提供2次連續洩漏搜尋之間的增量(增加或減少)。例如,事件iRB的增加是RB事件dPBk的減少PBk。對於第一次洩漏搜尋,增加和減少事件的值將為零。

–xtree-leak-file= [default: xtleak.kcg.%p]
在指定檔案中生成xtree洩漏報告。%p表示當前程序號

–undef-value-errors=<yes|no> [default: yes]
控制Memcheck是否報告使用未定義的值錯誤。

–track-origins=<yes|no> [default: no]
控制Memcheck是否跟蹤未初始化值的來源。預設情況下是no。
設定yes為時,Memcheck會跟蹤所有未初始化值的來源。然後,當報告未初始化的值錯誤時,Memcheck將嘗試顯示值的來源。
效能開銷:它將Memcheck的速度減半,並將記憶體使用量增加至少100MB,甚至更多。
準確性:Memcheck非常準確地跟蹤起源。為了避免非常大的空間和時間開銷,進行了一些近似。Memchecko有可能會報告錯誤的來源,或者無法識別任何來源。
請注意,–track-origins=yes 和–undef-value-errors=no不能同時設定。Memcheck在啟動時會檢查,如果同時設定了這兩項,會報錯。

–partial-loads-ok=<yes|no> [default: yes]
控制Memcheck如何處理32位,64位,128位和256位自然對齊的載入,這些載入來自某些位元組可定址而其他位元組不可定址的地址。何時yes,此類負載不會產生地址錯誤。相反,源自非法地址的載入位元組被標記為未初始化,而與合法地址相對應的載入位元組以正常方式處理。???
當no來自部分無效地址的載入與來自完全無效地址的載入相同時:發出非法地址錯誤,並將結果位元組標記為已初始化。
請注意,以這種方式執行的程式碼違反了ISO C / C ++標準,應該被視為已損壞。如果可能的話,應該修復這樣的程式碼。

–expensive-definedness-checks=<no|auto|yes> [default: auto]
控制Memcheck在檢查某些值的定義時是否應該使用更精確但更昂貴(耗時)的方法。特別是,這會影響整數加法,減法和相等比較的檢測。
選擇–expensive-definedness-checks=yes 最大限度地減少錯誤率,但可能導致高達30%的效能下降。
選擇–expensive-definedness-checks=no 最大限度地提高效能,但通常會產生非常高的錯誤率。
–expensive-definedness-checks=auto強烈建議使用預設設定。

–keep-stacktraces=alloc|free|alloc-and-free|alloc-then-free|none [default: alloc-and-free]
控制哪些堆疊跟蹤保留malloc或free塊。
使用alloc-then-free,在分配時記錄堆疊跟蹤,並與塊關聯。釋放塊時,將記錄第二個堆疊跟蹤,這將替換分配堆疊跟蹤。因此,與此塊相關的任何“釋放後使用”錯誤只能顯示塊被釋放的堆疊跟蹤。
使用時alloc-and-free,儲存塊的分配和釋放堆疊跟蹤。因此,“使用後免費”錯誤將顯示兩者,這可能使錯誤更容易診斷。相比之下alloc-then-free,此設定略微增加了Valgrind的記憶體使用,因為塊包含兩個引用而不是一個引用。
使用時alloc,僅記錄(並報告)分配堆疊跟蹤。使用時free,僅記錄(並報告)釋放堆疊跟蹤。這些值有點降低了Valgrind的記憶體和CPU使用率。它們可能很有用,具體取決於您要搜尋的錯誤型別以及分析它們所需的詳細程度。例如,如果您只對記憶體洩漏錯誤感興趣,則記錄分配堆疊跟蹤就足夠了。
使用時none,不會記錄malloc和free操作的堆疊跟蹤。如果您的程式分配了許多塊和/或從許多不同的堆疊跟蹤中分配/釋放,這可以顯著減少所需的CPU和/或記憶體。當然,對於與堆塊相關的錯誤,將報告的細節很少。
請注意,一旦記錄了堆疊跟蹤,Valgrind就會將堆疊跟蹤保留在記憶體中,即使它沒有被任何塊引用。某些程式(例如,遞迴演算法)可以生成大量的堆疊跟蹤。如果Valgrind在這種情況下使用太多記憶體,則可以減少選項所需的記憶體–keep-stacktraces 和/或使用較小的選項值–num-callers。
如果要使用 --xtree-memory=full記憶體分析(請參閱執行樹),則無法指定–keep-stacktraces=free 或–keep-stacktraces=none。

–freelist-vol= [default: 20000000]
當客戶端程式使用free( C)或 delete (C++)釋放記憶體時 ,該記憶體不會立即可用於重新分配。相反,它被標記為不可訪問並放置在已釋放塊的佇列中。目的是儘可能地推遲釋放記憶體重新流通的點。這增加了Memcheck在釋放後的一段時間內能夠檢測到對塊的無效訪問的機會。

此選項指定佇列中塊的最大總大小(以位元組為單位)。預設值為20000000。增加此值會增加Memcheck使用的記憶體總量,但可能會檢測到釋放塊的無效使用,否則將無法檢測到這些塊。

–freelist-big-blocks= [default: 1000000]
當從可用於重新分配的釋放塊佇列中建立塊時,Memcheck將優先重新迴圈大小大於或等於的塊–freelist-big-blocks。這確保釋放大塊(特別是釋放大於塊的塊 --freelist-vol)不會立即導致空閒列表中的所有(或許多)小塊的再迴圈。換句話說,這個選項增加了發現“小”塊的懸空指標的可能性,即使在釋放大塊時也是如此。

將值設定為0意味著所有塊都按FIFO順序重新迴圈。

–workaround-gcc296-bugs=<yes|no> [default: no]
啟用時,假設讀取和寫入堆疊指標下方的一些小距離是由於GCC 2.96中的錯誤,並且不報告它們。“小距離”預設為256位元組。請注意,GCC 2.96是某些古老Linux發行版(RedHat 7.X)上的預設編譯器,因此您可能需要使用此選項。如果您不必使用它,請不要使用它,因為它可能導致忽略真正的錯誤。更好的選擇是使用更新的GCC,其中修復了此錯誤。

在32位PowerPC Linux上使用GCC 3.X或4.X時,您可能還需要使用此選項。這是因為GCC生成的程式碼偶爾會訪問堆疊指標下方,特別是浮點到/來自整數轉換。這違反了32位PowerPC ELF規範,這使得無法訪問堆疊指標下方的位置。

從版本3.12開始,此選項已棄用,可能會從將來的版本中刪除。您應該使用 --ignore-range-below-sp指定應忽略的堆疊指標下方的精確偏移範圍。一個合適的等價物是–ignore-range-below-sp=1024-1。

–ignore-range-below-sp=-
這是對已棄用–workaround-gcc296-bugs選項的更一般替代 。指定時,它會導致Memcheck不報告堆疊指標下方指定偏移處的訪問錯誤。兩個偏移量必須是正十進位制數,並且 - 有點違反直覺 - 第一個必須更大,以便暗示要忽略的非環繞地址範圍。例如,要忽略堆疊指標下8192位元組的4位元組訪問,請使用–ignore-range-below-sp=8192-8189。只能指定一個範圍。

–show-mismatched-frees=<yes|no> [default: yes]
啟用後,Memcheck將使用與分配函式匹配的函式檢查是否已釋放堆塊。也就是說,它預計free將用於刪除根據所分配的塊malloc,delete供分配的塊new,並delete[]為塊的分配new[]。如果檢測到不匹配,則報告錯誤。這通常很重要,因為在某些環境中,使用不匹配的函式釋放可能會導致崩潰。

然而,存在無法避免這種不匹配的情況。也就是說,當用戶提供 new/ new[]呼叫malloc和delete/或delete[]呼叫的實現時free,這些函式是非對稱內聯的。例如,假設delete[]內聯但new[]不是內聯。結果是Memcheck“看到”所有delete[]呼叫都是直接呼叫free,即使程式源不包含不匹配的呼叫。

這會導致許多令人困惑和無關的錯誤報告。 --show-mismatched-frees=no禁用這些檢查。但是,通常不建議禁用它們,因為您可能會錯過真正的錯誤。

–ignore-ranges=0xPP-0xQQ[,0xRR-0xSS]
Memcheck的可定址性檢查將忽略此選項中列出的任何範圍(並且可以指定多個範圍,用逗號分隔)。

–malloc-fill=
使用指定的位元組填充由malloc, new等分配但不分配的塊calloc。當試圖擺脫模糊的記憶體損壞問題時,這可能很有用。Memcheck仍將分配的區域視為未定義 - 此選項僅影響其內容。請注意,–malloc-fill當它用作客戶端請求VALGRIND_MEMPOOL_ALLOC或VALGRIND_MALLOCLIKE_BLOCK的引數時,不會影響記憶體塊。

–free-fill=
填充由釋放的塊free, delete等等,與指定的位元組值。當試圖擺脫模糊的記憶體損壞問題時,這可能很有用。Memcheck仍將被釋放區域視為無效訪問 - 此選項僅影響其內容。請注意,–free-fill當它用作客戶端請求VALGRIND_MEMPOOL_FREE或VALGRIND_FREELIKE_BLOCK的引數時,不會影響記憶體塊。