[英]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
我运行编译的文件,并在编译的程序内部运行固定的模拟设置三遍。 现在,它每次都应该产生完全相同的结果,我通过在不同阶段打印随机数来检查。
当我使用以下选项在 valgrind 中运行程序时:
valgrind --leak-check=full --leak-resolution=high --show-reachable=yes
我在内部没有得到相同的结果
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)
但是,当我使用以下选项时:
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; } );
关于为什么我没有直接发现这个问题的一些评论:
--tool=helgrind
选项运行程序时,问题并没有持续存在。 我得到的一个建议(离线)是 memcheck 用给定的模式预初始化内存,如果未初始化的变量是原因,这将是一个答案。 看起来,helgrind 还控制不同范围内的内存,为我随后的每个模拟提供一个“新鲜”的虚拟内存,这样我的指针排序在重复循环中是稳定的。我希望这对遇到同样问题的人有所帮助。 感谢所有的建议!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.