Skip to content

[cDAC] Relax HRESULT validation to allow divergent failure codes#125236

Merged
max-charlamb merged 1 commit intodotnet:mainfrom
max-charlamb:cdac-divergent-failure-verification
Mar 6, 2026
Merged

[cDAC] Relax HRESULT validation to allow divergent failure codes#125236
max-charlamb merged 1 commit intodotnet:mainfrom
max-charlamb:cdac-divergent-failure-verification

Conversation

@max-charlamb
Copy link
Member

Summary

The cDAC's DEBUG validation asserts compare HRESULTs between the cDAC and legacy DAC using exact equality (Debug.Assert(hrLocal == hr)). This causes the debugger process to crash when the cDAC and native DAC return different failure HRESULTs for the same invalid input.

For example, when GetMethodTableData is called with a garbage method table pointer, the cDAC may throw InvalidOperationException (0x80131C49) while the native DAC returns E_INVALIDARG (0x80070057). Both correctly reject the input, but the exact HRESULT comparison fires a fatal Debug.Assert that terminates the debugger mid-command — causing flaky CI failures like SOS.VarargPInvokeInteropMD in the cDAC_windows_x64_release job.

No consumer (ClrMD, SOS, managed debugger) branches on specific failure codes from these APIs — they only check success vs failure.

Changes

New file: DebugExtensions.cs — adds Debug.ValidateHResult() as a C# 14 static extension method on System.Diagnostics.Debug:

Debug.ValidateHResult(hr, hrLocal);

With two validation modes via HResultValidationMode:

  • Exact — HRESULTs must match exactly (available for APIs where the specific code matters)
  • AllowDivergentFailures (default) — success HRESULTs (S_OK, S_FALSE) must match exactly, but any two failing HRESULTs (negative values) are considered equivalent

Converted all 113 call sites across 5 files from:

Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}");

to:

Debug.ValidateHResult(hr, hrLocal);

Copilot AI review requested due to automatic review settings March 5, 2026 20:53
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag
See info in area-owners.md if you want to be subscribed.

Copy link
Contributor

Copilot AI left a comment

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 updates the cDAC Legacy layer’s DEBUG cross-validation to stop asserting on exact HRESULT equality when both the cDAC and legacy/native DAC correctly fail, but return different failure codes. This avoids debugger-process termination and associated test flakiness while still preserving strict validation for success results.

Changes:

  • Introduces Debug.ValidateHResult() (with HResultValidationMode) to centralize HRESULT comparison rules.
  • Replaces ~113 Debug.Assert(hrLocal == hr, ...) call sites with Debug.ValidateHResult(hr, hrLocal) across the Legacy implementation.
  • Preserves strict matching for success HRESULTs while allowing divergent failure HRESULTs by default.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs Replaces legacy-vs-cDAC HRESULT equality asserts with Debug.ValidateHResult.
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.IXCLRDataProcess.cs Same replacement for IXCLRDataProcess-related validation asserts.
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataStackWalk.cs Uses Debug.ValidateHResult when cross-validating stack-walk HRESULTs in DEBUG.
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataMethodInstance.cs Replaces per-site “allow any failing HRESULT” logic with the shared validator.
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ClrDataFrame.cs Updates frame HRESULT validation to use the shared validator.
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/DebugExtensions.cs Adds centralized HRESULT validation helper and mode enum.

Copy link
Contributor

@rcj1 rcj1 left a comment

Choose a reason for hiding this comment

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

As long as none of these callers differentiate between failures, then looks good to me

@max-charlamb max-charlamb merged commit dd20361 into dotnet:main Mar 6, 2026
58 checks passed
@max-charlamb max-charlamb deleted the cdac-divergent-failure-verification branch March 6, 2026 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants