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  <<