簡體   English   中英

valgrind - hellgrind 與泄漏檢查的不同結果

[英]valgrind - different results with hellgrind vs leak-check

我有一些我不明白的奇怪行為。 代碼有點復雜,所以我不會在這里發布它,而是描述行為,並希望有人知道 valgrind 的工作原理,盡管信息很少,但我可以追求一個想法

背景:

我正在為開源的、基於 c/c++ 的基於代理的建模平台fork @ my github開發一些附加功能。 編譯沒問題。 根據我對測試程序的驗證,一切似乎都正常工作。 此外,valgrind 不會報告任何相關錯誤。 但是,可重復性(這是至關重要的)很奇怪。

在框架內定義一個模型文件(基本上是模擬運行的初始化)。 基於此文件,應該能夠重現完全相同的輸出(並且與平台無關)。 在某種程度上這是有效的:如果我啟動模擬環境(GUI 版本),加載文件並運行它,它每次都會產生相同的結果。 此外,使用命令行版本,我每次都得到相同的結果。

但是,如果從模擬環境的一個運行實例中,我不止一次運行同一個模型,那么就會出現奇怪的行為——有時......

使用的編譯器選項:

CC=g++
GLOBAL_CC=-march=native -std=gnu++14
SSWITCH_CC=-fnon-call-exceptions -Og -ggdb3 -Wall

設置:

我運行編譯的文件,並在編譯的程序內部運行固定的模擬設置三遍。 現在,它每次都應該產生完全相同的結果,我通過在不同階段打印隨機數來檢查。

奇怪的行為:

選項1:

當我使用以下選項在 valgrind 中運行程序時:

valgrind --leak-check=full --leak-resolution=high --show-reachable=yes

我在內部沒有得到相同的結果

來自選項 1 的報告:

Finished processing sim1
==6206==
==6206== HEAP SUMMARY:
==6206==     in use at exit: 43 bytes in 1 blocks
==6206==   total heap usage: 4,124,309 allocs, 4,124,308 frees, 888,390,511 bytes allocated
==6206==
==6206== 43 bytes in 1 blocks are still reachable in loss record 1 of 1
==6206==    at 0x4C2DDCF: realloc (vg_replace_malloc.c:785)
==6206==    by 0x5BE7FB2: getcwd (getcwd.c:84)
==6206==    by 0x143391: lsdmain(int, char**) (lsdmain.cpp:203)
==6206==    by 0x10C37D: main (main_gnuwin.cpp:29)
==6206==
==6206== LEAK SUMMARY:
==6206==    definitely lost: 0 bytes in 0 blocks
==6206==    indirectly lost: 0 bytes in 0 blocks
==6206==      possibly lost: 0 bytes in 0 blocks
==6206==    still reachable: 43 bytes in 1 blocks
==6206==         suppressed: 0 bytes in 0 blocks
==6206==
==6206== For counts of detected and suppressed errors, rerun with: -v
==6206== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

選項#2

但是,當我使用以下選項時:

valgrind --tool=helgrind

每次使用命令行版本時,我都會得到相同的結果。 有趣的是,選項#1 的第一個結果與選項#2 的結果相同。

我很樂意提供任何建議。 而且,我不是受過訓練的計算機科學家......我正在使用和 mt1937(每次重新初始化) - 但模擬之間的初始隨機數是相同的,所以我認為錯誤不存在於此。 盡管在運行后期,選項 #1 中的隨機數會發生變化(這是我的測試,除了模擬需要找到平衡的時間)。

最后,我找到了問題:在程序的兩個點上,我對一個臨時向量進行排序,其中包含距離值對和位於 2d 空間上的對象指針:

std::sort( vector.begin(),vector.end() ); // vector of std::pairs<double, pointer>

顯然,解決方案是僅按對的第一項排序:

std::sort( vector.begin(),vector.end(), [](auto const &A, auto const &B ){return A.first < B.first; } );

關於為什么我沒有直接發現這個問題的一些評論:

  • 當我實現這種排序時,我打算使它“穩定”。 對象的指針是獨一無二的,因此在不同的子集中,排序是相同的,並且與我如何將項目添加到集合中的方式無關。
  • 我不認為指針值是(不完全是,但實際上)不受我控制的隨機數。
  • 我沒有看到這一點,因為操作系統(或其他任何東西)總是在程序的不同調用之間分配相同的指針值(我建議有一個總是再次初始化的“虛擬”空間)。 因此,我沒有建議指針是問題所在。
  • 奇怪的是,當我使用 Valgrind 和--tool=helgrind選項運行程序時,問題並沒有持續存在。 我得到的一個建議(離線)是 memcheck 用給定的模式預初始化內存,如果未初始化的變量是原因,這將是一個答案。 看起來,helgrind 還控制不同范圍內的內存,為我隨后的每個模擬提供一個“新鮮”的虛擬內存,這樣我的指針排序在重復循環中是穩定的。

我希望這對遇到同樣問題的人有所幫助。 感謝所有的建議!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM