Debugging exceptions in managed code using Windbg

By default Windbg will break for access violations (or null reference exceptions as they're called in managed code). To get Windbg to break for managed exceptions use the sxe command.

0:004> sxe clr
0:004> g

A little while later our program generates a CLR exception and pops into the debugger.

(17c.1194): CLR exception - code e0434f4d (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0012eea0 ebx=0014d578 ecx=00000000 edx=00000025 esi=0012ef2c edi=e0434f4d
eip=77e55e02 esp=0012ee9c ebp=0012eef0 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
77e55e02 5e pop esi

This is a first chance exception so this may be expected and handled, as the message helpfully reminds you. Let's find out what caused this exception.

0:000> !PrintException
Exception object: 01289fb0
Exception type: System.ArgumentException
Message: Value does not fall within the expected range.
InnerException: <none>
StackTrace (generated):
StackTraceString: <none>
HResult: 80070057

We can also have a look at the managed stack trace to see where this exception happened.

0:000> !CLRStack
OS Thread Id: 0x1194 (0)
0012ef78 77e55e02 [HelperMethodFrame: 0012ef78]
0012f01c 00cc0795 WindbgDemo.Form1.CauseOtherException()
0012f024 00cc075d WindbgDemo.Form1.btnOtherException_Click(System.Object, System.EventArgs)
0012f02c 7b060a6b System.Windows.Forms.Control.OnClick(System.EventArgs)
0012f03c 7b105379 System.Windows.Forms.Button.OnClick(System.EventArgs)
0012f048 7b10547f System.Windows.Forms.Button.OnMouseUp(System.Windows.Forms.MouseEventArgs)
0012f06c 7b0d02d2 System.Windows.Forms.Control.WmMouseUp(System.Windows.Forms.Message ByRef, System.Windows.Forms.MouseButtons, Int32)
0012f0b8 7b072c74 System.Windows.Forms.Control.WndProc(System.Windows.Forms.Message ByRef)
0012f0bc 7b0815a6 [InlinedCallFrame: 0012f0bc]
0012f158 7b0814c3 System.Windows.Forms.Button.WndProc(System.Windows.Forms.Message ByRef)
0012f160 7b07a72d System.Windows.Forms.Control+ControlNativeWindow.OnMessage(System.Windows.Forms.Message ByRef)
0012f164 7b07a706 System.Windows.Forms.Control+ControlNativeWindow.WndProc(System.Windows.Forms.Message ByRef)
0012f178 7b07a515 System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr)
0012f324 0033216c [NDirectMethodFrameStandalone: 0012f324] System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG ByRef)
0012f334 7b084766 System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32, Int32, Int32)
0012f3d4 7b08432d System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)
0012f440 7b08416b System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)
0012f470 7b0c69fe System.Windows.Forms.Application.Run(System.Windows.Forms.Form)
0012f480 00cc0097 WindbgDemo.Program.Main()
0012f69c 79e88f63 [GCFrame: 0012f69c]

If we want to get a feel for what sorts of exceptions are generated by our program but not necessarily inspect each one we can tell Windbg to stop on exceptions, print out some information about the exception, and then continue running all without user intervention.

0:000> sxe -c "!pe;!clrstack;gc" clr