Nested exception analysis is much simpler in managed code than in unmanaged. Exception object references the inner exception if any and so on:
Exception.InnerException
WinDbg does a good job traversing all nested exceptions when executing !analyze -v command. In the following example of a Windows forms application crash ObjectDisposedException (shown in red) was re-thrown as Exception object with “Critical error” message (shown in magenta) which was re-thrown several times as Exception object with “Critical program error” message (shown in blue) that finally resulted in the process termination request in the top level exception handler:
MANAGED_STACK:
(TransitionMU)
001374B0 0B313757 System!System.Diagnostics.Process.Kill()+0x37
001374E4 0B3129C7 Component!Foo.HandleUnhandledException(System.Exception)+0x137
001374F4 07C0A7D3 Component!Foo+FooBarProcessMenuCommand(System.String)+0x33
(TransitionUM)
(TransitionMU)
[...]
EXCEPTION_OBJECT: !pe 3398614
Exception object: 03398614
Exception type: System.Exception
Message: Critical program error
InnerException: System.Exception, use !PrintException 03398560 to see more StackTrace (generated):
SP IP Function
001371A8 07C0CDD8 Foo.BarUserInteraction.Process(System.String)
00137258 07C0CCA6 Foo.BarUserInteraction.ProcessUserInteraction(Sub, BarStepType)
00137268 07C0A9BA Foo.BarMenu.Process(CMD)
00137544 07C0A8D8 Foo.BarMenu.ProcessCMD(CMD)
0013756C 07C0A7BE Foo+FooBar.ProcessBarMenuCommand(System.String)
StackTraceString: <none>
HResult: 80131500
EXCEPTION_OBJECT: !pe 3398560
Exception object: 03398560
Exception type: System.Exception
Message: Critical program error
InnerException: System.Exception, use !PrintException 033984ac to see more StackTrace (generated):
SP IP Function
00137154 07C0D4CA Foo.BarThreads+ProcessOpenQuery.Execute()
00137218 07C0D3B3 Foo.BarMenu.ProcessQuery()
00137220 07C0CCF3 Foo.BarUserInteraction.Process(System.String)
StackTraceString: <none>
HResult: 80131500
EXCEPTION_OBJECT: !pe 33984ac
Exception object: 033984ac
Exception type: System.Exception
Message: Critical program error
InnerException: System.Exception, use !PrintException 033983ec to see more StackTrace (generated):
SP IP Function
0013704C 0A6149DD Foo.Bar.OpenQueryThreaded(Foo.BarParameter)
00137154 0A6140D0 Foo.BarThreads+ProcessParameter.Execute()
[…]
StackTraceString: <none>
HResult: 80131500
EXCEPTION_OBJECT: !pe 33983ec
Exception object: 033983ec
Exception type: System.Exception
Message: Critical program error
InnerException: System.Exception, use !PrintException 033982fc to see more StackTrace (generated):
SP IP Function
00137008 0ACA59F1 Foo.BarApplication.Refresh(Boolean, Boolean)
001370C4 0A6144E0 Foo.Bar.OpenQueryThreaded(Foo.BarParameter)
StackTraceString: <none>
HResult: 80131500
EXCEPTION_OBJECT: !pe 33982fc
Exception object: 033982fc
Exception type: System.Exception
Message: Critical program error
InnerException: System.Exception, use !PrintException 03398260 to see more StackTrace (generated):
SP IP Function
00136F3C 0AE24983 Foo.BarDisplay.ShowVariableScreen(Foo.variables.BarVariables)
00136FDC 0AE204F6 Foo.variables.BarVariables.ShowVariableScreen()
00137070 0ACAFE1D Foo.BarApplication.ShowVariableScreen(Boolean)
00137080 0ACA5977 Foo.BarApplication.Refresh(Boolean, Boolean)
StackTraceString: <none>
HResult: 80131500
EXCEPTION_OBJECT: !pe 3398260
Exception object: 03398260
Exception type: System.Exception
Message: Critical error
InnerException: System.ObjectDisposedException, use !PrintException 03397db8 to see more StackTrace (generated):
SP IP Function
00136FB4 0AE24905 Foo.BarDisplay.ShowVariableScreen(Foo.variables.BarVariables)
StackTraceString: <none>
HResult: 80131500
EXCEPTION_OBJECT: !pe 3397db8
Exception object: 03397db8
Exception type: System.ObjectDisposedException
Message: Cannot access a disposed object.
InnerException: <none>
StackTrace (generated):
SP IP Function
00136258 06D36158 System.Windows.Forms.Control.CreateHandle()
001362B8 06D38F96 System.Windows.Forms.Control.get_Handle()
001362C4 0B0C8C68 System.Windows.Forms.Control.PointToScreen(System.Drawing.Point)
001362F0 0B0CECB4 System.Windows.Forms.Button.OnMouseUp(System.Windows.Forms.MouseEventArgs)
00136314 0B0C8BB7 System.Windows.Forms.Control.WmMouseUp(System.Windows.Forms.Message ByRef, System.Windows.Forms.MouseButtons, Int32)
00136384 06D385A0 System.Windows.Forms.Control.WndProc(System.Windows.Forms.Message ByRef)
001363E8 0A69C73E System.Windows.Forms.ButtonBase.WndProc(System.Windows.Forms.Message ByRef)
00136424 0A69C54D System.Windows.Forms.Button.WndProc(System.Windows.Forms.Message ByRef)
0013642C 06D37FAD System.Windows.Forms.Control+ControlNativeWindow.OnMessage(System.Windows.Forms.Message ByRef)
00136430 06D37F87 System.Windows.Forms.Control+ControlNativeWindow.WndProc(System.Windows.Forms.Message ByRef)
00136440 06D37D9F System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr)
StackTraceString: <none>
HResult: 80131622
[…]
EXCEPTION_MESSAGE: Cannot access a disposed object.
STACK_TEXT:
00137448 7c827c1b ntdll!KiFastSystemCallRet
0013744c 77e4201b ntdll!NtTerminateProcess+0xc
0013745c 05d78202 kernel32!TerminateProcess+0x20
[...]
- Dmitry Vostokov @ DumpAnalysis.org -