2010-02-18 51 views
8

我一直在努力寻找一个真正困难的错误崩溃我的应用程序在过去的几个星期。首先,应用程序在分配std :: string时崩溃,然后在没有局部变量的情况下。valgrind的补充?

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

我怀疑这个问题与某种内存损坏问题或指针损坏问题有关。问题是,我不能直观地追踪它。我不知道从哪里开始寻找代码,并且有成千上万行代码需要通过,所以这似乎不是一个现实的解决方案。

所以在谈到Valgrind的...

,我已经在很多时候取决于找到的代码,可能会导致这种类型的碰撞中问题的工具。但是,这一次它已空手而来!当问题发生时,我在valgrind中看不到任何错误,因此我提出这个问题的原因。

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

谢谢!

+0

你可以尝试张贴能重现问题最小,编译代码示例。我敢打赌,试图编写这样的代码示例的行为会让问题变得很明显。如果没有,我们很乐意提供帮助。 – 2010-02-18 14:48:08

+0

您想查看代码崩溃的位置(即崩溃位置的示例)吗?因为没有理由让它像我刚才提到的那样崩溃,但我不介意发布它 – bbazso 2010-02-18 15:01:22

回答

0

您是否尝试过使用lint,flexlint或cppcheck。这些可能有助于确定问题。

如果您知道哪些内存区域被损坏,您是否尝试将此内存标记为受保护的。这可能掩盖了你的问题,根本没有任何帮助,但是如果它仍然崩溃,修改内存的位置将有助于解决你的问题。

+1

如何保护内存?我从来没有这样做过...... – bbazso 2010-02-18 15:01:50

5

根据我的经验,覆盖和净化已经发现了这样的错误,而不是valgrind所没有的(实际上所有发现的问题都是其他问题没有看到的)。

但是有时候没有工具给出提示,你必须挖更多的东西,添加工具,在“修改内存地址”处使用断点,试着简单地通过失败的测试用例等来找出根本原因。这可能是非常痛苦的。

+0

我同意调试器的评论。有时候,最好在内存中设置一个断点,然后等待。 – 2010-02-18 15:36:44

+0

使用gdb,我如何在内存中设置断点来查看它何时写入? – bbazso 2010-02-18 15:59:11

+0

'watch'命令,可能伴随着你认为无效的条件 – 2010-02-18 16:05:10

1

你没有指定平台,但我可以推荐Gimpel PC-lint作为一个很好的静态分析工具(不要被名字愚弄!)。他们还为其他平台提供FlexeLint,但我没有该产品的个人经验。

+0

Gimpel软件是一个很好的装备。 +1 – 2010-02-19 02:43:00

6

我假设你正在使用valgrind的memcheck工具,它是着名的。由于您已经在使用valgrind,因此您可能还会尝试通过valgrind --tool=exp-sgcheck(以前的exp-ptrcheck)运行程序,该工具是一个实验性工具,用于捕获memcheck将会丢失的某些类型的错误,包括对堆栈和全局数组的访问检查,以及使用指向恰好指向有效对象但不是指定对象的指针。它通过使用完全不同的机制来实现这一点,基本上将每个指针跟踪到内存中,而不是跟踪内存本身,并通过使用启发式。

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

+0

我试过了,但我一直得到: sysno == 233 exp-ptrcheck:'不可能'发生: 未处理的系统调用 任何想法? – bbazso 2010-02-18 18:33:24

+0

试了一下,然后它下移到232. :)你在哪里找到系统调用否和它是什么之间的映射? – bbazso 2010-02-18 21:31:37

+0

'/ usr/include/asm-i386/unistd.h'(或x86_64的'asm-x86_64')。我想你可以看到为什么它仍然是实验性的... – mark4o 2010-02-18 21:48:46

2

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

除此之外,你是否启动了警告标志来帮助识别可疑代码?

+0

我试过旗子-fstack-protector-all,我也尝试过libsafe,都是空手而归? :( – bbazso 2010-02-18 18:40:50

0

如果valgrind可以识别传递给free()的错误指针,那么可以尝试在DDD下运行程序,DDD可以在内存位置设置硬件观察点,并在程序出现错误值时暂停程序。如果指针变得很多,你可能需要围绕malloc编写一些代码,并随意跟踪哪些值是好的和坏的。

3

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

More links有效的东西。