WinDbg Kata 001: Division By Zero on App Startup
The first Kata is about a division by zero exception that happens on startup, specifically a .net 4.5 console application (that’s explicitly set to x64 instead of AnyCPU and debugged with a 64-Bit WinDbg just so that I have a consistent environment) whose main method is this:
static void Main(string[] args) { // To make sure the Compiler doesn't catch or optimize this int x = 10 - 10; // This blows up with a Division By Zero exception int i = 2000 / x; Console.WriteLine("The result of 2000 / {0} is {1}.", x, i); }
Running this application results in an immediate crash, with no chance to attach a debugger. We start out by opening WinDbg and File > Open Executable. This results in WinDbg starting the app and immediately breaking into the debugger.
CommandLine: F:\WinDbgKatas\001-DivByZeroOnStartup\001-DivByZeroOnStartup\bin\Release\001-DivByZeroOnStartup.exe Symbol search path is: SRV*C:\Users\mstum\Desktop\MSDN\DEBUG\Symbols*http://msdl.microsoft.com/download/symbols Executable search path is: ModLoad: 00000001`3fb50000 00000001`3fb56000 001-DivByZeroOnStartup.exe ModLoad: 00000000`77290000 00000000`77439000 ntdll.dll ModLoad: 000007fe`f86f0000 000007fe`f875f000 C:\windows\SYSTEM32\MSCOREE.DLL ModLoad: 00000000`77170000 00000000`7728f000 C:\windows\system32\KERNEL32.dll ModLoad: 000007fe`fd3d0000 000007fe`fd43c000 C:\windows\system32\KERNELBASE.dll (30c4.337c): Break instruction exception - code 80000003 (first chance) ntdll!LdrpDoDebuggerBreak+0x30: 00000000`7733cb60 cc int 3
Debug > Go (or the g command line) makes it run and crash.
0:000> g ModLoad: 000007fe`ff4c0000 000007fe`ff59b000 C:\windows\system32\ADVAPI32.dll ModLoad: 000007fe`fe470000 000007fe`fe50f000 C:\windows\system32\msvcrt.dll ModLoad: 000007fe`fd910000 000007fe`fd92f000 C:\windows\SYSTEM32\sechost.dll ModLoad: 000007fe`fdf40000 000007fe`fe06d000 C:\windows\system32\RPCRT4.dll ModLoad: 000007fe`f8650000 000007fe`f86e9000 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscoreei.dll ModLoad: 000007fe`fda80000 000007fe`fdaf1000 C:\windows\system32\SHLWAPI.dll ModLoad: 000007fe`fd930000 000007fe`fd997000 C:\windows\system32\GDI32.dll ModLoad: 00000000`77070000 00000000`7716a000 C:\windows\system32\USER32.dll ModLoad: 000007fe`fdd50000 000007fe`fdd5e000 C:\windows\system32\LPK.dll ModLoad: 000007fe`fd490000 000007fe`fd559000 C:\windows\system32\USP10.dll ModLoad: 000007fe`fd610000 000007fe`fd63e000 C:\windows\system32\IMM32.DLL ModLoad: 000007fe`fdba0000 000007fe`fdca9000 C:\windows\system32\MSCTF.dll ModLoad: 000007fe`f7c50000 000007fe`f85ae000 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll ModLoad: 000007fe`f7b70000 000007fe`f7c42000 C:\windows\system32\MSVCR110_CLR0400.dll (30c4.337c): Unknown exception - code 04242420 (first chance) ModLoad: 000007fe`f65f0000 000007fe`f7b6d000 C:\windows\assembly\NativeImages_v4.0.30319_64\mscorlib\1b61dcfd88eae971a10423d914e1014a\mscorlib.ni.dll ModLoad: 000007fe`ff2b0000 000007fe`ff4b3000 C:\windows\system32\ole32.dll ModLoad: 000007fe`fcef0000 000007fe`fceff000 C:\windows\system32\CRYPTBASE.dll ModLoad: 000007fe`f64c0000 000007fe`f65ee000 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clrjit.dll ModLoad: 000007fe`fd9a0000 000007fe`fda77000 C:\windows\system32\OLEAUT32.dll (30c4.337c): Integer divide-by-zero - code c0000094 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled.
From here, we can load the .net debugging extensions through .loadby sos clr
(remember, in .net 4.0 it's clr instead of mscorwks) Now, this is a first chance exception and as the text says, it’s reported before any exception handling. Specifically, it’s not on the managed stack yet, so !pe
won’t find it:
0:000> .loadby sos clr 0:000> !pe There is no current managed exception on this thread
At this point, we can look at the !ClrStack
to get an idea where we crashed.
0:000> !ClrStack OS Thread Id: 0x337c (0) Child SP IP Call Site 000000000049ea60 000007fe9860009f *** WARNING: Unable to verify checksum for 001-DivByZeroOnStartup.exe WinDbgKata.DivByZeroOnStartup.Program.Main(System.String[]) [f:\WinDbgKatas\001-DivByZeroOnStartup\001-DivByZeroOnStartup\Program.cs @ 12] 000000000049ed90 000007fef7c9f713 [GCFrame: 000000000049ed90]
Entering g again will give us a second chance, this time the Exception is on the managed stack.
0:000> g ModLoad: 000007fe`fc140000 000007fe`fc14c000 C:\windows\system32\VERSION.dll ModLoad: 000007fe`f3f70000 000007fe`f4079000 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\diasymreader.dll (30c4.337c): Integer divide-by-zero - code c0000094 (!!! second chance !!!) KERNELBASE!RaiseException+0x39: 000007fe`fd3dbccd 4881c4c8000000 add rsp,0C8h 0:000> !pe Exception object: 0000000002572ed8 Exception type: System.DivideByZeroException Message: Attempted to divide by zero. InnerException: <none> StackTrace (generated): SP IP Function 000000000049EA60 000007FE9860009F 001_DivByZeroOnStartup!WinDbgKata.DivByZeroOnStartup.Program.Main(System.String[])+0xf StackTraceString: <none> HResult: 80020012
Depending on the exact exception we can now dig further, since it's on the managed stack we can !do
it. This won't give us much more information in the Division by Zero case, but if there's an InnerException
0:000> !do 0000000002572ed8 Name: System.DivideByZeroException MethodTable: 000007fef6c6f020 EEClass: 000007fef675f068 Size: 160(0xa0) bytes File: C:\windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll Fields: MT Field Offset Type VT Attr Value Name 000007fef6c8aee0 4000002 8 System.String 0 instance 000000000257ae30 _className 000007fef6c89460 4000003 10 ...ection.MethodBase 0 instance 0000000000000000 _exceptionMethod 000007fef6c8aee0 4000004 18 System.String 0 instance 0000000000000000 _exceptionMethodString 000007fef6c8aee0 4000005 20 System.String 0 instance 0000000002578fd0 _message 000007fef6c88ee8 4000006 28 ...tions.IDictionary 0 instance 0000000000000000 _data 000007fef6c8b110 4000007 30 System.Exception 0 instance 0000000000000000 _innerException 000007fef6c8aee0 4000008 38 System.String 0 instance 0000000000000000 _helpURL 000007fef6c8b4c0 4000009 40 System.Object 0 instance 0000000002579100 _stackTrace 000007fef6c8b4c0 400000a 48 System.Object 0 instance 0000000002579148 _watsonBuckets 000007fef6c8aee0 400000b 50 System.String 0 instance 0000000000000000 _stackTraceString 000007fef6c8aee0 400000c 58 System.String 0 instance 0000000000000000 _remoteStackTraceString 000007fef6c8dc90 400000d 88 System.Int32 1 instance 0 _remoteStackIndex 000007fef6c8b4c0 400000e 60 System.Object 0 instance 0000000000000000 _dynamicMethods 000007fef6c8dc90 400000f 8c System.Int32 1 instance -2147352558 _HResult 000007fef6c8aee0 4000010 68 System.String 0 instance 0000000000000000 _source 000007fef6c8ed00 4000011 78 System.IntPtr 1 instance 0 _xptrs 000007fef6c8dc90 4000012 90 System.Int32 1 instance -532462766 _xcode 000007fef6c77828 4000013 80 System.UIntPtr 1 instance 0 _ipForWatsonBuckets 000007fef6cf2960 4000014 70 ...ializationManager 0 instance 00000000025790c8 _safeSerializationManager 000007fef6c8b4c0 4000001 0 System.Object 0 shared static s_EDILock >> Domain:Value 00000000005c4a50:NotInit <<