8

过去几周我一直在努力寻找一个让我的应用程序崩溃的非常困难的错误。首先,应用程序在分配 std::string 时崩溃,然后在释放局部变量期间崩溃。

仔细检查代码后,没有理由在这些位置崩溃;但是,它总是在尝试释放无效指针(即指向无效内存的指针)时崩溃。而且我不知道为什么这个指针没有指向正确的位置。

我怀疑这个问题与某种内存损坏问题或指针损坏问题有关。问题是我无法在视觉上追踪它......但是。我不知道从哪里开始查看代码,并且有数千行代码要经过,所以这似乎不是解决问题的现实方法。

所以Valgrind来了……

我多次依赖的工具来查找代码中可能导致此类崩溃的问题。然而,这一次却是空手而归!当问题发生时,我在 valgrind 中看不到任何错误,因此我问这个问题的原因。

是否有任何其他应用程序可以补充 valgrind 并帮助查找代码中可能导致上述崩溃的问题?

谢谢!

4

8 回答 8

6

我假设您正在使用 valgrind 的 memcheck 工具,这就是它的著名之处。由于您已经在使用 valgrind,您也可以尝试通过valgrind --tool=exp-sgcheck(以前exp-ptrcheck)运行您的程序,这是一个实验性工具,旨在捕获 memcheck 将错过的某些类型的错误,包括堆栈和全局数组的访问检查,以及指针的使用碰巧指向一个有效的对象,但不是预期的对象。它通过使用完全不同的机制来做到这一点,本质上是跟踪每个指针到内存中而不是跟踪内存本身,并通过使用启发式方法。

请注意,该工具是实验性的,但您可能会发现它捕获了一些重要的东西。目前它还不支持 OS X 或非 Intel 处理器。

于 2010-02-18T16:31:40.770 回答
5

根据我的经验,coverity 和 purify 发现了比 valgrind 没有发现的错误(实际上所有发现的问题都没有被其他人看到)。

但有时没有工具给出提示,您必须进行更多挖掘,添加仪器,在“修改地址处的内存”上玩断点,尝试简单地测试失败的测试用例等等以找出根本原因。那会很痛苦。

于 2010-02-18T15:02:10.007 回答
3

我的经验是,这类问题通常是由堆溢出引起的。 Electric Fence是我比较喜欢用的一个比较简单的配置调试工具。它的主要用途是作为检查堆溢出的动态分析工具,作为“-fstack-protector-all”检查堆栈溢出的补充。

更多指向 efence 的链接。

于 2010-02-19T05:32:48.243 回答
2

在我看来,使用具有“反向调试”功能的调试器可能会有所帮助。您将能够及时退后一步,并希望找出问题的真正根源。

这里有几个链接:

http://www.gnu.org/software/gdb/news/reversible.html

http://undo-software.com/(对于非商业应用程序显然是免费的)

于 2010-02-20T17:15:53.563 回答
2

是否可能发生一些堆栈损坏?如果是这样,请尝试使用该选项启用堆栈金丝雀-fstack-protector-all,假设您使用的是 g++。

除此之外,您是否设置了警告标志来帮助识别可疑代码?

于 2010-02-18T17:58:46.403 回答
1

您没有指定平台,但我可以推荐Gimpel PC-lint作为出色的静态分析工具(不要被名称所迷惑!)。他们还为其他平台提供 FlexeLint,但我对该产品没有个人经验。

于 2010-02-18T15:09:56.323 回答
0

您是否尝试过使用 lint、flexlint 或 cppcheck。这些可能有助于识别问题。

如果您知道哪个内存区域被损坏,您是否尝试过将此内存标记为受保护。这可能会掩盖您的问题并且根本没有帮助,但是如果它仍然崩溃,那么修改内存的点将有助于解决您的问题。

于 2010-02-18T14:52:30.493 回答
0

如果 valgrind 可以识别传递给的错误指针free(),您可以尝试在 DDD 下运行程序,这可以在内存位置设置硬件监视点,并在程序获得错误值时停止程序。如果指针发生了很大变化,您可能必须围绕 malloc 编写一些代码,并且可以自由地跟踪哪些值是好的和坏的。

于 2010-02-19T02:44:25.163 回答