Watching members in release builds

A typical development scenario:  you fight a bug that raises its head only in production build. You step through your code and inspect member variables, only to be greeted by utter garbage.
There’s an easy workaround, surprisingly.

The calling convention for member methods is thiscall – with a few exceptions (static methods, variable-argument ones and mixing native/managed code). In this convention, the ‘this’ pointer is passed as an implicit argument in the ecx register.

There are two differences between debug and release builds in this respect.
1) In debug builds, the generated debug info (PDB or otherwise) keeps separate track of the ‘this’ context for each stack frame – which is probably impossible (or at least very hard) in optimized builds.
2) In release builds optimized for speed (and not for space), the compiler is inclined to inline methods – thereby bypassing the function call mechanism altogether.

So, in release builds the debugger has little chance of presenting meaningful member info. However, if we know in advance what we’re looking for, we can do much better than the debugger.

1) Pick a ‘heavyweight’ method of the class you wish to watch – one that is unlikely to be inlined – and break immediately after entering it.

2) Make sure the members watch gives meaningful info.  if it doesn’t, try breaking at a different method.
3) Note the value of the ecx register (or ‘this’ pointer – they coincide here), and keep a watch on that value, casted to a class pointer.

setwatch

4) Run until your favorite breakpoint.

Voilà!  Your lost members magically reappear.

Advertisement
This entry was posted in Debugging, VC++, Visual Studio. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s