In short, MSDN describes exception dispatching for user mode application like this:
try/catch
is invoked (if available)This sequence does not consider the presence of an unhandled exception handler. How does exception dispatching change when an unhandled exception handler is present?
The unhandled exception handlers insert at position 3. The sequence is:
try/catch
is invoked (if available)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