我有一些我不理解的奇怪行为。该代码有点复杂,因此我不打算在此处发布代码,而是描述行为,并且希望知道了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中的随机数会发生变化(这是我的测试,除了模拟需要找到平衡点的时间之外)。
答案 0 :(得分: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还在不同范围内控制内存,为我的每个后续模拟提供了“新鲜”虚拟内存,以使我的指针排序在重复循环中保持稳定。 我希望这对某人遇到同样的问题有帮助。感谢您的所有建议!