Skip to content

Windows WER backend for native crash reporting in C#/WinUI3 apps #1662

@BernhardMarconato

Description

@BernhardMarconato

Add a new backend to Sentry that implements a Windows Error Reporting out-of-process DLL registered using WerRegisterRuntimeExceptionModule to improve crash handling on Windows, mainly for C#/WinUI 3 apps.

Background

getsentry/sentry-dotnet#3244 tracked the user-facing issue that WinUI 3 / C# apps cannot capture fatal native crashes through sentry-dotnet alone. @jamescrosswell asked me to create a issue in this repo to continue tracking this issue.

Even when additionally including sentry-native in the C#/WinUI app with the Crashpad backend, this solution has multiple issues. The default Crashpad backend misses the native crashes that matter most in C# apps:

  • Access violation 0xC0000005: CoreCLR intercepts corrupted-state exceptions before SetUnhandledExceptionFilter
  • Stack overflow 0xC00000FD: Same CoreCLR interception
  • Fail fast exceptions: Process fast-exits before app-local handlers run (WinUI uses them a lot)
  • WinUI stowed exceptions 0xC000027B: Raised through the WinRT stowed-exception path, contain additional stowed call stacks that get lost

In addition, Crashpad's crashpad_wer.dll explicitly excludes 0xC0000005 and 0xC00000FD from its WER filter (correct for pure-native apps, wrong for C# apps where CoreCLR overrides Crashpad handling). Even when the exception is captured, Crashpad-produced minidumps do not reliably yield .NET frame names in Sentry (getsentry/symbolicator#1731). MSIX-packaged apps have additional registry-virtualization and DLL-identity problems that Crashpad does not address.

Proposed Solution: WER backend

A new wer backend using WerRegisterRuntimeExceptionModule.

At startup the backend stages the DSN, breadcrumbs, event seed, and attachment metadata to disk, then registers sentry_wer_module.dll with WER.

On crash Windows launches WerFault.exe, which loads the module out-of-process. The module reads the crashed process's staged context via ReadProcessMemory, writes a minidump with MiniDumpWriteDump, captures stowed-exception stack frames for 0xC000027B crashes, and uploads immediately via WinHTTP. If upload fails, the artifacts are uploaded on next startup.

This covers the full set of missing exceptions, produces dumps that include managed frames, works in MSIX packaged apps, and preserves stowed-exception information that Crashpad discards. The main use case are WinUI 3/C# apps that interop with native code, but theoretically this works for all native Windows apps.

More details: https://github.com/elgatosf/sentry-native/blob/feat/wer-backend/docs/windows-wer-backend.md

This approach also has some limitations (as described in the link above) due to the out-of-process nature, but solutions could be found.

Status

I have a working proof-of-concept on a fork: https://github.com/elgatosf/sentry-native/tree/feat/wer-backend.

It includes:

  • sentry_wer_module.dll — the out-of-process WER handler
  • sentry_backend_wer.cpp — the in-process backend entry point
  • CMake build integration, unit tests, integration tests, and WinUI 3 / console .NET example projects
  • Documentation notes in docs/windows-wer-backend.md

We will try to use this in our WinUI 3 apps going forward. To help improve the Sentry situation for Windows and especially WinUI 3 apps, which didn't see any development in the last years, I would like to contribute this as a PR. Feel free to let me know how to proceed

Metadata

Metadata

Assignees

No one assigned

    Labels

    No fields configured for issues without a type.

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions