I had some fun with the Visual Studio debugger today, and actually learnt a few new tricks (even though I’m aware this may be an old hat to some 😉
The problem: I had an object which contained an invalid pointer, and crashed the application. Ups. I could see that the object started out fine, but somewhere along the way said pointer was modified to point to nowhere. I had no idea where the pointer was modified, however.
So what I really wanted to do was my program to break whenever that pointer was touched.
At the first glimpse, this appears easy: You just create a new data breakpoint, telling the debugger that you want to break whenever variable foo is changed.
Unfortunately, this only works if you also give a context in which the variable is valid. (You can only break on foo when you know foo.) And I didn’t have a symbolic name for the object that was valid in all scopes.
What I did have was the object’s address (let’s say 0x002342). I can tell the debugger to set a data breakpoint on that address. It will break when the value at that address is changed. Which still isn’t quite what I wanted.
If I watch the object’s address, the debugger will only watch this one memory location, which is one byte at the start of the object’s memory location. You could tell the debugger to check sizeof(MyCoolClass) bytes for changes. This will break on any change to the object, but if your object isn’t tiny it stalls the debugger.
What I really needed was a breakpoint on the myFooPointer member, which is stored at the n-th byte of the object.
There are several ways to get at the myFooPointer address.
- See the complete address space of the object, by evaluating something like
((void*) 0x002342),123 (replacing 123 with the size of your object), and try to find the offset manually. This is not the brightest idea 😉
- Dereference the pointer by evaluating &((MyCoolClass*) 0x002342)->myFooPointer) and use that address as the breakpoint.
- If you want to be really nifty, you give the expression ((MyCoolClass*) 0x002342)->myFooPointer as the breakpoint location. This works, too.
I also found that when you give an object address as a breakpoint location, the breakpoint will be hit on object deletion.