Skip to content

Add TestCDACNoFallback flag for cDAC-only testing#5806

Merged
max-charlamb merged 1 commit intomainfrom
cdac-only-testing
Apr 17, 2026
Merged

Add TestCDACNoFallback flag for cDAC-only testing#5806
max-charlamb merged 1 commit intomainfrom
cdac-only-testing

Conversation

@max-charlamb
Copy link
Copy Markdown
Member

@max-charlamb max-charlamb commented Apr 16, 2026

Add a new TestCDACNoFallback test configuration flag (SOS_TEST_CDAC_NO_FALLBACK env var) that enables cDAC with no fallback to the legacy DAC.

When enabled:

  • Sets DOTNET_ENABLE_CDAC=1 and CDAC_NO_FALLBACK=1 on the debugger process
  • Adds CDAC_NO_FALLBACK_TESTING define to skip ClrStack -i tests (ICorDebug is not implemented in the cDAC)
  • TestCDACNoFallback takes precedence over TestCDAC when both are set

Wraps ClrStack -i commands with !IFDEF:CDAC_NO_FALLBACK_TESTING / ENDIF:CDAC_NO_FALLBACK_TESTING in 7 script files.

The CDAC_NO_FALLBACK environment variable is added by dotnet/runtime#126752, which introduces the no-fallback mode to the cDAC runtime and adds a no-fallback test leg to the runtime-diagnostics pipeline.

@max-charlamb max-charlamb requested a review from a team as a code owner April 16, 2026 19:06
Copilot AI review requested due to automatic review settings April 16, 2026 19:06
Copy link
Copy Markdown
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

Adds a new SOS unit test configuration knob (TestCDACNoFallback via SOS_TEST_CDAC_NO_FALLBACK) to run tests with cDAC enabled without falling back to the legacy DAC, and conditionally skips ICorDebug-dependent ClrStack -i validations in script-based tests.

Changes:

  • Introduces TestCDACNoFallback in TestConfiguration (env var parsing + log suffix tagging).
  • When enabled, sets DOTNET_ENABLE_CDAC=1 and CDAC_NO_FALLBACK=1 for the debugger process and adds a script define (CDAC_TESTING) to gate unsupported test sections.
  • Wraps ClrStack -i (ICorDebug) sections in 7 SOS .script files with !IFDEF:CDAC_TESTING / ENDIF:CDAC_TESTING.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/tests/SOS.UnitTests/Scripts/WebApp.script Skips ClrStack -i verification when CDAC_TESTING is enabled.
src/tests/SOS.UnitTests/Scripts/StackTests.script Gates ICorDebug-based ClrStack -i / -i -a region under !IFDEF:CDAC_TESTING.
src/tests/SOS.UnitTests/Scripts/StackAndOtherTests.script Gates ICorDebug-based ClrStack -i / -i -a region under !IFDEF:CDAC_TESTING.
src/tests/SOS.UnitTests/Scripts/MiniDumpLocalVarLookup.script Skips clrstack -i -l locals verification under CDAC_TESTING.
src/tests/SOS.UnitTests/Scripts/DynamicMethod.script Gates the ICorDebug-dependent flow (used for <POUT> capture) under !IFDEF:CDAC_TESTING.
src/tests/SOS.UnitTests/Scripts/DualRuntimes.script Skips ClrStack -i verification under CDAC_TESTING.
src/tests/SOS.UnitTests/Scripts/ClrStackWithNumberOfFrames.script Skips ClrStack -i -c ... checks under CDAC_TESTING.
src/tests/SOS.UnitTests/SOSRunner.cs Adds env var setup for no-fallback mode + enables CDAC_TESTING define for scripts.
src/Microsoft.Diagnostics.TestHelpers/TestConfiguration.cs Adds TestCDACNoFallback config value, suffix tagging, and boolean accessor.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/tests/SOS.UnitTests/SOSRunner.cs Outdated
Comment thread src/tests/SOS.UnitTests/SOSRunner.cs Outdated
Comment thread src/Microsoft.Diagnostics.TestHelpers/TestConfiguration.cs Outdated
@max-charlamb max-charlamb force-pushed the cdac-only-testing branch 2 times, most recently from 5d47d59 to 6e1da4b Compare April 16, 2026 19:22
@max-charlamb max-charlamb requested a review from rcj1 April 16, 2026 22:07
Add a new TestCDACNoFallback test configuration flag (SOS_TEST_CDAC_NO_FALLBACK
env var) that enables cDAC with no fallback to the legacy DAC.

When enabled:
- Sets DOTNET_ENABLE_CDAC=1 and CDAC_NO_FALLBACK=1 on the debugger process
- Adds CDAC_TESTING define to skip ClrStack -i tests (ICorDebug is not
  implemented in the cDAC)

Wraps ClrStack -i commands with !IFDEF:CDAC_TESTING in 7 script files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@max-charlamb max-charlamb enabled auto-merge (squash) April 16, 2026 22:25
@max-charlamb max-charlamb merged commit e82b80e into main Apr 17, 2026
19 checks passed
max-charlamb added a commit to dotnet/runtime that referenced this pull request Apr 17, 2026
Update runtime-diagnostics pipeline to use the -noFallback build flag
from dotnet/diagnostics#5806 instead of setting CDAC_NO_FALLBACK as a
pipeline-level environment variable. The -noFallback flag properly sets
the env var on the debugger process and enables CDAC_NO_FALLBACK_TESTING
defines to skip ClrStack -i tests.

Add noFallback parameter to runtime-diag-job.yml template and wire it
through to the build script.

