Valgrind 或 Electric Fence 未检测到堆损坏。我应该怀疑吗? (C++)
我最近遇到了我的第一次战斗 (已解决)堆损坏。在我家里的 Linux 机器上,使用 valgrind 和 electric-fence(使用 gdb),罪魁祸首代码退出时没有错误。然而,在我们实验室的 Windows 机器上,我始终从 VS 收到与我引用的帖子中所述的堆损坏相关的错误消息。
valgrind 和 electric fence 不会检测到这样的问题,这是否令人惊讶(或至少不常见)?其他人在此处的答案中提到了一个可能类似的错误,该错误避开了 valgrind 。这些工具无法检测到此问题的原因可能是什么?是否有任何理由怀疑该错误实际上是堆损坏?
更新:正如描述原始问题的帖子中提到的,我发现问题是由于指向 std::vector 中的元素的指针,这变得很糟糕。用 std::list 替换向量(添加新元素时指针不会变得无效)解决了这个问题。因此,回到我关于为什么 valgrind 没有检测到问题的问题,我询问是否有任何关于如何避免将来出现类似情况的建议,即 valgrind 未检测到的内存问题,这是我的问题之一最喜欢的工具。显然,更好地理解 STL 的工作原理是一个好主意。也许我需要在编程等中更加自信地使用断言。
I recently encountered my first battle (solved) with heap corruption. On my linux machine at home the culprit code exits without error using valgrind and electric-fence(with gdb). Yet on the windows machine in our lab, I consistently get the heap corruption related error message from VS described in my referenced post.
Is it surprising (or at least uncommon) that valgrind and electric fence wouldn't detect such a problem? Someone else mentioned a possibly similar bug that eluded valgrind in a answer here. What might be some reasons why this problem wouldn't be detected by these tools? Is there any reason to doubt that error is in fact heap corruption?
Update: As mentioned in the post describing the original problem, I found that the problem was due to having pointers to elements in a std::vector, which became bad. Replacing the vectors with std::list (to which pointers don't become invalid when adding new elements) fixed the problem. So getting back to my question about why valgrind didn't detect the problem, I ask if there are any recommendations about how to avoid a similar situation in the future, namely a memory problem that isn't detected by valgrind which is one of my favorite tools. Obviously getting a better understanding of how STL works would be a good idea. Perhaps I need to be more assertive with assert in my programming, etc.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
因此,Valgrind 未能检测到堆损坏的明显原因是 GCC STL 实现根本没有发生损坏(即没有要检测的错误)。
不幸的是,Valgrind 的运行级别比 STL 低得多,因此许多错误仍未被发现。例如:
幸运的是,GCC STL 有一个特殊的调试模式,旨在捕获许多这样的问题。尝试使用
-D_GLIBCXX_DEBUG
构建原始代码。它可能会捕获原始问题,并且可能会捕获更多您还不知道的问题。So the apparent reason that Valgrind failed to detect your heap corruption is that the corruption did not happen with GCC STL implementation at all (i.e. there was no error to detect).
Unfortunately, Valgrind operates at much lower level than STL, and so many bugs remain undetected. For example:
Fortunately, GCC STL has a special debugging mode, designed to catch many such problems. Try building your original code with
-D_GLIBCXX_DEBUG
. It will likely catch the original problem, and may catch more problems you don't yet know about.如果使用相同的工具在一台机器上获得良好的结果,而在另一台机器上获得糟糕的结果,那么在开发机器上运行一些内存测试将是一个非常好的主意。可以轻松获得 memtest86 的可启动映像,并且某些内存错误可以清楚地解释您的问题。
另一方面,如果您在每台计算机上使用不同的操作系统,则您使用的任何跨平台库的 Windows 版本中也可能(甚至更有可能)存在错误。
If you're getting good results on one machine and bad results on another using the same tool, it'd be a really good idea to run some memory tests on the development machine. Bootable images for memtest86 can be obtained easily, and certain memory errors could explain your issue neatly.
On the other hand, if you're using different operating systems on each machine it's also possible (maybe even more likely) that a bug exists in the windows versions of whatever crossplatform libraries you're using.
你不明白什么是堆损坏。特别是,内存泄漏不是堆损坏。
Parallel Studio 报告的内存泄漏也似乎是伪造的,并且更有可能是 Parallel Studio 中的错误而不是您的程序中的错误。
You don't understand what heap corruption is. In particular, memory leaks are not heap corruption.
The memory leak reported by Parallel Studio also appears bogus, and more likely to be a bug in Parallel Studio than in your program.