Skip to content

[release/11.0] [mono] Preserve arguments across AOT exception filters - #136928

Open
pavelsavara wants to merge 1 commit into
dotnet:release/11.0from
pavelsavara:pr136852-browser-mono-filter-net11
Open

pavelsavara wants to merge 1 commit into
dotnet:release/11.0from
pavelsavara:pr136852-browser-mono-filter-net11

Conversation

@pavelsavara

Copy link
Copy Markdown
Member

Fixes Issue #136780

main PR #136852

Description

Backport the Mono AOT exception-filter argument-corruption fix from #136852.

The AOT-to-interpreter exception bridge used the first argument slot as the filter-result buffer. Returning from a filter overwrote that argument, and argument writeback copied the corrupted value into the suspended AOT frame. Use a separate result slot for filter evaluation while preserving catch/finally result storage and legitimate argument/local writeback.

The automated backport failed on a context conflict in ExceptionTests.cs: main has two unrelated catch-handling tests after the insertion point that are absent from release/11.0. Resolve only that insertion context, retain the release branch's surrounding code, and carry over all ten regression data rows without bringing in those unrelated tests. The native fix is unchanged from main.

Customer Impact

Mono browser-wasm applications published with AOT can read corrupted method arguments after an exception filter runs. This can produce incorrect results or crash when code dereferences a corrupted object argument, for example while disposing a stream from a filtered catch. Plain catches and fully interpreted execution avoid the reported corruption. Frequency depends on application use of exception filters; no prevalence estimate is available.

Regression

Not established as a regression introduced in .NET 11. The original issue reports the failure on .NET 10, and it was also reproduced and fixed on main. This is a targeted reliability/correctness backport rather than a new feature.

Testing

Validated on release/11.0 with a Mono/browser-wasm Debug runtime and Release test app. $root is the backport checkout. Local runs used cached Emscripten through EMSDK_PATH, cached Chrome through CHROME_PATH_FOR_TESTS, and its matching ChromeDriver on PATH; no browser installation was requested.

Clean baseline and fixed runtime/libraries builds: passed, 0 warnings and 0 errors.

.\build.cmd -bl -os browser -subset mono+libs -c Debug /p:RuntimeFlavor=Mono /p:EnableHotReloadInRuntimeConfigDevFile=false

Release test-app symbolicator build: passed, 0 warnings and 0 errors.

.\dotnet.cmd build -bl -c Release /p:TargetOS=browser /p:TargetArchitecture=wasm /p:RuntimeFlavor=Mono .\src\mono\wasm\symbolicator\WasmSymbolicator.csproj

Chrome AOT exception suite: passed, 16/16 tests, including all ten regression data rows.

.\dotnet.cmd build -bl /p:TargetOS=browser /p:TargetArchitecture=wasm /p:RuntimeFlavor=Mono /p:Configuration=Release /p:RuntimeConfiguration=Debug /p:RuntimeConfig=Debug /p:LibrariesConfiguration=Debug /p:TasksConfiguration=Debug "/p:WasmTestRunnerDir=$root\artifacts\bin\WasmTestRunner\Debug\net11.0-browser\" /t:Test /p:RunAOTCompilation=true /p:EnableAggressiveTrimming=true /p:Scenario=WasmTestOnChrome /p:InstallChromeForTests=false /p:EnableHotReloadInRuntimeConfigDevFile=false /p:XUnitClassName=System.Tests.ExceptionTests .\src\libraries\System.Runtime\tests\System.Runtime.Tests\System.Runtime.Tests.csproj

Chrome interpreter exception suite: passed, 18/18 tests. Two existing target-site cases have Mono-AOT exclusions and therefore run only in the interpreter configuration.

