繁体   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