11

我见过这个线程。我的情况略有不同,我正在努力弄清楚"this"指针是如何损坏的。

我正在使用 Qt 4.6.2 框架,将它们QTreeView与我自己的模型一起使用。我得到的回溯(86 帧长,有很多递归,这就是为什么我没有把整个东西粘贴进去,它在这个pastebin中只涉及他们的代码。

它最终在 QBasicAtomicInt::deref 中的一些汇编程序上出现了段错误,但很明显它已经死得更远了,这三个框架证明了这一点:

#15 0x01420fd3 in QFrame::event (this=0x942bba0, e=0xbf8eb624) at widgets/qframe.cpp:557
#16 0x014bb382 in QAbstractScrollArea::viewportEvent (this=0x4, e=0x93f9240) at widgets/qabstractscrollarea.cpp:1036
#17 0x0156fbd7 in QAbstractItemView::viewportEvent (this=0x942bba0, event=0xbf8eb624) at itemviews/qabstractitemview.cpp:1610

在第 17 帧中,this0x942bb0。在第 16 帧中,this应该是相同的,因为在第 17 帧中它正在调用其祖先的相同方法的实现。但是this变成0x4。

有趣的是,在第 15 帧(同样,第 16 帧调用了其祖先对同一函数的实现),“this”指针恢复为0x942bba0.

如果您查看完整回溯的 pastebin,您可能会看到一些“优化值”。我在优化的情况下编译了应用程序;我现在将 gcc 设置为,-g3 -O0所以下次发生时我可能会有更多的东西。但当然现在我不能让它崩溃——这是一个相当难以发生的错误(但修复非常重要)所以我不认为这太可疑了。

鉴于优化,这是this pointer=0x4不寻常的还是绝对错误的?奇怪的是,这些 viewportEvent 框架中都没有真正的代码——它们只是对事件的类型进行切换,它通过 switch 语句,并返回其祖先的实现。

Valgrind 似乎没有抛出任何问题,尽管我还没有让它在 Valgrind 中崩溃。

有没有人见过这种行为?可能是什么原因造成的?

4

1 回答 1

8

我之前在调试优化构建时看到过这种事情,但它从来没有表明真正的错误对我来说是什么。

首先考虑局部变量更容易。在未优化的构建中,所有内容在内存中都有指定的位置,并且必须存储在每一行代码之后。这样调试器就可以找到它。在优化的构建中,值可以存在于寄存器中而无需写入内存。这是优化构建的改进性能的主要部分。调试器不理解这一点,总是会查看内存,所以你会经常看到错误的值。

参数也会发生同样的情况。如果优化器决定在寄存器中传递参数,调试器仍然会查看堆栈帧。更具体地说,在参数将根据调用约定规则的位置。

堆栈的下一帧具有正确恢复的值这一事实表明生成的指令正在正确处理 this 参数,但调试器只是不知道在哪里寻找它。

于 2011-08-30T07:47:57.873 回答