Skip to content

Implement ExceptionHandling.SetFatalErrorHandler#129543

Draft
AaronRobinsonMSFT wants to merge 7 commits into
dotnet:mainfrom
AaronRobinsonMSFT:set-fatal-error-handler
Draft

Implement ExceptionHandling.SetFatalErrorHandler#129543
AaronRobinsonMSFT wants to merge 7 commits into
dotnet:mainfrom
AaronRobinsonMSFT:set-fatal-error-handler

Conversation

@AaronRobinsonMSFT

@AaronRobinsonMSFT AaronRobinsonMSFT commented Jun 17, 2026

Copy link
Copy Markdown
Member

Implements the ExceptionHandling.SetFatalErrorHandler API (#101560) for both NativeAOT and CoreCLR. Mono throws PlatformNotSupportedException.

Changes

Managed API (ExceptionHandling.cs)

  • Enable SetFatalErrorHandler and s_fatalErrorHandler for CoreCLR (Mono still throws PNSE)

NativeAOT (RuntimeExceptionHelpers.cs)

  • Invoke handler from FailFast after crash info is written to stderr
  • Capture crash log alongside stderr writes in a pre-allocated 8KB buffer
  • pfnGetFatalErrorLog implemented via [UnmanagedCallersOnly] callback
  • SkipDefaultHandler exits via _Exit/ExitProcess without crash dump

CoreCLR (eepolicy.cpp)

  • Read s_fatalErrorHandler from managed static via CoreLibBinder
  • Invoke handler after LogFatalError in both HandleFatalError and HandleFatalStackOverflow
  • Crash log captured by tee-ing PrintToStdErrA into a static buffer
  • SkipDefaultHandler calls _exit() to bypass crash dump

Public native header (src/native/public/FatalErrorHandling.h)

  • Defines FatalErrorHandlerResult enum, FatalErrorInfo struct, callback typedefs

Tests (src/tests/baseservices/exceptions/FatalErrorHandler/)

  • Subprocess-based tests validating: SkipHandler, RunHandler, LogHandler, SetNull, SetTwice
  • Works on both CoreCLR and NativeAOT

Fixes #101560

AaronRobinsonMSFT and others added 2 commits June 17, 2026 15:05
Implement the ExceptionHandling.SetFatalErrorHandler API for NativeAOT.
The handler is invoked from RuntimeExceptionHelpers.FailFast before the
runtime performs its default crash handling (crash dump + abort).

- Add src/native/public/FatalErrorHandling.h defining the native
  FatalErrorInfo struct and FatalErrorHandlerResult enum
- Wire RegisterFatalErrorHandler as a no-op for NativeAOT (handler
  pointer stored in managed s_fatalErrorHandler field)
- Add crash log capture in FailFast alongside existing stderr output
- Implement pfnGetFatalErrorLog callback via UnmanagedCallersOnly
- SkipDefaultHandler exits via _Exit/ExitProcess instead of crash dump
- Consolidate ExceptionHandling partials: MONO||CORECLR throws PNSE
  inline, eliminating per-runtime partial files
- Add subprocess-based smoke tests validating handler invocation,
  SkipDefaultHandler/RunDefaultHandler, pfnGetFatalErrorLog callback,
  and API contract (null/double-set)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Wire up the user-registered fatal error handler in the CoreCLR runtime.
Read the managed ExceptionHandling.s_fatalErrorHandler static field via
CoreLibBinder and invoke the handler after LogFatalError completes in
both HandleFatalError and HandleFatalStackOverflow. If the handler
returns SkipDefaultHandler, exit without crash dump.

- Add ExceptionHandling class/field bindings to corelib.h
- Enable s_fatalErrorHandler field and SetFatalErrorHandler for CoreCLR
- Add crash log capture in PrintToStdErrA for pfnGetFatalErrorLog
- Include public/FatalErrorHandling.h for shared type definitions
- Fix test subprocess launch for CoreCLR (pass DLL path to corerun)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 17, 2026 22:24
@github-actions github-actions Bot added the area-ExceptionHandling-coreclr only use for closed issues label Jun 17, 2026
@AaronRobinsonMSFT AaronRobinsonMSFT changed the title Implement ExceptionHandling.SetFatalErrorHandler Implement ExceptionHandling.SetFatalErrorHandler Jun 17, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces the public System.Runtime.ExceptionServices.ExceptionHandling.SetFatalErrorHandler API and wires it up so CoreCLR and NativeAOT invoke a user-provided unmanaged callback during fatal-error paths, with a mechanism to retrieve the fatal-error log text.

Changes:

  • Adds ExceptionHandling.SetFatalErrorHandler(delegate* unmanaged<int, void*, int>) to the public surface and implements registration in System.Private.CoreLib.
  • Implements fatal-error handler invocation + crash-log capture in both CoreCLR (VM) and NativeAOT fail-fast paths.
  • Adds a new native public header (FatalErrorHandling.h) and a new subprocess-based test covering handler behaviors.
Show a summary per file
File Description
src/tests/baseservices/exceptions/FatalErrorHandler/FatalErrorHandlerTest.csproj Adds new standalone test project for fatal error handler scenarios.
src/tests/baseservices/exceptions/FatalErrorHandler/FatalErrorHandlerTest.cs Subprocess-based validation of handler invocation, skip/run default behavior, and log retrieval.
src/native/public/FatalErrorHandling.h Defines native ABI structs/enums/callback types for fatal error handling and log retrieval.
src/libraries/System.Runtime/ref/System.Runtime.cs Adds the new public ref-assembly API for SetFatalErrorHandler.
src/libraries/System.Private.CoreLib/src/System/Runtime/ExceptionServices/ExceptionHandling.cs Implements handler registration and stores function pointer for runtimes to read.
src/libraries/System.Private.CoreLib/src/Resources/Strings.resx Adds resource string for duplicate fatal handler registration.
src/coreclr/vm/util.hpp Declares crash-log capture helpers used by fatal-error handler plumbing.
src/coreclr/vm/util.cpp Implements stderr “tee” into a fixed crash-log buffer.
src/coreclr/vm/eepolicy.cpp Invokes the fatal handler after logging fatal errors / stack overflow and provides log callback.
src/coreclr/vm/corelib.h Adds CoreLibBinder field binding for ExceptionHandling.s_fatalErrorHandler.
src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeExceptionHelpers.cs Captures crash output into a buffer and invokes the fatal handler before default crash processing.

Copilot's findings

  • Files reviewed: 11/11 changed files
  • Comments generated: 5

Comment thread src/coreclr/vm/eepolicy.cpp Outdated
Comment thread src/tests/baseservices/exceptions/FatalErrorHandler/FatalErrorHandlerTest.cs Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 17, 2026 22:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 11/11 changed files
  • Comments generated: 6

Comment thread src/coreclr/vm/util.cpp
Comment thread src/coreclr/vm/eepolicy.cpp
Comment thread src/tests/baseservices/exceptions/FatalErrorHandler/FatalErrorHandlerTest.cs Outdated
Comment thread src/libraries/System.Runtime/ref/System.Runtime.cs
AaronRobinsonMSFT and others added 2 commits June 17, 2026 15:58
The SkipDefaultHandler path should terminate immediately without running
atexit handlers, which can deadlock in a corrupted process. Replace the
call to exit() (via Interop.Sys.Exit) with _exit() (via a new
Interop.Sys._Exit P/Invoke) in the NativeAOT FailFast path, matching
CoreCLR's native _exit() semantics.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread src/tests/baseservices/exceptions/FatalErrorHandler/FatalErrorHandlerTest.cs Outdated
Comment thread src/tests/baseservices/exceptions/FatalErrorHandler/FatalErrorHandlerTest.cs Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 17, 2026 23:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 17/17 changed files
  • Comments generated: 4

Comment thread src/coreclr/vm/eepolicy.cpp
Comment thread src/native/libs/System.Native/pal_threading.c
Comment thread src/native/libs/System.Native/pal_threading_wasi.c
- Use C99 _Exit() instead of _exit() to avoid unistd.h dependency
- Add COR_E_FAILFAST to IsCrashExitCode for Windows CoreCLR
- Suppress unused parameter warning in GetFatalErrorLogCallback

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-ExceptionHandling-coreclr only use for closed issues

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

[API Proposal]: Overriding the default behavior in case of unhandled exceptions and fatal errors.

3 participants