Why does the 'this' pointer change its value while passing through the code?

I am debugging a crash, and I noticed how a step through the debugger, the this pointer changed its value, and after 3 steps it finally got the value 0x00000001 and the application crashed.

Now the value 0x00000001 is obviously wrong, but should I expect this change when passing through the debugger?

Below the constructor I debug where it crashes. I added the value of this pointer in the comments with each step, and as you can see, it jumps quite a bit.

 CADOCommand::CADOCommand(CADODatabase* pAdoDatabase, CString strCommandText, int nCommandType) { m_pCommand = NULL; m_pCommand.CreateInstance(__uuidof(Command)); // this = 0x515f9d10 m_strCommandText = strCommandText; // this = 0x2c0c0ee8 m_pCommand->CommandText = m_strCommandText.AllocSysString(); // this = 0x515f9d20 m_nCommandType = nCommandType; // this = 0x70847a55 m_pCommand->CommandType = (CommandTypeEnum)m_nCommandType; // this = 0x00000001 m_pCommand->ActiveConnection = pAdoDatabase->GetActiveConnection(); m_nRecordsAffected = 0; } 

Are there any circumstances where the value of this can or should change when passing code in this member function?

Update

I have to add for recording and in response to a few comments, I debugged the release build, but when I debug the same function in the debug build, this value did not change in the end.

So what does this mean if there is a problem only in the release build?

The comment from @drescherjm is saved, which says in release mode the this pointer is not correct because of optimization , but what exactly does this mean "wrong"? That we cannot trust this pointer in the release assembly (is fictitious) or that the pointer value is correct, but the release collection is broken due to optimization?

+5
source share
2 answers

Depending on the debugger, it may be normal to see a change in the this value between clicking on a function and entering it.

this == 0xcccccccc before entering the function

hit S::f()

it has a valid address after entering the function

input S::f()

However, once you have entered the function, this value should not change 1 . If so, that probably means you have something like a buffer overflow and overwrites your stack.

Finding out a problem can be difficult. You can try setting memory breakpoints on this to see when it changes or comments out the code until the problem goes away. This should help you narrow it down. Note that the culprit may not even be in this particular function: memory corruption is notorious for causing chaos in unrelated places.

You also seem to be looking at this using an optimized build. Be very careful when relying on the debugger when optimizations have been used: variables can disappear from your code, giving the impression that their value is incorrect. If you can reproduce the problem, I will try to write this somewhere, and not look at it through the debugger. In fact, it could be a red herring.

1 However, this can change when you call another member function in a hierarchy, especially when virtual databases are involved.

+5
source

Since your example starts by creating an instance from the GUID obtained with __uuidof , there is one factor that can also make the release very different from the debug code: according to the docs, __uuidof overwritten at runtime in debug builds and compiled for releases. In the first case, the worst case is that the load / bind order of the module may be affected.

__ uuidof Operator

https://msdn.microsoft.com/en-us/library/zaah6a61.aspx


Note:

In the debug build, __ uuidof always initializes the object dynamically (at run time). In the release build, __ uuidof can statically (at compile time) initialize the object.

When something is wrong with the version or otherwise, it is also possible that the runtime value is different from the result associated with the statics, which means that you can debug different objects in the release and debug scripts.

0
source

All Articles