.NET Debugging Demos Lab 5: Crash - Walkthrough

3 minute read

Since I already posted a challenge for this lab earlier, I didn’t want to wait too long with publishing the walkthrough

Previous labs and setup instructions

If you are new to the debugging labs, here you can find information on how to set up the labs as well as links to the previous labs in the series.

Reproduce the issue

  1. Start the application and browse to the Company Information page
  2. Type some message and click the Send button

    • What do you see in the browser? or what is the experience?

      It seems to hang in the browser - in the task manager Windows Error Reporting shows up and when that dies Edge shows up with a “Hmmm… can’t reach this page”.

Explore the event logs

  1. Open the Windows System and Application event logs (event viewer)

    • What events do you notice relating to the crash? (Note: you may see different events on different operating systems)

        Error       Application Error   1000
      
        Faulting application name: iisexpress.exe, version: 10.0.19041.1, time stamp: 0x0cefd54e
        Faulting module name: coreclr.dll, version: 4.700.20.56602, time stamp: 0x5fb2b303
        Exception code: 0xc00000fd
        Fault offset: 0x000000000004a4c7
        Faulting process id: 0x3768
        Faulting application start time: 0x01d6fdf5cded9a7d
        Faulting application path: C:\Program Files\IIS Express\iisexpress.exe
        Faulting module path: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.11\coreclr.dll
        Report Id: 9dbee3ee-b0b5-4026-86e1-6e781325f757
        Faulting package full name:
        Faulting package-relative application ID:
      
    • What does Exception code 0xc00000fd mean?

      The code 0xc00000fd means STATUS_STACK_OVERFLOW

    • Based on the event logs, what caused the crash?

      A StackOverflowException in the application - so probably an infinite recursion

Examine the threads

