Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does VS and Windbg print "this" pointer as "0xcccccccc" even in debug version?

I tried to use windbg to print "this" pointer when entering a member function, like below.

class IBase {
    int m_i;
public:
    IBase() :m_i(23) {}
    virtual int FuncOne(void) = 0;
    virtual int FuncTwo(void) = 0;
};
class DerivedOne : public IBase {
public:
    virtual int FuncOne(void) { return 1; };//set break point here.
    virtual int FuncTwo(void) { return 2; };
};
class DerivedTwo : public IBase {
public:
    virtual int FuncOne(void) { return 101; };
    virtual int FuncTwo(void) { return 102; };
};
void DoIt(IBase* Base)
{
    int i=Base->FuncOne();//break point here
}
int main(int argc, char *argv[])
{
    DerivedOne d1;
    DerivedTwo d2;
    DoIt(&d1);
    DoIt(&d2);
    return 0;
}

(1) I compiled it with VC2015 debug version(32bit)

(2) I set the break point in "DoIt" function.

(3) When hit Base->FuncOne(), I pressed "F11" to enter the function of DerivedOne.

Now I can see the call stack is like this:

0:000> k
 # ChildEBP RetAddr  
00 0041f654 0022157c ConsoleApplication1!DerivedOne::FuncOne [d:\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1.cpp @ 13]
01 0041f734 0022173c ConsoleApplication1!DoIt+0x2c [d:\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1.cpp @ 23]
02 0041f850 00221dc9 ConsoleApplication1!main+0x7c [d:\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1.cpp @ 36]
03 0041f8a0 00221fbd ConsoleApplication1!__tmainCRTStartup+0x199 [f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c @ 626]
04 0041f8a8 75b9338a ConsoleApplication1!mainCRTStartup+0xd [f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c @ 466]
05 0041f8b4 77529902 kernel32!BaseThreadInitThunk+0xe
06 0041f8f4 775298d5 ntdll!__RtlUserThreadStart+0x70
07 0041f90c 00000000 ntdll!_RtlUserThreadStart+0x1b

But "dv" command gave unexpected result

0:000> dv
       this = 0xcccccccc

Why is this? The program runs well, debug version doesn't optimize anything, seems everything is fine. But why "this" pointer is invalid?

I used VC's own IDE to debug, same observation. But why?

like image 783
Troskyvs Avatar asked Sep 05 '16 08:09

Troskyvs


1 Answers

virtual int FuncOne(void) { return 1; };//set break point here.

It is your coding style that causes this issue. Since you wrote the function body in the same line as the function definition, the breakpoint is set at the start of the function, not the start of the function body. At that point the prologue of the function has not been executed yet. The code that sets up the stack frame and retrieves the arguments of the function. The hidden this argument is one of them, it is passed as the first argument of the function.

You can only observe this having the proper value after that prologue code has executed. Which requires using Debug > Windows > Disassembly so you can step past the prologue code, all the way up to instruction after mov dword ptr [this],ecx. Very awkward.

You won't have this issue when it write it like this:

virtual int FuncOne(void)
{ return 1; };//set break point here.

Or whatever brace style you prefer. Now setting the breakpoint ensures that the prologue of the function was executed and this has the expected value.

Or tackle it by knowing that stepping through the function just isn't interesting since it doesn't do anything that's worth debugging. The basic reason you wrote it like that. Use Debug > Step Over instead. If you accidentally stepped into such a function then use Debug > Step Out to quickly get back into code you actually want to debug.

like image 58
Hans Passant Avatar answered Oct 19 '22 15:10

Hans Passant