"this"指针在堆栈跟踪中损坏

"this" pointer getting corrupted in stack trace

本文关键字:损坏 跟踪 this 指针 堆栈      更新时间:2023-10-16

我看过这个帖子。我的情况略有不同,我正在努力弄清楚"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

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

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

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

有人见过这种行为吗?是什么引起的呢?

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

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

参数也是如此。如果优化器决定在寄存器中传递参数,则调试器仍将查看堆栈帧。更具体地说,根据调用约定的规则,在参数所在的位置。

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