Valgrind报告一个系统上的无效读取而不是另一个系统

时间:2015-04-29 15:12:00

标签: c++ c segmentation-fault valgrind

我需要在新机器上运行一个相当大的软件包才能工作。该应用程序是用C和C ++编写的,我在CentOS 6.5上运行。

该程序构建正常,但在我运行它时会出现段错误。使用valgrind,我看到在segfault的位置报告了以下错误:

==23843== Invalid read of size 4
[stack trace here]
==23843==  Address 0x642e7464 is not stack'd, malloc'd or (recently) free'd

因此,出于某种原因,我们正在从内存中读取我们不应该并且正在调用未定义的行为。当我查看我的源文件时,将它们带到另一台CentOS 6.5机器(带有相同的内核)并编译它们(使用相同的makefile和相同的GCC版本)程序似乎运行正常。

我也在那台机器上运行了valgrind,并期望再次看到无效的读取。我的想法是无效的读取总是存在,但由于行为未定义,事情恰好在一台机器上正常工作而在另一台机器上没有。

然而,我发现valgrind报告第二台机器上没有读取错误。怎么可能这样呢?

3 个答案:

答案 0 :(得分:3)

Valgrind使运行环境更具确定性,但并未消除所有随机性。也许其他机器安装了不同版本的库,或者它使用的任何外部文件(文件,网络......)都不同,代码执行不必完全相同。

您应该查看堆栈跟踪并分析发生错误的代码。如果仅从堆栈跟踪中看不明显,则可以使用valgrind参数启动--vgdb=full。一旦发生错误,它将暂停执行并打印出如何附加gdb的说明。或者你可以直接在调试器下运行程序 - 你写道它甚至在没有valgrind的情况下崩溃。

答案 1 :(得分:0)

根据您提供的稀疏信息判断,不同的库版本是最好的猜测。要尝试的事情:

1)通过包管理器使两台机器都是最新的,然后再试一次

2)运行ldd [binary]以查看相关程序使用的所有库。在两台机器上运行类似md5sum的内容,以查明是否存在差异。

总的来说,我的经验是valgrind在检测堆栈上的无效内存访问时非常糟糕,所以这可能是一个隐藏的根本原因。如果所有其他方法都失败了,您可能想尝试使用clang和address sanitizer。它可能会发现valgrind无法捕获的东西,反之亦然。

答案 2 :(得分:0)

这可能是由于使用了不同版本的Valgrind。

在较新版本中会删除一些常见的误报错误。这可以解释为什么一台机器抱怨它(旧版本)而另一台机器不抱怨(较新版本)。