Note: In a dump file the active thread is the thread that caused the debugger to dump the process, i.e. a process exit exception or other exception.

  1. Run kb 200 and !clrstack to see what the active thread is doing

     0:040> k 20
     # Child-SP          RetAddr               Call Site
     00 (Inline Function) --------`--------     coreclr!IJitManager::IsFunclet+0xa
     01 (Inline Function) --------`--------     coreclr!EECodeInfo::IsFunclet+0xe
     02 0000008f`085d3fe0 00007ffb`bb35c87b     coreclr!CrawlFrame::IsFunclet+0x28
     03 0000008f`085d4010 00007ffb`bb359ee5     coreclr!ExceptionTracker::ProcessManagedCallFrame+0xb3
     04 0000008f`085d43c0 00007ffb`bb3594e2     coreclr!ExceptionTracker::ProcessOSExceptionNotification+0x2e9
     05 0000008f`085d5390 00007ffc`8037138f     coreclr!ProcessCLRException+0x382
     06 0000008f`085d5590 00007ffc`802f1d19     ntdll!RtlpExecuteHandlerForUnwind+0xf
     07 0000008f`085d55c0 00007ffb`bb357a90     ntdll!RtlUnwindEx+0x339
     08 0000008f`085d5ce0 00007ffb`bb359618     coreclr!ClrUnwindEx+0x40
     09 0000008f`085d6200 00007ffc`8037130f     coreclr!ProcessCLRException+0x4b8
     0a 0000008f`085d6400 00007ffc`8031b5e4     ntdll!RtlpExecuteHandlerForException+0xf
     0b 0000008f`085d6430 00007ffc`8036fe3e     ntdll!RtlDispatchException+0x244
     0c 0000008f`085d6b40 00007ffc`7e08d759     ntdll!KiUserExceptionDispatch+0x2e
     0d 0000008f`085d72c0 00007ffb`bb41bd68     KERNELBASE!RaiseException+0x69
     0e 0000008f`085d73a0 00007ffb`bb41b4d3     coreclr!RaiseTheExceptionInternalOnly+0x28c
     0f 0000008f`085d74c0 00007ffb`5c3242ba     coreclr!IL_Throw+0x113
     10 0000008f`085d7660 00007ffb`5c326b28     0x00007ffb`5c3242ba
    
     0:040> !clrstack
     OS Thread Id: 0x9d10 (40)
             Child SP               IP Call Site
     0000008F085D7568 00007ffbbb35be94 [HelperMethodFrame: 0000008f085d7568]
     0000008F085D7660 00007ffb5c3242ba System.IO.FileStream.ValidateFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle)
     0000008F085D76B0 00007ffb5c326b28 System.IO.FileStream.CreateFileOpenHandle(System.IO.FileMode, System.IO.FileShare, System.IO.FileOptions)
     0000008F085D7760 00007ffb5c3258f6 System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare, Int32, System.IO.FileOptions)
     0000008F085D77D0 00007ffb5c3275c9 System.IO.StreamWriter.ValidateArgsAndOpenPath(System.String, Boolean, System.Text.Encoding, Int32)
     0000008F085D7830 00007ffb5c327509 System.IO.StreamWriter..ctor(System.String)
     0000008F085D7870 00007ffb5c3229ce BuggyBits.Models.Utility.WriteToLog(System.String, System.String)
     0000008F085D7900 00007ffb5c32294f BuggyBits.Models.ErrorHandler.LogException(System.Exception)
     0000008F085D7940 00007ffb5c322af0 BuggyBits.Models.Utility.WriteToLog(System.String, System.String)
     0000008F085D9C68 00007ffbbb41cacf [HelperMethodFrame: 0000008f085d9c68]
     0000008F085D9D60 00007ffb5c3242ba System.IO.FileStream.ValidateFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle)
     0000008F085D9DB0 00007ffb5c326b28 System.IO.FileStream.CreateFileOpenHandle(System.IO.FileMode, System.IO.FileShare, System.IO.FileOptions)
     0000008F085D9E60 00007ffb5c3258f6 System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare, Int32, System.IO.FileOptions)
     0000008F085D9ED0 00007ffb5c3275c9 System.IO.StreamWriter.ValidateArgsAndOpenPath(System.String, Boolean, System.Text.Encoding, Int32)
     0000008F085D9F30 00007ffb5c327509 System.IO.StreamWriter..ctor(System.String)
     0000008F085D9F70 00007ffb5c3229ce BuggyBits.Models.Utility.WriteToLog(System.String, System.String)
     0000008F085DA000 00007ffb5c32294f BuggyBits.Models.ErrorHandler.LogException(System.Exception)
     0000008F085DA040 00007ffb5c322af0 BuggyBits.Models.Utility.WriteToLog(System.String, System.String)
     0000008F085DC368 00007ffbbb41cacf [HelperMethodFrame: 0000008f085dc368]
     0000008F085DC460 00007ffb5c3242ba System.IO.FileStream.ValidateFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle)
     0000008F085DC4B0 00007ffb5c326b28 System.IO.FileStream.CreateFileOpenHandle(System.IO.FileMode, System.IO.FileShare, System.IO.FileOptions)
     ...
     ...
     ...
     0000008F0961B170 00007ffbbad9ef65 System.IO.FileStream.CreateFileOpenHandle(System.IO.FileMode, System.IO.FileShare, System.IO.FileOptions)
     0000008F0961B220 00007ffbbad9eb8e System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare, Int32, System.IO.FileOptions)
     0000008F0961B290 00007ffbbadb13be System.IO.StreamWriter.ValidateArgsAndOpenPath(System.String, Boolean, System.Text.Encoding, Int32)
     0000008F0961B2F0 00007ffbbadb131e System.IO.StreamWriter..ctor(System.String)
     0000008F0961B340 00007ffb5c3229ce BuggyBits.Models.Utility.WriteToLog(System.String, System.String)
     0000008F0961B3D0 00007ffb5c32294f BuggyBits.Models.ErrorHandler.LogException(System.Exception)
     0000008F0961B410 00007ffb5c32189b BuggyBits.Models.BuggyMail.SendEmail(System.String, System.String)
     0000008F0961D738 00007ffbbb41cacf [HelperMethodFrame: 0000008f0961d738]
     0000008F0961D830 00007ffb5c32196f BuggyBits.Models.BuggyMail.IsValidEmailAddress(System.String)
     0000008F0961D880 00007ffb5c321854 BuggyBits.Models.BuggyMail.SendEmail(System.String, System.String)
     0000008F0961D8E0 00007ffb5c32171d BuggyBits.Controllers.CompanyInformationController.Contact(BuggyBits.Models.ContactViewModel)
     ...
    
    • Can you tell what the issue is from here?

      From !clrstack it appears that we are processing CompanyInformationController.Contact and which calls into BuggyMail.SendEmail. From there we go into some type of recursion between ErrorHandler.LogException(System.Exception) and Utility.WriteToLog(System.String, System.String), and eventually we run out of stack space and throw the StackOverflowException that kills the process.

      To resolve the issue we need to figure out a way to stop the recursive loop between LogException and WriteToLog. You may be tempted to believe that it is the coreclr!IJitManager::IsFunclet method that cause the stack overflow but in reality thats just the straw that broke the camels back.

      Dumping out the last exception shows that we throw an exception in the WriteToLog function, and catch it with the ErrorHandler causing this recursion

        0:040> !pe
        Exception object: 000001c516984e10
        Exception type:   System.UnauthorizedAccessException
        Message:          Access to the path 'c:\log.txt' is denied.
        InnerException:   <none>
        StackTrace (generated):
            SP               IP               Function
            0000008F085D7660 00007FFB5C3242BA System_Private_CoreLib!System.IO.FileStream.ValidateFileHandle(Microsoft.Win32.SafeHandles.SafeFileHandle)+0x9a
            0000008F085D76B0 00007FFB5C326B28 System_Private_CoreLib!System.IO.FileStream.CreateFileOpenHandle(System.IO.FileMode, System.IO.FileShare, System.IO.FileOptions)+0xa8
            0000008F085D7760 00007FFB5C3258F6 System_Private_CoreLib!System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare, Int32, System.IO.FileOptions)+0x176
            0000008F085D77D0 00007FFB5C3275C9 System_Private_CoreLib!System.IO.StreamWriter.ValidateArgsAndOpenPath(System.String, Boolean, System.Text.Encoding, Int32)+0x79
            0000008F085D7830 00007FFB5C327509 System_Private_CoreLib!System.IO.StreamWriter..ctor(System.String)+0x29
            0000008F085D7870 00007FFB5C3229CE BuggyBits!BuggyBits.Models.Utility.WriteToLog(System.String, System.String)+0x5e
      
        StackTraceString: <none>
        HResult: 80070005
        There are nested exceptions on this thread. Run with -nested for details
      
    • Fix the problem

Have fun,

Tess