Remove unnecessary try/catch around Console.Error.WriteLine in
LegacyFallbackHelper — stderr writes don't throw when the stream is
unavailable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@max-charlamb max-charlamb deleted the cdac-only-testing branch April 17, 2026 16:36
max-charlamb added a commit to dotnet/runtime that referenced this pull request Apr 17, 2026
Update runtime-diagnostics pipeline to use the -noFallback build flag
from dotnet/diagnostics#5806 instead of setting CDAC_NO_FALLBACK as a
pipeline-level environment variable. The -noFallback flag properly sets
the env var on the debugger process and enables CDAC_NO_FALLBACK_TESTING
defines to skip ClrStack -i tests.

Add noFallback parameter to runtime-diag-job.yml template and wire it
through to the build script.

Remove unnecessary try/catch around Console.Error.WriteLine in
LegacyFallbackHelper — stderr writes don't throw when the stream is
unavailable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
max-charlamb added a commit to dotnet/runtime that referenced this pull request Apr 17, 2026
> [!NOTE]
> This PR description was generated with the assistance of GitHub
Copilot.

## Summary

Add a granular, per-method allowlist (`LegacyFallbackHelper`) that
controls which delegation-only APIs may fall back to the legacy DAC when
`CDAC_NO_FALLBACK=1` is set. This enables selective no-fallback testing
— blocking fallback for most APIs while allowing specific APIs that are
known to not yet be implemented in the cDAC.

Wire this into the runtime-diagnostics CI pipeline using the
`-noFallback` flag from
[dotnet/diagnostics#5806](dotnet/diagnostics#5806).

All fallback attempts (both allowed and blocked) are logged to stderr
with method name, file, and line number for capture by the diagnostics
test infrastructure.

## Changes

### LegacyFallbackHelper.cs — Granular fallback control

New static helper that every delegation-only call site invokes via
`CanFallback()`. Uses `[CallerMemberName]`, `[CallerFilePath]`, and
`[CallerLineNumber]` to identify the call site.

- **Normal mode** (`CDAC_NO_FALLBACK` unset): Always returns `true`
(single `bool` check, `[AggressiveInlining]`)
- **No-fallback mode** (`CDAC_NO_FALLBACK=1`): Checks method name
against a `HashSet<string>` allowlist and file name against a file-level
allowlist

**Per-method allowlist:**

| Method | Reason |
|--------|--------|
| `EnumMemoryRegions` | Dump creation — cDAC has no memory enumeration
implementation |
| `GetInterface` | IMetaDataImport QI ([PR
#127028](#127028)) |
| `GetMethodDefinitionByToken` | IXCLRDataModule — not yet implemented
in cDAC |
| `IsTrackedType` | GC heap analysis ([PR
#125895](#125895)) |
| `TraverseLoaderHeap` | Loader heap traversal ([PR
#125129](#125129)) |

**File-level allowlist:**

| File | Reason |
|------|--------|
| `DacDbiImpl.cs` | Entire DBI/ICorDebug interface (122 methods) —
deferred |

### Entrypoints.cs — Simplified creation

Both `CreateSosInterface` and `CreateDacDbiInterface` now follow the
same pattern: the legacy implementation is always passed through, and
`LegacyFallbackHelper.CanFallback()` at each call site decides whether
to delegate. Removed `prevent_release`, `noFallback` env var check, and
null-legacy-ref logic.

### 13 Legacy wrapper files — Instrumented delegation sites

All 296 delegation-only methods across all legacy wrapper files now call
`LegacyFallbackHelper.CanFallback()`:

- `SOSDacImpl.cs` (12 methods)
- `SOSDacImpl.IXCLRDataProcess.cs` (38 methods, `Flush()` intentionally
excluded — cache management)
- `ClrDataModule.cs` (29 methods + IMetaDataImport QI)
- `DacDbiImpl.cs` (122 methods)
- Other wrappers: `ClrDataTask.cs`, `ClrDataExceptionState.cs`,
`ClrDataFrame.cs`, `ClrDataValue.cs`, `ClrDataTypeInstance.cs`,
`ClrDataMethodInstance.cs`, `ClrDataStackWalk.cs`, `ClrDataProcess.cs`

### CI Pipeline — `-noFallback` flag

Updated `runtime-diag-job.yml` to accept a `noFallback` parameter that
passes `-noFallback` to the diagnostics build script. The
`cDAC_no_fallback` leg in `runtime-diagnostics.yml` now uses
`noFallback: true` instead of setting `CDAC_NO_FALLBACK` as a
pipeline-level environment variable. The `-noFallback` flag (from
[dotnet/diagnostics#5806](dotnet/diagnostics#5806))
properly:

- Sets `DOTNET_ENABLE_CDAC=1` and `CDAC_NO_FALLBACK=1` on the debugger
process
- Defines `CDAC_NO_FALLBACK_TESTING` to skip `ClrStack -i` tests
(ICorDebug not implemented in cDAC)

### Stderr logging

Every fallback attempt is logged to stderr in the format:

```
[cDAC] Allowed fallback: CreateStackWalk at DacDbiImpl.cs:590
[cDAC] Blocked fallback: SomeMethod at SOSDacImpl.cs:123
```

The diagnostics test infrastructure (`ProcessRunner`) captures stderr
and routes it to xunit test output with `STDERROR:` prefix, making
fallback usage visible in test results.

## Test Results

With `CDAC_NO_FALLBACK=1` and the current allowlist, running the full
SOS test suite against a private runtime build:

- **24 passed**, **2 failed** (flaky/pre-existing), **2 skipped**
(Linux-only)
- **0 blocked fallbacks**

## Motivation

The existing cDAC test leg always has the legacy DAC as a fallback, so
unimplemented APIs are silently handled. The granular no-fallback mode
makes gaps visible per-method, helping track progress toward full cDAC
coverage while keeping tests green for known-deferred APIs.

---------

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants