Skip to content

Fix Mono Windows x64 hardware exception continuations - #133774

Merged
tannergooding merged 1 commit into
dotnet:mainfrom
tannergooding:tannergooding-ci-failure-analysis
Sep 12, 2026
Merged

tannergooding merged 1 commit into
dotnet:mainfrom
tannergooding:tannergooding-ci-failure-analysis

Conversation

@tannergooding

Copy link
Copy Markdown
Member

Summary

Fix Windows x64 Mono MiniJIT hardware-exception handling when Windows validates exception-continuation addresses. The vectored exception handler currently resumes directly at a dynamically generated managed handler; affected processes terminate with FAST_FAIL_SET_CONTEXT_DENIED instead of entering the catch.

Save the resolved managed handler context in existing thread-local storage and resume first at a native runtime entry point, which restores that context through Mono's existing restore trampoline. Supply the Win64 entry-stack alignment and argument home area, and keep the stack-overflow restoration context separate from the native continuation. This does not change process mitigation settings or add general CET support.

Add a three-case theory covering repeated divide-by-zero, overflow, and null-reference exceptions with nested hardware exceptions in filters and finally blocks. Restore the Windows x64 MiniJIT runtime-test lane disabled by #133747 so this PR exercises the full lane.

Fixes #133702.

Validation

  • Built Release and Debug Mono on Windows x64.
  • div2_d, div2_ro, HardwareEh, unhandledTester, and ExceptionInterop pass with both native builds in MiniJIT mode.
  • The same final HardwareEh binary exits with 0xC0000409 on the saved unfixed runtime and passes on the fixed Release and Debug runtimes. Verified that its generated entry point invokes all three new theory cases. It also passes with the Release interpreter.
  • Repeated local explicit-throw measurements overlap within measurement uncertainty: baseline 2.070 us versus candidate 2.008 us. The unfixed hardware-throw benchmark terminates, so there is no valid before/after throughput ratio for that path.
  • Verified that eng/pipelines/runtime.yml exactly matches its pre-quarantine version. Full MiniJIT CI and cross-platform suites have not been run locally.

Note

This PR was generated with GitHub Copilot.

Resume vectored exceptions through a native runtime entry point before restoring the managed handler context. Preserve the Win64 stack convention and stack-overflow restoration context without changing process mitigations.

Add nested hardware-exception coverage and restore the Windows x64 MiniJIT CI lane disabled for dotnet#133702.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings September 12, 2026 02:51
@github-actions github-actions Bot added the area-ExceptionHandling-coreclr only use for closed issues label Sep 12, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 6 pipeline(s).
10 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

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 review overview

🔵 Needs a closer look

SIMD-state restoration and stack-overflow coverage remain unresolved.

Review tier: Lite
Findings: None

What changed in this PR

Fixes Windows x64 Mono MiniJIT hardware-exception continuations through native context restoration, adds regression coverage, and restores the quarantined test lane.

Changes:

  • Adds nested divide-by-zero, overflow, and null-reference tests.
  • Routes continuations through native restoration with separate stack-overflow context.
  • Re-enables Windows x64 Mono MiniJIT runtime tests.
File Summary
src/​tests/​baseservices/​exceptions/​simple/​HardwareEh.cs Adds nested hardware-exception regression tests.
src/​mono/​mono/​mini/​exceptions-amd64.c Implements native continuation handling. Findings: SIMD state restoration is missing (moderate, 1 vote), and stack-overflow context splitting lacks Mono regression coverage (nit, 1 vote).
eng/​pipelines/​runtime.yml Restores the Windows x64 MiniJIT runtime-test lane.

@tannergooding

Copy link
Copy Markdown
Member Author

The untracked runtime failure is separate, but I have a fix up as #133775

The DAC jobs were kicked off because the eng/pipelines folder was changed, it was already broken and is separate.

Other failures are tracked by build analysis and are the networking, certificate, or gc tests.

@tannergooding

Copy link
Copy Markdown
Member Author

/ba-g unrelated known issues

@tannergooding
tannergooding merged commit 37dd42c into dotnet:main Sep 12, 2026
210 of 219 checks passed
@tannergooding
tannergooding deleted the tannergooding-ci-failure-analysis branch September 12, 2026 09:06
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 12.0-preview1 milestone Sep 14, 2026
max-charlamb pushed a commit to dotnet/diagnostics that referenced this pull request Sep 14, 2026
`Build.cmd -test` fails with MSB1001 because the wrapper's injected
`-restore -build` switches are forwarded to the separate Arcade test
invocation through array splatting. They become positional arguments
passed to MSBuild rather than named PowerShell switches.

Declare `restore` and `build` as wrapper parameters with Arcade's `r`
and `b` aliases, and forward their values explicitly to the
managed-build invocation. This keeps the injected switches out of the
test arguments while retaining the existing build/test phases and
remaining-argument forwarding paths.

Addresses the Windows SOS argument-forwarding failure observed on
dotnet/runtime#133774.

Validation: full Windows x64 build, plus targeted
`SOSGCTests.DumpGCData` runs through both `Build.cmd -test` and
`Test.cmd` against a private runtime in DAC mode; two cases passed in
each run.

> [!NOTE]
> This pull request description was drafted with GitHub Copilot.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
lewing pushed a commit that referenced this pull request Sep 14, 2026
## Summary

This fixes #133798

Fix the two AOT failures exposed by the expanded `github60486`
regression in #133707 and observed in CI for
#133774.

