From 9a47b017a92ae94872166d6bdc29f649ca24a83c Mon Sep 17 00:00:00 2001 From: GittyHarsha Date: Wed, 13 May 2026 10:41:31 +0530 Subject: [PATCH 1/7] Add CrashReport API spec for WebView2 ProcessFailed correlation Adds CrashReport.md spec for the new ICoreWebView2StagingCrashReport API that correlates WebView2 process failures with Watson crash reports. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- specs/CrashReport.md | 252 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 specs/CrashReport.md diff --git a/specs/CrashReport.md b/specs/CrashReport.md new file mode 100644 index 000000000..9b66fe473 --- /dev/null +++ b/specs/CrashReport.md @@ -0,0 +1,252 @@ +ICoreWebView2CrashReport +=== + +# Background + +WebView2 fires the +[`ProcessFailed`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2#add_processfailed) +event when a WebView2 process crashes, hangs, or fails to launch. The event tells you +the failure kind, the exit code, and the process type, enough to react and recover. But it does not +tell you _which crash report was generated_ for that failure. + +When a crash occurs, the WebView2 runtime's crash handler captures a minidump and writes crash +signature data (exception code, faulting module, bucket ID) to disk. This data is useful for +tracking reliability, grouping crashes by root cause, and filing actionable bug reports. Today there +is no supported API to read this data from a host application. + +This document proposes `ICoreWebView2CrashReport`, a new read-only property on +`ProcessFailedEventArgs` that delivers crash signature data to your handler at the moment the event +fires: no file parsing, no event log queries, no internal knowledge required. A stable +`CrashReportId` ties the event directly to the crash report on disk, which you can locate via +[`FailureReportFolderPath`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2environment11#get_failurereportfolderpath). + +# Description + +We propose to extend `ProcessFailedEventArgs` with a read-only `CrashReport` property that exposes +a `CoreWebView2CrashReport` object. This object is a snapshot of crash signature data captured at +the moment of failure (exception code, faulting module and version, fault offset, bucket id, and +report time). Per-property reference documentation appears in the API Details section. + +`CrashReport` is `null` when the failure did not produce a crash report. That is: + +- The failure is a hang (`CoreWebView2ProcessFailedReason.Unresponsive`); the process is still + alive at this point, so no crash report exists yet. +- The failure is a launch failure or a clean termination; these do not go through the crash + handler. +- The crash handler ran but could not find a matching crash record (rare; typically a timing issue). + +`CrashReport` is populated for crash failures, including renderer crashes, GPU process crashes, +utility process crashes, browser process crashes, and out-of-memory terminations. + +Each `CoreWebView2Environment` only delivers reports for its own WebView2 processes (scoped by user +data folder). When +[`IsCustomCrashReportingEnabled`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2environmentoptions3#get_iscustomcrashreportingenabled) +is `TRUE`, the crash handler still catches exceptions and writes the minidump and crash metadata to +disk, so `CrashReport` is populated and all fields except `BucketId` are available. `BucketId` will +be empty because the network hit that returns the bucket assignment is not made when custom crash +reporting is enabled. + +# Examples + +The following code snippets demonstrate how to use `CrashReport` to log crash identity at failure +time. + +## Win32 C++ + +```cpp +CHECK_FAILURE(m_webView->add_ProcessFailed( + Callback( + [this](ICoreWebView2* sender, + ICoreWebView2ProcessFailedEventArgs* argsRaw) -> HRESULT + { + wil::com_ptr args; + CHECK_FAILURE(argsRaw->QueryInterface(IID_PPV_ARGS(&args))); + + wil::com_ptr crashReport; + CHECK_FAILURE(args->get_CrashReport(&crashReport)); + + if (crashReport) + { + wil::unique_cotaskmem_string crashReportId; + CHECK_FAILURE(crashReport->get_CrashReportId(&crashReportId)); + + UINT32 exceptionCode = 0; + CHECK_FAILURE(crashReport->get_ExceptionCode(&exceptionCode)); + + wil::unique_cotaskmem_string faultingModuleName; + CHECK_FAILURE(crashReport->get_FaultingModuleName(&faultingModuleName)); + + wil::unique_cotaskmem_string faultingModuleVersion; + CHECK_FAILURE(crashReport->get_FaultingModuleVersion(&faultingModuleVersion)); + + UINT64 faultOffset = 0; + CHECK_FAILURE(crashReport->get_FaultOffset(&faultOffset)); + + wil::unique_cotaskmem_string bucketId; + CHECK_FAILURE(crashReport->get_BucketId(&bucketId)); + + UINT64 reportTime = 0; + CHECK_FAILURE(crashReport->get_ReportTime(&reportTime)); + + LogCrashReport( + crashReportId.get(), + exceptionCode, + faultingModuleName.get(), + faultingModuleVersion.get(), + faultOffset, + bucketId.get(), + reportTime); + } + // crashReport is null when the failure did not produce a crash report + // (e.g., normal exit, hang, or external kill). Use ProcessFailedKind + // and Reason to decide how to handle the failure. + return S_OK; + }) + .Get(), + &m_processFailedToken)); +``` + +## .NET and WinRT + +```c# +webView.CoreWebView2.ProcessFailed += (sender, args) => +{ + var report = args.CrashReport; // null if no crash report + if (report != null) + { + LogCrashReport( + report.CrashReportId, + report.ExceptionCode, + report.FaultingModuleName, + report.FaultingModuleVersion, + report.FaultOffset, + report.BucketId, + report.ReportTime); // Windows.Foundation.DateTime (DateTimeOffset in C#) + } + // report is null when the failure did not produce a crash report + // (e.g., normal exit, hang, or external kill). +}; +``` + +# API Details + +## COM + +```cpp +/// Provides crash signature data captured at the moment of process failure. +/// Accessed via ICoreWebView2ProcessFailedEventArgs5.CrashReport. +/// +/// CrashReport is null when the failure did not produce a crash report +/// (normal exit, external kill, launch failure, hang). +[uuid(7c3a1b40-9f1e-4a5d-8b2e-2e0e7c1f3a55), object, pointer_default(unique)] +interface ICoreWebView2CrashReport : IUnknown { + /// A stable identifier for this crash report. Use this to locate the + /// corresponding dump file in `FailureReportFolderPath`. The dump file + /// is written as `.dmp` directly inside that folder. + // MSOWNERS: core (wvcore@microsoft.com) + [propget] HRESULT CrashReportId([out, retval] LPWSTR* value); + + /// The Windows exception code captured by the crash handler, + /// e.g. 0xC0000005 for STATUS_ACCESS_VIOLATION or 0xC0000409 for + /// STATUS_STACK_BUFFER_OVERRUN (fast-fail). + // MSOWNERS: core (wvcore@microsoft.com) + [propget] HRESULT ExceptionCode([out, retval] UINT32* value); + + /// Basename of the module containing the faulting instruction, + /// e.g. "v8.dll". Never a full path. + // MSOWNERS: core (wvcore@microsoft.com) + [propget] HRESULT FaultingModuleName([out, retval] LPWSTR* value); + + /// Version of the faulting module, e.g. "128.0.2739.42". + // MSOWNERS: core (wvcore@microsoft.com) + [propget] HRESULT FaultingModuleVersion([out, retval] LPWSTR* value); + + /// Relative virtual address (RVA) of the faulting instruction within + /// `FaultingModuleName`. + // MSOWNERS: core (wvcore@microsoft.com) + [propget] HRESULT FaultOffset([out, retval] UINT64* value); + + /// Crash bucket identifier assigned by Microsoft's crash telemetry + /// service, if available at event-fire time. Empty when no bucket was + /// assigned (network throttled/unavailable, custom crash reporting + /// enabled, or the crash bypassed the standard handler such as + /// `__fastfail`). + // MSOWNERS: core (wvcore@microsoft.com) + [propget] HRESULT BucketId([out, retval] LPWSTR* value); + + /// Time the crash report was recorded, as a Windows FILETIME value + /// (100-nanosecond intervals since Jan 1 1601 UTC). Zero if unavailable. + // MSOWNERS: core (wvcore@microsoft.com) + [propget] HRESULT ReportTime([out, retval] UINT64* value); +} + +/// A continuation of the ICoreWebView2ProcessFailedEventArgs4 interface +/// for getting the crash report associated with the process failure. +[uuid(1d8e2f4a-3c6b-4f7d-9a1e-5b8c2d3e4f60), object, pointer_default(unique)] +interface ICoreWebView2ProcessFailedEventArgs5 + : ICoreWebView2ProcessFailedEventArgs4 { + /// The crash report for this process failure, or null if the failure + /// did not produce a report (normal exit, external kill, launch + /// failure, hang). + // MSOWNERS: core (wvcore@microsoft.com) + [propget] HRESULT CrashReport( + [out, retval] ICoreWebView2CrashReport** value); +} +``` + +## .NET / WinRT + +```c# +namespace Microsoft.Web.WebView2.Core +{ + runtimeclass CoreWebView2CrashReport + { + [interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2CrashReport")] + { + String CrashReportId { get; }; + UInt32 ExceptionCode { get; }; + String FaultingModuleName { get; }; + String FaultingModuleVersion { get; }; + UInt64 FaultOffset { get; }; + String BucketId { get; }; + // Projected from the COM FILETIME (UINT64). + Windows.Foundation.DateTime ReportTime { get; }; + } + } + + runtimeclass CoreWebView2ProcessFailedEventArgs + { + // ... existing members ... + + [interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2ProcessFailedEventArgs5")] + { + CoreWebView2CrashReport CrashReport { get; }; + } + } +} +``` + +# Appendix + +## Relationship to existing APIs + +| API | Purpose | +| --- | --- | +| `ProcessFailedEventArgs5.CrashReport` _(this API)_ | Crash identity and signature at failure time. | +| [`ProcessFailed`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2#add_processfailed) | Real-time recovery signal (kind, reason, exit code). | +| [`BrowserProcessExited`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2environment5#add_browserprocessexited) | Browser process exit notification (lifecycle, no CrashReport). | +| [`IsCustomCrashReportingEnabled`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2environmentoptions3#get_iscustomcrashreportingenabled) | Disables upload to Microsoft's telemetry service. Minidump is still written locally; `CrashReport` is populated but `BucketId` will be empty. | +| [`FailureReportFolderPath`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2environment11#get_failurereportfolderpath) | Dump folder. Use `CrashReportId` to find the dump file. | + +## Privacy + +All fields in `CrashReport` are technical crash-signature values with no user-identifying signal: + +| Field | Notes | PII Risk | +| --- | --- | --- | +| `CrashReportId` | Random UUID; no user-identifying signal. | None | +| `ExceptionCode`, `FaultOffset` | Technical values; identical across users for the same crash. | None | +| `FaultingModuleName` | Basename only; never a full path. | None | +| `FaultingModuleVersion` | Public version string. | None | +| `BucketId` | Identifier assigned by Microsoft's crash telemetry service; no user data. May be empty. | None | +| `ReportTime` | Timestamp of the crash; identical precision to OS event logs. No user-identifying signal. | None | From 913a79570693ccc901c0edf5ce91cfb9b4a6c932 Mon Sep 17 00:00:00 2001 From: GittyHarsha Date: Wed, 13 May 2026 14:41:57 +0530 Subject: [PATCH 2/7] CrashReport: apply doc review fixes - Fix title from interface name to human-friendly 'Crash Report' - Fix COM IDL code block language tag (cpp -> no tag) - Fix WinRT/NET section headings to 'WinRT and .NET' - Add __fastfail note: fields from WER event log, BucketId empty - Add OOM exception code 0xe0000008 to ExceptionCode doc - Soften CrashReportId dump filename claim - Clean up BucketId doc (remove WER internal field names) - Fix IsCustomCrashReportingEnabled: remove 'network hit' impl detail Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- specs/CrashReport.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/specs/CrashReport.md b/specs/CrashReport.md index 9b66fe473..3274ba50a 100644 --- a/specs/CrashReport.md +++ b/specs/CrashReport.md @@ -1,4 +1,4 @@ -ICoreWebView2CrashReport +Crash Report === # Background @@ -33,18 +33,18 @@ report time). Per-property reference documentation appears in the API Details se alive at this point, so no crash report exists yet. - The failure is a launch failure or a clean termination; these do not go through the crash handler. -- The crash handler ran but could not find a matching crash record (rare; typically a timing issue). -`CrashReport` is populated for crash failures, including renderer crashes, GPU process crashes, -utility process crashes, browser process crashes, and out-of-memory terminations. +`CrashReport` is populated for any crash-type process failure, including `__fastfail` +(`0xC0000409`) and out-of-memory terminations. For `__fastfail` crashes, fields are +sourced from the Windows Error Reporting event log rather than the crash handler; +`BucketId` will be empty. Each `CoreWebView2Environment` only delivers reports for its own WebView2 processes (scoped by user data folder). When [`IsCustomCrashReportingEnabled`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2environmentoptions3#get_iscustomcrashreportingenabled) is `TRUE`, the crash handler still catches exceptions and writes the minidump and crash metadata to disk, so `CrashReport` is populated and all fields except `BucketId` are available. `BucketId` will -be empty because the network hit that returns the bucket assignment is not made when custom crash -reporting is enabled. +be empty because crash data is not uploaded to Microsoft's telemetry service. # Examples @@ -106,7 +106,7 @@ CHECK_FAILURE(m_webView->add_ProcessFailed( &m_processFailedToken)); ``` -## .NET and WinRT +## WinRT and .NET ```c# webView.CoreWebView2.ProcessFailed += (sender, args) => @@ -132,7 +132,7 @@ webView.CoreWebView2.ProcessFailed += (sender, args) => ## COM -```cpp +``` /// Provides crash signature data captured at the moment of process failure. /// Accessed via ICoreWebView2ProcessFailedEventArgs5.CrashReport. /// @@ -141,14 +141,13 @@ webView.CoreWebView2.ProcessFailed += (sender, args) => [uuid(7c3a1b40-9f1e-4a5d-8b2e-2e0e7c1f3a55), object, pointer_default(unique)] interface ICoreWebView2CrashReport : IUnknown { /// A stable identifier for this crash report. Use this to locate the - /// corresponding dump file in `FailureReportFolderPath`. The dump file - /// is written as `.dmp` directly inside that folder. + /// corresponding dump file in `FailureReportFolderPath`. // MSOWNERS: core (wvcore@microsoft.com) [propget] HRESULT CrashReportId([out, retval] LPWSTR* value); - /// The Windows exception code captured by the crash handler, - /// e.g. 0xC0000005 for STATUS_ACCESS_VIOLATION or 0xC0000409 for - /// STATUS_STACK_BUFFER_OVERRUN (fast-fail). + /// The Windows exception code for the failure, e.g. 0xC0000005 for + /// STATUS_ACCESS_VIOLATION, 0xC0000409 for STATUS_STACK_BUFFER_OVERRUN + /// (fast-fail), or 0xe0000008 for an out-of-memory termination. // MSOWNERS: core (wvcore@microsoft.com) [propget] HRESULT ExceptionCode([out, retval] UINT32* value); @@ -166,11 +165,12 @@ interface ICoreWebView2CrashReport : IUnknown { // MSOWNERS: core (wvcore@microsoft.com) [propget] HRESULT FaultOffset([out, retval] UINT64* value); - /// Crash bucket identifier assigned by Microsoft's crash telemetry - /// service, if available at event-fire time. Empty when no bucket was - /// assigned (network throttled/unavailable, custom crash reporting - /// enabled, or the crash bypassed the standard handler such as - /// `__fastfail`). + /// Crash bucket identifier assigned by Microsoft's crash telemetry service, + /// if available at event-fire time. Returned as a 32-character hex string. + /// Empty when no bucket was assigned: crash data was not uploaded to + /// Microsoft's telemetry service (custom crash reporting enabled), the + /// assignment was not yet received (network throttled/unavailable), or the + /// crash bypassed the standard handler (e.g. `__fastfail`). // MSOWNERS: core (wvcore@microsoft.com) [propget] HRESULT BucketId([out, retval] LPWSTR* value); @@ -194,7 +194,7 @@ interface ICoreWebView2ProcessFailedEventArgs5 } ``` -## .NET / WinRT +## WinRT and .NET ```c# namespace Microsoft.Web.WebView2.Core @@ -248,5 +248,5 @@ All fields in `CrashReport` are technical crash-signature values with no user-id | `ExceptionCode`, `FaultOffset` | Technical values; identical across users for the same crash. | None | | `FaultingModuleName` | Basename only; never a full path. | None | | `FaultingModuleVersion` | Public version string. | None | -| `BucketId` | Identifier assigned by Microsoft's crash telemetry service; no user data. May be empty. | None | +| `BucketId` | Hex string identifier assigned by Microsoft's crash telemetry service; no user data. May be empty. | None | | `ReportTime` | Timestamp of the crash; identical precision to OS event logs. No user-identifying signal. | None | From c82eec60d64e358882e997aa32ab5357faae5e6c Mon Sep 17 00:00:00 2001 From: harshanp_microsoft Date: Mon, 25 May 2026 17:35:37 +0530 Subject: [PATCH 3/7] Fix BucketId availability doc and CrashReportId dump-file claim - BucketId IS available at event-fire time for HTTP/Mac paths (handler completes upload before ProcessFailed fires). Remove stale 'network throttled/unavailable' case which implied it might not be. - Add enterprise AAD WerReportSubmit as an explicit empty-BucketId case (no HTTP feedback channel, bucket never returned at event time). - CrashReportId: soften 'locate the dump file' claim -- __fastfail crashes have no dump; CrashReportId still identifies the failure. - Background: note that __fastfail produces no dump; CrashReportId still valid in that case. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- specs/CrashReport.md | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/specs/CrashReport.md b/specs/CrashReport.md index 3274ba50a..1315df9ca 100644 --- a/specs/CrashReport.md +++ b/specs/CrashReport.md @@ -17,8 +17,11 @@ is no supported API to read this data from a host application. This document proposes `ICoreWebView2CrashReport`, a new read-only property on `ProcessFailedEventArgs` that delivers crash signature data to your handler at the moment the event fires: no file parsing, no event log queries, no internal knowledge required. A stable -`CrashReportId` ties the event directly to the crash report on disk, which you can locate via +`CrashReportId` identifies the crash event and, when a dump was written, can be used to locate the +corresponding dump file via [`FailureReportFolderPath`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2environment11#get_failurereportfolderpath). +Note that some crash types (e.g. `__fastfail`) do not produce a dump file at all; `CrashReportId` +still uniquely identifies the failure in that case. # Description @@ -35,9 +38,11 @@ report time). Per-property reference documentation appears in the API Details se handler. `CrashReport` is populated for any crash-type process failure, including `__fastfail` -(`0xC0000409`) and out-of-memory terminations. For `__fastfail` crashes, fields are -sourced from the Windows Error Reporting event log rather than the crash handler; -`BucketId` will be empty. +(`0xC0000409`) and out-of-memory terminations. For `__fastfail` crashes on Windows, the standard +crash handler is bypassed entirely; fields are sourced from the Windows Error Reporting event log +instead, and `BucketId` will be empty. `BucketId` is also empty on Windows devices where crash +reports are submitted via `WerReportSubmit` rather than direct HTTP upload (enterprise +Azure-AD-joined devices not classified as internal users). Each `CoreWebView2Environment` only delivers reports for its own WebView2 processes (scoped by user data folder). When @@ -140,8 +145,10 @@ webView.CoreWebView2.ProcessFailed += (sender, args) => /// (normal exit, external kill, launch failure, hang). [uuid(7c3a1b40-9f1e-4a5d-8b2e-2e0e7c1f3a55), object, pointer_default(unique)] interface ICoreWebView2CrashReport : IUnknown { - /// A stable identifier for this crash report. Use this to locate the - /// corresponding dump file in `FailureReportFolderPath`. + /// A stable identifier for this crash report. When a minidump was written, + /// use this to locate the corresponding dump file in `FailureReportFolderPath`. + /// For crashes that bypass the standard handler (e.g. `__fastfail`), no dump + /// file is written, but `CrashReportId` still uniquely identifies the failure. // MSOWNERS: core (wvcore@microsoft.com) [propget] HRESULT CrashReportId([out, retval] LPWSTR* value); @@ -165,12 +172,18 @@ interface ICoreWebView2CrashReport : IUnknown { // MSOWNERS: core (wvcore@microsoft.com) [propget] HRESULT FaultOffset([out, retval] UINT64* value); - /// Crash bucket identifier assigned by Microsoft's crash telemetry service, - /// if available at event-fire time. Returned as a 32-character hex string. - /// Empty when no bucket was assigned: crash data was not uploaded to - /// Microsoft's telemetry service (custom crash reporting enabled), the - /// assignment was not yet received (network throttled/unavailable), or the - /// crash bypassed the standard handler (e.g. `__fastfail`). + /// Crash bucket identifier assigned by Microsoft's crash telemetry service. + /// Returned as a 32-character hex string. Available at event-fire time on + /// devices that upload crash data via HTTP (the standard path for most + /// consumer and non-enterprise Windows devices, and all Mac devices). + /// Empty in the following cases: + /// - Custom crash reporting is enabled (`IsCustomCrashReportingEnabled`): + /// crash data is not uploaded to Microsoft's telemetry service. + /// - The crash bypassed the standard handler (e.g. `__fastfail` on Windows): + /// no crash handler ran, so no upload occurred. + /// - Enterprise Azure-AD-joined device (non-internal): crash is submitted via + /// `WerReportSubmit` rather than HTTP; no feedback channel exists to return + /// the bucket assignment at event time. // MSOWNERS: core (wvcore@microsoft.com) [propget] HRESULT BucketId([out, retval] LPWSTR* value); From 38033afbed52e3edc0f00914497b17d6161f6558 Mon Sep 17 00:00:00 2001 From: harshanp_microsoft Date: Mon, 25 May 2026 17:37:40 +0530 Subject: [PATCH 4/7] Revert "Fix BucketId availability doc and CrashReportId dump-file claim" This reverts commit c82eec60d64e358882e997aa32ab5357faae5e6c. --- specs/CrashReport.md | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/specs/CrashReport.md b/specs/CrashReport.md index 1315df9ca..3274ba50a 100644 --- a/specs/CrashReport.md +++ b/specs/CrashReport.md @@ -17,11 +17,8 @@ is no supported API to read this data from a host application. This document proposes `ICoreWebView2CrashReport`, a new read-only property on `ProcessFailedEventArgs` that delivers crash signature data to your handler at the moment the event fires: no file parsing, no event log queries, no internal knowledge required. A stable -`CrashReportId` identifies the crash event and, when a dump was written, can be used to locate the -corresponding dump file via +`CrashReportId` ties the event directly to the crash report on disk, which you can locate via [`FailureReportFolderPath`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2environment11#get_failurereportfolderpath). -Note that some crash types (e.g. `__fastfail`) do not produce a dump file at all; `CrashReportId` -still uniquely identifies the failure in that case. # Description @@ -38,11 +35,9 @@ report time). Per-property reference documentation appears in the API Details se handler. `CrashReport` is populated for any crash-type process failure, including `__fastfail` -(`0xC0000409`) and out-of-memory terminations. For `__fastfail` crashes on Windows, the standard -crash handler is bypassed entirely; fields are sourced from the Windows Error Reporting event log -instead, and `BucketId` will be empty. `BucketId` is also empty on Windows devices where crash -reports are submitted via `WerReportSubmit` rather than direct HTTP upload (enterprise -Azure-AD-joined devices not classified as internal users). +(`0xC0000409`) and out-of-memory terminations. For `__fastfail` crashes, fields are +sourced from the Windows Error Reporting event log rather than the crash handler; +`BucketId` will be empty. Each `CoreWebView2Environment` only delivers reports for its own WebView2 processes (scoped by user data folder). When @@ -145,10 +140,8 @@ webView.CoreWebView2.ProcessFailed += (sender, args) => /// (normal exit, external kill, launch failure, hang). [uuid(7c3a1b40-9f1e-4a5d-8b2e-2e0e7c1f3a55), object, pointer_default(unique)] interface ICoreWebView2CrashReport : IUnknown { - /// A stable identifier for this crash report. When a minidump was written, - /// use this to locate the corresponding dump file in `FailureReportFolderPath`. - /// For crashes that bypass the standard handler (e.g. `__fastfail`), no dump - /// file is written, but `CrashReportId` still uniquely identifies the failure. + /// A stable identifier for this crash report. Use this to locate the + /// corresponding dump file in `FailureReportFolderPath`. // MSOWNERS: core (wvcore@microsoft.com) [propget] HRESULT CrashReportId([out, retval] LPWSTR* value); @@ -172,18 +165,12 @@ interface ICoreWebView2CrashReport : IUnknown { // MSOWNERS: core (wvcore@microsoft.com) [propget] HRESULT FaultOffset([out, retval] UINT64* value); - /// Crash bucket identifier assigned by Microsoft's crash telemetry service. - /// Returned as a 32-character hex string. Available at event-fire time on - /// devices that upload crash data via HTTP (the standard path for most - /// consumer and non-enterprise Windows devices, and all Mac devices). - /// Empty in the following cases: - /// - Custom crash reporting is enabled (`IsCustomCrashReportingEnabled`): - /// crash data is not uploaded to Microsoft's telemetry service. - /// - The crash bypassed the standard handler (e.g. `__fastfail` on Windows): - /// no crash handler ran, so no upload occurred. - /// - Enterprise Azure-AD-joined device (non-internal): crash is submitted via - /// `WerReportSubmit` rather than HTTP; no feedback channel exists to return - /// the bucket assignment at event time. + /// Crash bucket identifier assigned by Microsoft's crash telemetry service, + /// if available at event-fire time. Returned as a 32-character hex string. + /// Empty when no bucket was assigned: crash data was not uploaded to + /// Microsoft's telemetry service (custom crash reporting enabled), the + /// assignment was not yet received (network throttled/unavailable), or the + /// crash bypassed the standard handler (e.g. `__fastfail`). // MSOWNERS: core (wvcore@microsoft.com) [propget] HRESULT BucketId([out, retval] LPWSTR* value); From e583ecd13917ec4f123a0d4a441d9bdf1ca29218 Mon Sep 17 00:00:00 2001 From: GittyHarsha Date: Wed, 27 May 2026 09:56:56 +0530 Subject: [PATCH 5/7] CrashReport: Crashpad-only contract, null for __fastfail/heap corruption CrashReport is null for crashes that bypass the Crashpad crash handler (__fastfail, heap corruption). These still fire ProcessFailed but do not produce a crash report. Host apps that need data for those failure types can query WER Event 1000 directly. Remove WER event-log sourcing language from the summary and property docs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- specs/CrashReport.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/specs/CrashReport.md b/specs/CrashReport.md index 3274ba50a..2dd0fa325 100644 --- a/specs/CrashReport.md +++ b/specs/CrashReport.md @@ -34,10 +34,10 @@ report time). Per-property reference documentation appears in the API Details se - The failure is a launch failure or a clean termination; these do not go through the crash handler. -`CrashReport` is populated for any crash-type process failure, including `__fastfail` -(`0xC0000409`) and out-of-memory terminations. For `__fastfail` crashes, fields are -sourced from the Windows Error Reporting event log rather than the crash handler; -`BucketId` will be empty. +`CrashReport` is populated for crash-type process failures handled by the WebView2 crash +handler, including out-of-memory terminations. `CrashReport` is `null` for crashes that +bypass the crash handler, such as `__fastfail` (`0xC0000409`) and heap corruption +terminations; these failures still fire `ProcessFailed` but do not produce a crash report. Each `CoreWebView2Environment` only delivers reports for its own WebView2 processes (scoped by user data folder). When @@ -146,8 +146,7 @@ interface ICoreWebView2CrashReport : IUnknown { [propget] HRESULT CrashReportId([out, retval] LPWSTR* value); /// The Windows exception code for the failure, e.g. 0xC0000005 for - /// STATUS_ACCESS_VIOLATION, 0xC0000409 for STATUS_STACK_BUFFER_OVERRUN - /// (fast-fail), or 0xe0000008 for an out-of-memory termination. + /// STATUS_ACCESS_VIOLATION, or 0xe0000008 for an out-of-memory termination. // MSOWNERS: core (wvcore@microsoft.com) [propget] HRESULT ExceptionCode([out, retval] UINT32* value); @@ -168,9 +167,8 @@ interface ICoreWebView2CrashReport : IUnknown { /// Crash bucket identifier assigned by Microsoft's crash telemetry service, /// if available at event-fire time. Returned as a 32-character hex string. /// Empty when no bucket was assigned: crash data was not uploaded to - /// Microsoft's telemetry service (custom crash reporting enabled), the - /// assignment was not yet received (network throttled/unavailable), or the - /// crash bypassed the standard handler (e.g. `__fastfail`). + /// Microsoft's telemetry service (custom crash reporting enabled), or the + /// assignment was not yet received (network throttled/unavailable). // MSOWNERS: core (wvcore@microsoft.com) [propget] HRESULT BucketId([out, retval] LPWSTR* value); From b742fde06ec2e345cbdd15d2e3c068c45bbfc4ef Mon Sep 17 00:00:00 2001 From: GittyHarsha Date: Fri, 29 May 2026 06:33:41 +0530 Subject: [PATCH 6/7] CrashReport: clean up spec language and null-case documentation - Replace 'minidump' with 'crash dump' throughout (heap dumps also possible) - Remove implementation-detail language (no fastfail/heap corruption enumeration, no internal mechanism references) - Remove field list from Background and Description intros - Remove marketing noise from Background paragraph - Add external kill as explicit null case - Tighten null-case prose to be implementation-neutral - Add dump filename hint (.dmp) to Background - Update IDL comment to cover crash-type failures with no report --- specs/CrashReport.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/specs/CrashReport.md b/specs/CrashReport.md index 2dd0fa325..aba826956 100644 --- a/specs/CrashReport.md +++ b/specs/CrashReport.md @@ -9,23 +9,22 @@ event when a WebView2 process crashes, hangs, or fails to launch. The event tell the failure kind, the exit code, and the process type, enough to react and recover. But it does not tell you _which crash report was generated_ for that failure. -When a crash occurs, the WebView2 runtime's crash handler captures a minidump and writes crash +When a crash occurs, the WebView2 runtime's crash handler captures a crash dump and writes crash signature data (exception code, faulting module, bucket ID) to disk. This data is useful for tracking reliability, grouping crashes by root cause, and filing actionable bug reports. Today there is no supported API to read this data from a host application. This document proposes `ICoreWebView2CrashReport`, a new read-only property on `ProcessFailedEventArgs` that delivers crash signature data to your handler at the moment the event -fires: no file parsing, no event log queries, no internal knowledge required. A stable -`CrashReportId` ties the event directly to the crash report on disk, which you can locate via +fires. `CrashReportId` ties the event directly to the crash report on disk (`.dmp`), +which you can locate via [`FailureReportFolderPath`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2environment11#get_failurereportfolderpath). # Description We propose to extend `ProcessFailedEventArgs` with a read-only `CrashReport` property that exposes -a `CoreWebView2CrashReport` object. This object is a snapshot of crash signature data captured at -the moment of failure (exception code, faulting module and version, fault offset, bucket id, and -report time). Per-property reference documentation appears in the API Details section. +a `CoreWebView2CrashReport` object. This object provides crash signature data captured at +the moment of failure. Per-property reference documentation appears in the API Details section. `CrashReport` is `null` when the failure did not produce a crash report. That is: @@ -33,16 +32,17 @@ report time). Per-property reference documentation appears in the API Details se alive at this point, so no crash report exists yet. - The failure is a launch failure or a clean termination; these do not go through the crash handler. +- The process was terminated externally (for example, by Task Manager or another application + calling `TerminateProcess`); no crash handler runs in this case. -`CrashReport` is populated for crash-type process failures handled by the WebView2 crash -handler, including out-of-memory terminations. `CrashReport` is `null` for crashes that -bypass the crash handler, such as `__fastfail` (`0xC0000409`) and heap corruption -terminations; these failures still fire `ProcessFailed` but do not produce a crash report. +`CrashReport` is populated for crash-type process failures for which a crash report is +available. `CrashReport` may be `null` for certain crash-type failures where no crash +report was produced; host apps should always check for `null` before accessing properties. Each `CoreWebView2Environment` only delivers reports for its own WebView2 processes (scoped by user data folder). When [`IsCustomCrashReportingEnabled`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2environmentoptions3#get_iscustomcrashreportingenabled) -is `TRUE`, the crash handler still catches exceptions and writes the minidump and crash metadata to +is `TRUE`, the crash handler still catches exceptions and writes the crash dump and crash metadata to disk, so `CrashReport` is populated and all fields except `BucketId` are available. `BucketId` will be empty because crash data is not uploaded to Microsoft's telemetry service. @@ -183,9 +183,9 @@ interface ICoreWebView2CrashReport : IUnknown { [uuid(1d8e2f4a-3c6b-4f7d-9a1e-5b8c2d3e4f60), object, pointer_default(unique)] interface ICoreWebView2ProcessFailedEventArgs5 : ICoreWebView2ProcessFailedEventArgs4 { - /// The crash report for this process failure, or null if the failure - /// did not produce a report (normal exit, external kill, launch - /// failure, hang). + /// The crash report for this process failure, or null if no crash report + /// is available for this failure (normal exit, external kill, launch + /// failure, hang, or crash-type failure that produced no report). // MSOWNERS: core (wvcore@microsoft.com) [propget] HRESULT CrashReport( [out, retval] ICoreWebView2CrashReport** value); @@ -233,7 +233,7 @@ namespace Microsoft.Web.WebView2.Core | `ProcessFailedEventArgs5.CrashReport` _(this API)_ | Crash identity and signature at failure time. | | [`ProcessFailed`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2#add_processfailed) | Real-time recovery signal (kind, reason, exit code). | | [`BrowserProcessExited`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2environment5#add_browserprocessexited) | Browser process exit notification (lifecycle, no CrashReport). | -| [`IsCustomCrashReportingEnabled`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2environmentoptions3#get_iscustomcrashreportingenabled) | Disables upload to Microsoft's telemetry service. Minidump is still written locally; `CrashReport` is populated but `BucketId` will be empty. | +| [`IsCustomCrashReportingEnabled`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2environmentoptions3#get_iscustomcrashreportingenabled) | Disables upload to Microsoft's telemetry service. Crash dump is still written locally; `CrashReport` is populated but `BucketId` will be empty. | | [`FailureReportFolderPath`](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2environment11#get_failurereportfolderpath) | Dump folder. Use `CrashReportId` to find the dump file. | ## Privacy From 8cc189303caa20c7de523ac4d1bd82bd9fead5a2 Mon Sep 17 00:00:00 2001 From: GittyHarsha Date: Fri, 29 May 2026 21:45:03 +0530 Subject: [PATCH 7/7] fixup! CrashReport: clean up spec language and null-case documentation --- specs/CrashReport.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specs/CrashReport.md b/specs/CrashReport.md index aba826956..6e9db1b3a 100644 --- a/specs/CrashReport.md +++ b/specs/CrashReport.md @@ -10,9 +10,9 @@ the failure kind, the exit code, and the process type, enough to react and recov tell you _which crash report was generated_ for that failure. When a crash occurs, the WebView2 runtime's crash handler captures a crash dump and writes crash -signature data (exception code, faulting module, bucket ID) to disk. This data is useful for -tracking reliability, grouping crashes by root cause, and filing actionable bug reports. Today there -is no supported API to read this data from a host application. +signature data to disk. This data is useful for tracking reliability, grouping crashes by root +cause, and filing actionable bug reports. Today there is no supported API to read this data from a +host application. This document proposes `ICoreWebView2CrashReport`, a new read-only property on `ProcessFailedEventArgs` that delivers crash signature data to your handler at the moment the event