Unhandled Exceptions
In Windows programming, an unhandled exception terminates the process unless a debugger is attached or a structured exception handler (SEH) is present. This article explains how to detect, diagnose, and mitigate unhandled exceptions in native and managed code.
Table of Contents
- Overview
- Native (C/C++) Exceptions
- Managed (.NET) Exceptions
- Debugging Unhandled Exceptions
- Best Practices
Overview
When an exception propagates out of the top‑level thread entry point without being caught, Windows raises a EXCEPTION_UNHANDLED
event. The default behaviour is to display the Windows Error Reporting (WER) dialog and terminate the process.
Native (C/C++) Exceptions
Windows uses Structured Exception Handling (SEH) to manage low‑level exceptions such as access violations.
#include <windows.h>
#include <stdio.h>
int main()
{
__try
{
int *p = NULL;
*p = 42; // Access violation
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
printf("Caught an access violation!\\n");
}
return 0;
}
For C++ exceptions, use try
/catch
blocks or combine with SEH via __try/__except
.
Managed (.NET) Exceptions
In .NET, unhandled exceptions on any thread cause the runtime to invoke AppDomain.UnhandledException
. You can subscribe to this event to log or perform cleanup.
using System;
class Program
{
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += (s, e) =>
{
Console.WriteLine("Unhandled exception: " + ((Exception)e.ExceptionObject).Message);
};
throw new InvalidOperationException("Oops!");
}
}
Debugging Unhandled Exceptions
Use Visual Studio or WinDbg to capture a crash dump. Enable WER
local dump collection:
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpFolder /t REG_EXPAND_SZ /d "%LOCALAPPDATA%\\CrashDumps" /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpType /t REG_DWORD /d 2 /f
After a crash, open the .dmp
file in WinDbg and run !analyze -v
to view the exception stack.
Best Practices
- Wrap entry points (e.g.,
WinMain
,main
) in a top‑leveltry/catch
or__try/__except
block. - Log detailed information in
AppDomain.UnhandledException
for managed code. - Enable WER local dumps for production environments.
- Avoid catching exceptions you cannot handle; rethrow after logging.
- Use
SetUnhandledExceptionFilter
to provide a custom crash handler.