- Preserve callers of the stack-walk implementation of
`MethodBase.GetCurrentMethod` during Mono LLVM inlining. The LLVM-only
intrinsic already prevents inlining; the stack-walk path needs the same
protection. The test's inlineable helper remains unannotated.
- Allow unrelated NativeAOT stack frames to lack reflection metadata. A
local diagnostic run identified `TestEntryPoint` as the frame returning
null from `GetMethod`; all four recursive frames returned valid method
metadata. Keep the exact four-frame assertion and all existing DIM,
exception-stack, caller-identity, and GC-root checks.

Related caller-inlining report: #60334. Its iOS
configuration was not tested here.

## Validation

Built Checked CoreCLR/NativeAOT and Release Mono with LLVM from a clean
baseline in the same worktree.

| Windows x64 configuration | Before | After |
|---|---|---|
| NativeAOT Checked | Reported null-reference failure | Pass |
| Mono LLVM AOT Release | Expected `GetCurrentMethodInlineable`, actual
`ValidateCurrentMethod` | Pass |
| CoreCLR Checked | Pass | Pass |
| Mono MiniJIT Release | Pass | Pass |

Each run executes the full standalone `github60486` regression. Mono
LLVM AOT comparisons use identical test IL, and runtime logging confirms
the fixed AOT image is loaded. LLVM IR adds `noinline` to the inlineable
and generic wrappers; the optimized caller retains the helper call
instead of inlining it. No performance claim is made.

The Windows Mono LLVM AOT reproduction matches the Linux CI failure
signature. Linux and browser Wasm were not run locally. The Windows x64
JIT formatting check completed successfully.

> [!NOTE]
> This change and pull request description were developed with GitHub
Copilot assistance.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jtschuster pushed a commit to jtschuster/runtime that referenced this pull request Sep 18, 2026
## Summary

Fix Windows x64 Mono MiniJIT hardware-exception handling when Windows
validates exception-continuation addresses. The vectored exception
handler currently resumes directly at a dynamically generated managed
handler; affected processes terminate with
`FAST_FAIL_SET_CONTEXT_DENIED` instead of entering the catch.

Save the resolved managed handler context in existing thread-local
storage and resume first at a native runtime entry point, which restores
that context through Mono's existing restore trampoline. Supply the
Win64 entry-stack alignment and argument home area, and keep the
stack-overflow restoration context separate from the native
continuation. This does not change process mitigation settings or add
general CET support.

Add a three-case theory covering repeated divide-by-zero, overflow, and
null-reference exceptions with nested hardware exceptions in filters and
finally blocks. Restore the Windows x64 MiniJIT runtime-test lane
disabled by dotnet#133747 so this PR exercises the full lane.

Fixes dotnet#133702.

## Validation

- Built Release and Debug Mono on Windows x64.
- `div2_d`, `div2_ro`, `HardwareEh`, `unhandledTester`, and
`ExceptionInterop` pass with both native builds in MiniJIT mode.
- The same final `HardwareEh` binary exits with `0xC0000409` on the
saved unfixed runtime and passes on the fixed Release and Debug
runtimes. Verified that its generated entry point invokes all three new
theory cases. It also passes with the Release interpreter.
- Repeated local explicit-throw measurements overlap within measurement
uncertainty: baseline 2.070 us versus candidate 2.008 us. The unfixed
hardware-throw benchmark terminates, so there is no valid before/after
throughput ratio for that path.
- Verified that `eng/pipelines/runtime.yml` exactly matches its
pre-quarantine version. Full MiniJIT CI and cross-platform suites have
not been run locally.

> [!NOTE]
> This PR was generated with GitHub Copilot.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jtschuster pushed a commit to jtschuster/runtime that referenced this pull request Sep 18, 2026
)

## Summary

This fixes dotnet#133798

Fix the two AOT failures exposed by the expanded `github60486`
regression in dotnet#133707 and observed in CI for
dotnet#133774.

- Preserve callers of the stack-walk implementation of
`MethodBase.GetCurrentMethod` during Mono LLVM inlining. The LLVM-only
intrinsic already prevents inlining; the stack-walk path needs the same
protection. The test's inlineable helper remains unannotated.
- Allow unrelated NativeAOT stack frames to lack reflection metadata. A
local diagnostic run identified `TestEntryPoint` as the frame returning
null from `GetMethod`; all four recursive frames returned valid method
metadata. Keep the exact four-frame assertion and all existing DIM,
exception-stack, caller-identity, and GC-root checks.

Related caller-inlining report: dotnet#60334. Its iOS
configuration was not tested here.

## Validation

Built Checked CoreCLR/NativeAOT and Release Mono with LLVM from a clean
baseline in the same worktree.

| Windows x64 configuration | Before | After |
|---|---|---|
| NativeAOT Checked | Reported null-reference failure | Pass |
| Mono LLVM AOT Release | Expected `GetCurrentMethodInlineable`, actual
`ValidateCurrentMethod` | Pass |
| CoreCLR Checked | Pass | Pass |
| Mono MiniJIT Release | Pass | Pass |

Each run executes the full standalone `github60486` regression. Mono
LLVM AOT comparisons use identical test IL, and runtime logging confirms
the fixed AOT image is loaded. LLVM IR adds `noinline` to the inlineable
and generic wrappers; the optimized caller retains the helper call
instead of inlining it. No performance claim is made.

The Windows Mono LLVM AOT reproduction matches the Linux CI failure
signature. Linux and browser Wasm were not run locally. The Windows x64
JIT formatting check completed successfully.

> [!NOTE]
> This change and pull request description were developed with GitHub
Copilot assistance.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
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.

[Mono][Windows] MiniJIT crashes across unrelated runtime tests with FAST_FAIL_SET_CONTEXT_DENIED

4 participants