1

In short, MSDN describes exception dispatching for user mode application like this:

  1. the debugger gets notified of the first chance exception (if attached)
  2. an exception handler aka. try/catch is invoked (if available)
  3. the debugger gets notified of the second chance exception (if attached)
  4. the system cares about the unhandled exception (typically: terminate the process)

This sequence does not consider the presence of an unhandled exception handler. How does exception dispatching change when an unhandled exception handler is present?

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
  • I believe the [tag:winapi] tag is misleading, since you are talking about exception handling in the CLR only. Internally, Windows uses [Structured Exception Handling](https://msdn.microsoft.com/en-us/library/windows/desktop/ms680657.aspx). While CLR exceptions are implemented in terms of SEH exceptions, SEH exceptions and CLR exceptions expose different semantics. Then again, your first link points to SEH, and I'm not sure, which exception handling you are referring to (your answer contains C# code). – IInspectable Dec 01 '15 at 22:16
  • @IInspectable: thanks for the insight. I didn't consider the behavior would be language specific. Ok, we have SEH, CLR uses SEH internally. I'm not sure what the semantics would change to that. Let's get practical: do you say a C++ answer would differ? – Thomas Weller Dec 01 '15 at 22:23
  • The key difference is in the first sentence of [Exception Dispatching](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679327.aspx): *"When a hardware or software exception occurs [...]"*. Exception handling in C++ (and probably C# as well) is strictly synchronous. A `try/catch` handler will only catch exceptions that are thrown. It will not catch hardware exceptions. Details are outlined under [Exception Handling Differences](https://msdn.microsoft.com/en-us/library/de5awhsw.aspx). An answer to this question should probably be in C, that uses SEH exception filters. – IInspectable Dec 04 '15 at 00:02

1 Answers1

1

The unhandled exception handlers insert at position 3. The sequence is:

  1. the debugger gets notified of the first chance exception (if attached)
  2. an exception handler aka. try/catch is invoked (if available)
  3. the unhandled exception handlers (note the plural) are called (if available)
  4. the debugger gets notified of the second chance exception (if attached)
  5. the system cares about the unhandled exception (typically: terminate the process)

The following C# program demonstrates it. Depending on the .NET version, you'll a message of another unhandled exception handler, which is the .NET framework printing the exception and the call stack.

using System;
namespace UnhandledException
{
    static class Program
    {
        static void Main()
        {
            Console.WriteLine("Please attach the debugger now and press Enter.");
            Console.ReadLine();            
            AppDomain.CurrentDomain.UnhandledException += (sender, e) => Unhandled1();
            AppDomain.CurrentDomain.UnhandledException += (sender, e) => Unhandled2();
            try
            {
                Console.WriteLine("Throwing now.");
                // Will cause a first chance, because in try/catch
                throw new Exception("Any exception will do");
            }
            catch (Exception)
            {
                // Will cause first chance and second chance, because in NOT try/catch
                Console.WriteLine("In catch block.");
                throw;
            }
        }

        static void Unhandled1() => Console.WriteLine("In unhandled exception handler 1");
        static void Unhandled2() => Console.WriteLine("In unhandled exception handler 2");
    }
}

Commands required in the debugger (WinDbg):

.symfix
.reload
sxe clr
g; *** for the breakpoint due to attaching the debugger
g; *** first chance in try/catch
g; *** first chance outside try/catch
g; *** second chance
Thomas Weller
  • 55,411
  • 20
  • 125
  • 222