Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"this" pointer getting corrupted in stack trace

I have seen this thread. My case is slightly different and I'm struggling to figure out how "this" pointer is getting corrupted.

I'm using the Qt 4.6.2 framework, using their QTreeView with my own model. The backtrace I get (86 frames long, with a lot of recursion, that's why I haven't pasted the whole thing in, it's in this pastebin only involves their code.

It finally segfaults on some assembler in QBasicAtomicInt::deref, but it's obvious that it has died further down, evidenced by these three frames:

#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

In frame 17, this is 0x942bb0. In frame 16, this should be the same, as in frame 17 it's calling its ancestor's implementation of the same method. However this becomes 0x4.

Interestingly enough in frame 15 (again, frame 16 has called its ancestor's implementation of the same function), the 'this' pointer is restored to 0x942bba0.

If you looked at the pastebin of the full backtrace, you might see some 'value optimized out'. I had the application compiled with optimization on; I now have gcc set to -g3 -O0 so when it happens next time I might have something more. But of course now I can't make it crash -- it is a fairly difficult bug to make happen (but very important to fix nonetheless) so I don't think that's too suspicious.

Given the optimizations, is that this pointer=0x4 unusual or definitely wrong? What is odd is that there's no real code in any of these viewportEvent frames -- they simply do a switch on the event's type, it falls through the switch statement, and it returns its ancestor's implementation.

Valgrind doesn't seem to be throwing up any issues, although I haven't made it crash in Valgrind yet.

Has anybody seen this behaviour before? What could be causing it?

like image 577
xwhatsit Avatar asked Aug 30 '11 06:08

xwhatsit


1 Answers

I have seen this sort of thing before when debugging optimized builds and it has never been an indication of what the real bug is for me.

It is easier to first think about a local variable. In a non-optimized build, everything has its designated place in memory and must be stored after every line of code. This is so the debugger can find it. In an optimized build, values can live in registers without being written to memory. This is a major part of the improved performance of an optimized build. The debugger doesn't understand this and will always look at memory, so you will often see the wrong value.

The same can happen with parameters. If the optimizer decides to pass a parameter in a register, the debugger is still going to look at the stackframe. More specifically, at the location where the parameter would be according to the rules of the calling convention.

The fact that the next frame of the stack has the value properly restored indicates that the generated instructions are dealing with the this parameter correctly, but the debugger just doesn't know where to look for it.

like image 168
IronMensan Avatar answered Nov 04 '22 01:11

IronMensan