.\dotnet.cmd build -bl /p:TargetOS=browser /p:TargetArchitecture=wasm /p:RuntimeFlavor=Mono /p:Configuration=Release /p:RuntimeConfiguration=Debug /p:RuntimeConfig=Debug /p:LibrariesConfiguration=Debug /p:TasksConfiguration=Debug "/p:WasmTestRunnerDir=$root\artifacts\bin\WasmTestRunner\Debug\net11.0-browser\" /t:Test /p:RunAOTCompilation=false /p:EnableAggressiveTrimming=false /p:Scenario=WasmTestOnChrome /p:InstallChromeForTests=false /p:EnableHotReloadInRuntimeConfigDevFile=false /p:XUnitClassName=System.Tests.ExceptionTests .\src\libraries\System.Runtime\tests\System.Runtime.Tests\System.Runtime.Tests.csproj

Cleaned only this test project's browser-wasm bin/obj output directories before switching AOT off, avoiding reuse of IL-stripped staging.

Initial local AOT invocations without EnableAggressiveTrimming=true compiled but failed before executing tests because the runner was not retained in the trimmed app. The successful command above enables the release branch's existing xUnit/runner descriptors; no build-target changes are included in the backport.

Main validation completed before merging #136852: Mono/browser Debug runtime build passed; Chrome AOT exception suite passed 18/18 and interpreter suite passed 20/20. Seven regression cases failed before the fix on main. Other runtime/platform targets were not tested locally.

Risk

Low, but not zero: the native change is limited to the result buffer used when the Mono AOT exception bridge evaluates a filter. It follows the existing interpreter filter path's separate-result-slot pattern. Catch/finally result storage, argument/local writeback, public API, and normal execution paths are unchanged. The backport adds regression coverage for argument/local preservation and argument mutations in both accepted and rejected filters.

Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.

Note

This backport, conflict resolution, and PR description were prepared with GitHub Copilot.

Backport the separate filter-result slot and all ten regression data rows
from the merged main fix. Resolve the exception-test insertion context
without adding unrelated catch-handling tests from main.

(cherry picked from commit 76e0443)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@pavelsavara pavelsavara added Servicing-consider Issue for next servicing release review arch-wasm WebAssembly architecture area-Codegen-AOT-mono os-browser Browser variant of arch-wasm labels Nov 3, 2026
@pavelsavara
pavelsavara deployed to copilot-pat-pool November 3, 2026 17:56 — with GitHub Actions Active
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@pavelsavara
pavelsavara deployed to copilot-pat-pool November 3, 2026 17:56 — with GitHub Actions Active
@azure-pipelines

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

@pavelsavara

Copy link
Copy Markdown
Member Author

/azp run runtime-wasm

@pavelsavara
pavelsavara requested a review from lewing November 3, 2026 19:01
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@pavelsavara

Copy link
Copy Markdown
Member Author

CI assessment

Reviewed runtime build 1662242 and runtime-wasm build 1662313 for head 03a3f82fd98.

Mono AOT coverage validates this backport. In both pipelines, the Linux and Windows AOT System.Runtime.Tests Helix results explicitly show all ten new exception-filter regression cases passing. Each suite reports 77,154 passed, 0 failed, 184 skipped. Browser AOT smoke/high-resource and WASI AOT legs also passed.

The remaining runtime failures are consistent with existing release-branch blockers:

runtime-wasm fails in the multithreading lane, not AOT. Repeated timeouts and HTTP stream failures also occur in the earlier release/11.0 build 1662039. Two additional MT worker-startup/exit-code failures remain unclassified; they have not been proven unrelated. Per Pavel's direction, MT failures are being excluded from the blocking assessment for this backport. The MT System.Runtime.Tests work item itself passed, including all ten new cases.

No change to the AOT fix is indicated by the reviewed results. This is not a claim that every CI failure is matched: Build Analysis is partial, and the MT exceptions above are an explicit scope decision. The separate check-labels gate still requires human servicing approval (Servicing-approved).

Note

This CI assessment was prepared with GitHub Copilot.

@kotlarmilos kotlarmilos added Servicing-approved Approved for servicing release and removed Servicing-consider Issue for next servicing release review labels Nov 4, 2026

This branch was successfully deployed

1 active deployment
copilot-pat-pool — 03a3f82f Deployed Nov 3, 2026 by pavelsavara via conclusion #11669
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch-wasm WebAssembly architecture area-Codegen-AOT-mono os-browser Browser variant of arch-wasm Servicing-approved Approved for servicing release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants