Breaking when a function returns a specific value without depending on its call site

Jigar Mehta writes today about how to set a breakpoint in the debugger on a function and check its return value using conditionals, in another post in his fine blog, that can teach even a seasoned Windbg user a thing or two (personally I didn’t know of the “-psn” switch that allows easy attachment to a service process until reading about there).

However, Jigar’s approach requires to determine the call site of the interesting function and breaking after its return for examining the return value. This may be tolerable if you are only interested in what the function returns when invoked from a specific location, but for more general scenarios can be insufficient.

An alternative approach is to use the “gu” debugger command (go up to after the call site) and examine the return value register and potentially other output parameters at that state. For example:

0:000> bp kernel32!CreateFileW "gu; j @eax == -1 '.echo CreateFileW failed; gc' '.printf \"CreateFileW returned %p\", @$retreg; .echo; gc'"
0:000> g
ModLoad: 5cb70000 5cb96000 C:\WINDOWS\system32\ShimEng.dll
ModLoad: 74d90000 74dfb000 C:\WINDOWS\system32\USP10.dll
CreateFileW returned 000007c8
ModLoad: 74720000 7476b000 C:\WINDOWS\system32\MSCTF.dll
CreateFileW returned 00000774
CreateFileW returned 00000774
ModLoad: 755c0000 755ee000 C:\WINDOWS\system32\msctfime.ime
ModLoad: 605d0000 605d9000 C:\WINDOWS\system32\mslbui.dll

I get bonus points for using the portable @$retreg over @eax. I lose some for not figuring out how the heck to get .printf to write a newline without a trailing .echo (both \n and \r\n don’t seem to do the trick here). Of course if what you have in mind is to actually break at the breakpoint, do not append “gc” (go from conditional breakpoint) at the end of the branch of interest.


4 thoughts on “Breaking when a function returns a specific value without depending on its call site

  1. You need to double escape your string (\\n should work) for the .printf command in that case.

    Note: Beware saved breakpoints (bu) and double escaping, as when you save and reload the workspace, the double escaping gets broken and your breakpoints start failing in bizzare ways. Ugh.

  2. Well, it’s not that different from C string literals conceptually. Just think of it like you were writing a C program that outputted another C program that called printf with \n :)

Leave a Reply

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

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

Google+ photo

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

Twitter picture

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

Facebook photo

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


Connecting to %s