g_dwLastErrorToBreakOn: Watching Errors on VS Revisited

Raymond Chen posted about SetLastError recently, and an interesting discussion ensued. One comment in particular caught my eye:

The easiest way to catch a specific last error value in debugger is to set ntdll!g_dwLastErrorToBreakOn to that value.

A good while back I needed to break when such a LastError is set, and dug up all sorts of hacks to do so – breaking at SetLastError, setting data breakpoint on the thread-env-block-error, and the like. Beyond being cumbersome and plain ugly such breakpoint tricks can be very slow, and give a lot of false positives.

Seems the Win32 folks had similar needs and I was glad to discover they formed a better (undocumented, but still) solution. The authoritative source seems to be a 2007 post from Microsoft’s Daniel Pearson:

..Hiding inside of kernel32’s address space is a global variable called g_dwLastErrorToBreakOn. It turns out that SetLastError checks the value of this variable and if it’s non-zero, calls DbgBreakPoint if the two [values] match.

It’s a zero-overhead trick, and is very easy to do in Visual Studio: make sure kernel32.dll symbols are loaded, then type in a watch window –

(int*){,,kernel32.dll}_g_dwLastErrorToBreakOn

– and edit the referenced int:

image

Pearson notes two changes introduced in Vista:

(1) Up until XP, only Win32 API implemented in KERNEL32.DLL actually used SetLastError (and so tested g_dwLastErrorToBreakOn) – other dll’s used to set the error value via RtlSetLastWin32Error. Since Vista all Win32 API which set an error do so with SetLastError, so the g_dwLastErrorToBreakOn is much more reliable.

(2) Since Vista, g_dwLastErrorToBreakOn moved to NTDLL.DLL, so the VS usage should be changed to –

(int*){,,ntdll.dll}_g_dwLastErrorToBreakOn

It’s interesting to note that ntdll.dll does contain a separate instance of g_dwLastErrortToBreakOn also on XP machines:

image

But I verified that this value is never read, on calls into both kernel32 and ntdll.

Advertisement
This entry was posted in Debugging, Win32. Bookmark the permalink.

3 Responses to g_dwLastErrorToBreakOn: Watching Errors on VS Revisited

  1. Niv Fisher says:

    Great post – will come in handy!

    BTW, what is the default value? does it ignore (ie. not break) when zero?

  2. Hvergelmir says:

    The post you quote is long gone, but can still be found via the Internet Archive: https://web.archive.org/web/20131031135425/http://blogs.msdn.com/b/danpear/archive/2007/04/06/2033100.aspx

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