Skip to content

[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks - #131355

Merged
lewing merged 1 commit into
dotnet:mainfrom
lewing:wasm-r2r-crst-nativeimage-eagerfixups
Jul 28, 2026
Merged

[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks#131355
lewing merged 1 commit into
dotnet:mainfrom
lewing:wasm-r2r-crst-nativeimage-eagerfixups

Conversation

@lewing

Copy link
Copy Markdown
Member

The WASM R2R path acquires the NativeImageEagerFixups and PregeneratedStringThunks Crsts without a defined acquisition order between them, which trips a Crst level violation.

Add an AcquiredBefore PregeneratedStringThunks edge to NativeImageEagerFixups in CrstTypes.def so the two locks have a well-defined ordering, and regenerate crsttypes_generated.h (CrstNativeImageEagerFixups level 7 -> 8). Nothing acquires NativeImageEagerFixups before another lock, so the change does not cascade to any other Crst level.

Note

This pull request was authored with assistance from GitHub Copilot.

…nd PregeneratedStringThunks
During a composite R2R load on WebAssembly, the eager-fixup path takes
CrstPregeneratedStringThunks while already holding CrstNativeImageEagerFixups.
Both were assigned the same rank (level 7) because neither declared an ordering
relative to the other, so the nested acquisition trips the Crst level
consistency check ("Can't take level 7 lock ... because you already holding
level 7 lock ...").
Declare NativeImageEagerFixups AcquiredBefore PregeneratedStringThunks in
CrstTypes.def and regenerate crsttypes_generated.h (NativeImageEagerFixups is
now level 8, above PregeneratedStringThunks at 7), making the nested
acquisition well-ordered.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 50ddfb2c-b6f8-4847-81e7-44d37d44a175
@azure-pipelines

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

CopilotAI 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.

Pull request overview

This PR adjusts CoreCLR Crst lock-order metadata to establish a defined ordering between NativeImageEagerFixups and PregeneratedStringThunks, preventing checked-build Crst level violations when both locks are acquired on the WASM R2R path.

Changes:

  • Updates CrstTypes.def to specify NativeImageEagerFixups is acquired before PregeneratedStringThunks (and still before UnresolvedClassLock).
  • Regenerates crsttypes_generated.h, updating CrstNativeImageEagerFixups’s computed level from 7 to 8 to satisfy the new ordering constraint.

Reviewed changes

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

FileDescription
src/coreclr/inc/CrstTypes.defAdds the AcquiredBefore PregeneratedStringThunks dependency for NativeImageEagerFixups to define lock acquisition order.
src/coreclr/inc/crsttypes_generated.hRegenerated Crst level map reflects the new ordering by bumping CrstNativeImageEagerFixups from level 7 to 8.

@lewinglewing added the arch-wasm WebAssembly architecture label Jul 24, 2026
@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.

@lewing

Copy link
Copy Markdown
MemberAuthor

/ba-g arm64 failure is infra

@lewing
lewing merged commit e99b8d4 into dotnet:mainJul 28, 2026
118 of 120 checks passed
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-rc1 milestone Jul 29, 2026
radekdoulik added a commit that referenced this pull request Aug 4, 2026
## Summary
CoreCLR browser-WASM cannot use `fork` or managed process creation, so
runtime
tests marked `RequiresProcessIsolation` were omitted from merged
runners. This
PR enables those tests without adding Node-specific process APIs to
managed
runtime code:
- the merged runner emits a plan using its existing filtering and
striping;
- the host Bash or Batch script executes each existing per-test wrapper
in a
fresh child shell;
- the merged runner imports the child results into its normal xUnit
report.
The PR also includes the runtime-test infrastructure, platform gating,
and
focused runtime/test fixes needed to make priority-0 and priority-1
CoreCLR
browser-WASM coverage pass consistently.
This reuses the existing CoreCLR `corerun` wrappers; it does not
introduce a
parallel `browserhost` scheduler or duplicate per-test execution
semantics.
## Execution model
The browser run has three phases:
1. **Plan:** the generated merged runner writes the selected
out-of-process
assembly paths.
2. **Execute:** the host runs each existing `.sh` or `.cmd` wrapper and
records
its output, exit code, pass/skip state, and skip reason.
3. **Import:** the normal merged run executes in-process tests and
reports the
precomputed child outcomes through the existing xUnit summary.
Existing wrappers remain authoritative for test arguments, environment
variables, pre/post commands, expected exit codes, and per-test
timeouts.
Merged-runner arguments and stripe state are cleared while child
wrappers run
and restored afterward.
The result format is versioned and bound to a per-run token. Missing
plans,
wrappers, results, malformed records, or stale tokens fail as
infrastructure
errors. A child in which every test is skipped is reported as skipped
rather
than passed. Empty plan/status environment settings are treated as
unset.
The host orchestration marker is emitted only for CoreCLR browser-WASM
merged
runners that contain out-of-process tests.
## Browser-WASM enablement and fixes
- **Discovery:** only buildable projects with runnable wrappers are
added to
merged-runner OOP plans.
- **Interpreter:** `InterpreterTester` runs `Interpreter.dll` directly
through
the host OOP path with the required interpreter environment instead of
calling `Process.Start` inside the browser.
- **ReadyToRun assets:** host Crossgen2 assets are staged for
cross-architecture runs, and emitted WASM components, including
composite
output, are validated.
- **Composite ReadyToRun tests:** affected CoreCLR browser tests carry
an
ActiveIssue for
[#131767](#131767). Their
browser
projects do not force Crossgen2, allowing the managed wrapper to report
the
skip before CoreCLR probes the unsupported composite WebCIL layout.
Other
targets retain their existing composite R2R coverage.
- **Host paths:** Batch orchestration retains Windows paths for host
file
operations while exposing Unix-style absolute paths to browser managed
code.
- **Multithreading:** `FeatureMultithreading` is available during test
project
evaluation. Tests whose only requirement is managed multithreading use
that
global capability, so they remain excluded on single-threaded targets
and
become buildable when threads are enabled.
- **Precise platform scope:** tests requiring background/server GC,
native
threads, child processes, unsupported browser APIs, mutable host
filesystem
behavior, or impractical interpreter workloads are gated or excluded at
the
narrowest applicable level.
- **Shutdown lifecycle:** the CoreCLR browser shutdown wrapper is
installed
from Emscripten `preRun`, after native exports are bound, so explicit
`Environment.Exit` values are preserved and no finalization work is
scheduled while the runtime exits.
- **Background GC information test:** the browser CoreCLR
`GetGCMemoryInfo` test carries an ActiveIssue for
[#131766](#131766), which tracks
the
assertion from requesting `GCKind.Background` when background GC is not
compiled. This PR does not change the product behavior.
- **Test assumptions:** focused adaptations remove incidental process,
threading, filesystem, and host-tool assumptions while preserving the
behavior each test is intended to cover.
- **Post-merge CI coverage:** build 1528104 exposed 30 deterministic OOP
failures after newer `main` changes activated more browser scenarios.
The
eager-fixup lock-order failure is fixed on `main` by
[#131355](#131355). Composite
WebCIL
loading and background-GC information remain tracked separately by
#131767
and #131766. The `Int128` field-layout correctness fix is proceeding in
[#131421](#131421); other
unsupported
cases are gated only for CoreCLR browser-WASM with explicit re-enable
prerequisites.
No shipping public API is added.
## Deferred scope
Per-test native assets, UCO thunk generation, and native relinking are
intentionally deferred. Tests that need them remain guarded by their
existing
tracking issues.
The remaining non-multithreading/non-relinking exclusions were audited:
41 represent recoverable coverage and 16 exercise browser-inapplicable
contracts. The recoverable set and its prerequisites are tracked by
[#131321](#131321), with links
from each
suppression site. The newly exposed native-relinking test remains
tracked by
[#123946](#123946).
## Validation
The following complete-suite results were recorded before the two
product fixes
were moved to their dedicated tracking issues:
| CoreCLR browser-WASM run | Total | Passed | Skipped | Failed |
| --- | ---: | ---: | ---: | ---: |
| Priority 0 after the `main` merge | 3,970 | 3,412 | 558 | 0 |
| Priority 0 OOP subset | 485 | 408 | 77 | 0 |
| Earlier full priority 0+1 validation | 14,726 | 13,850 | 876 | 0 |
| Earlier priority 0+1 OOP subset | 740 | 651 | 89 | 0 |
Current-head validation after removing those fixes:
- rebuilt the Checked CoreCLR browser-WASM runtime and libraries with
zero
warnings or errors;
- cleanly built all ten affected browser test projects;
- ran all ten generated wrappers against the unfixed runtime: every
wrapper
exited with the expected status and reported #131766 or #131767 through
the
OOP skip-status protocol, without either runtime assertion;
- verified that the shared non-R2R browser `BasicTest` remains enabled;
- verified on macOS that the R2R variant still forces Crossgen2, emits
and
validates its composite image, and passes.
Additional earlier validation:
- composite and non-composite WASM ReadyToRun output;
- native `NativeLibraryTests` asset staging;
- plan/import success, failure, filtering, striping,
stale/malformed/missing
records, environment-sensitive wrappers, and all-skipped children;
- unset, empty, and non-empty plan/status environment settings;
- direct browser-WASM `InterpreterTester` execution under Node;
- generated Bash syntax and generated Batch structure/path conversion;
- Checked browser runtime rebuild plus a fresh priority-0 payload and
test
layout after the `main` merge;
- all 22 new gates across CoreCLR browser, WASI, desktop, and Mono
browser
evaluations, preserving the pre-existing Mono ReadyToRun exclusions;
- the complete 72-runner Node run, including the ReadyToRun, base
services,
JIT, Loader, and tracing work items that failed in build 1528104.
| Representative CoreCLR browser library suite | Total | Passed |
Skipped | Failed |
| --- | ---: | ---: | ---: | ---: |
| `System.Threading.Timer.Tests` | 33 | 16 | 17 | 0 |
| `System.Runtime.InteropServices.JavaScript.Tests` | 476 | 474 | 2 | 0
|
| `System.Reflection.Emit.Tests` (Debug) | 2,028 | 2,017 | 11 | 0 |
| `System.Runtime.Tests` (Debug) | 75,726 | 75,559 | 167 | 0 |
The generated Batch path has been inspected and generated successfully
but
still requires execution on Windows CI.
> [!NOTE]
> This pull request description was updated with GitHub Copilot.
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 29, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-VM-coreclr

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@lewing@davidwrighton
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks by lewing · Pull Request #131355 · dotnet/runtime · GitHub
Skip to content

[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks - #131355

Merged
lewing merged 1 commit into
dotnet:mainfrom
lewing:wasm-r2r-crst-nativeimage-eagerfixups
Jul 28, 2026
Merged

[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks#131355
lewing merged 1 commit into
dotnet:mainfrom
lewing:wasm-r2r-crst-nativeimage-eagerfixups

Conversation

@lewing

Copy link
Copy Markdown
Member

The WASM R2R path acquires the NativeImageEagerFixups and PregeneratedStringThunks Crsts without a defined acquisition order between them, which trips a Crst level violation.

Add an AcquiredBefore PregeneratedStringThunks edge to NativeImageEagerFixups in CrstTypes.def so the two locks have a well-defined ordering, and regenerate crsttypes_generated.h (CrstNativeImageEagerFixups level 7 -> 8). Nothing acquires NativeImageEagerFixups before another lock, so the change does not cascade to any other Crst level.

Note

This pull request was authored with assistance from GitHub Copilot.

…nd PregeneratedStringThunks
During a composite R2R load on WebAssembly, the eager-fixup path takes
CrstPregeneratedStringThunks while already holding CrstNativeImageEagerFixups.
Both were assigned the same rank (level 7) because neither declared an ordering
relative to the other, so the nested acquisition trips the Crst level
consistency check ("Can't take level 7 lock ... because you already holding
level 7 lock ...").
Declare NativeImageEagerFixups AcquiredBefore PregeneratedStringThunks in
CrstTypes.def and regenerate crsttypes_generated.h (NativeImageEagerFixups is
now level 8, above PregeneratedStringThunks at 7), making the nested
acquisition well-ordered.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 50ddfb2c-b6f8-4847-81e7-44d37d44a175
@azure-pipelines

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

CopilotAI 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.

Pull request overview

This PR adjusts CoreCLR Crst lock-order metadata to establish a defined ordering between NativeImageEagerFixups and PregeneratedStringThunks, preventing checked-build Crst level violations when both locks are acquired on the WASM R2R path.

Changes:

  • Updates CrstTypes.def to specify NativeImageEagerFixups is acquired before PregeneratedStringThunks (and still before UnresolvedClassLock).
  • Regenerates crsttypes_generated.h, updating CrstNativeImageEagerFixups’s computed level from 7 to 8 to satisfy the new ordering constraint.

Reviewed changes

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

FileDescription
src/coreclr/inc/CrstTypes.defAdds the AcquiredBefore PregeneratedStringThunks dependency for NativeImageEagerFixups to define lock acquisition order.
src/coreclr/inc/crsttypes_generated.hRegenerated Crst level map reflects the new ordering by bumping CrstNativeImageEagerFixups from level 7 to 8.

@lewinglewing added the arch-wasm WebAssembly architecture label Jul 24, 2026
@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.

@lewing

Copy link
Copy Markdown
MemberAuthor

/ba-g arm64 failure is infra

@lewing
lewing merged commit e99b8d4 into dotnet:mainJul 28, 2026
118 of 120 checks passed
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-rc1 milestone Jul 29, 2026
radekdoulik added a commit that referenced this pull request Aug 4, 2026
## Summary
CoreCLR browser-WASM cannot use `fork` or managed process creation, so
runtime
tests marked `RequiresProcessIsolation` were omitted from merged
runners. This
PR enables those tests without adding Node-specific process APIs to
managed
runtime code:
- the merged runner emits a plan using its existing filtering and
striping;
- the host Bash or Batch script executes each existing per-test wrapper
in a
fresh child shell;
- the merged runner imports the child results into its normal xUnit
report.
The PR also includes the runtime-test infrastructure, platform gating,
and
focused runtime/test fixes needed to make priority-0 and priority-1
CoreCLR
browser-WASM coverage pass consistently.
This reuses the existing CoreCLR `corerun` wrappers; it does not
introduce a
parallel `browserhost` scheduler or duplicate per-test execution
semantics.
## Execution model
The browser run has three phases:
1. **Plan:** the generated merged runner writes the selected
out-of-process
assembly paths.
2. **Execute:** the host runs each existing `.sh` or `.cmd` wrapper and
records
its output, exit code, pass/skip state, and skip reason.
3. **Import:** the normal merged run executes in-process tests and
reports the
precomputed child outcomes through the existing xUnit summary.
Existing wrappers remain authoritative for test arguments, environment
variables, pre/post commands, expected exit codes, and per-test
timeouts.
Merged-runner arguments and stripe state are cleared while child
wrappers run
and restored afterward.
The result format is versioned and bound to a per-run token. Missing
plans,
wrappers, results, malformed records, or stale tokens fail as
infrastructure
errors. A child in which every test is skipped is reported as skipped
rather
than passed. Empty plan/status environment settings are treated as
unset.
The host orchestration marker is emitted only for CoreCLR browser-WASM
merged
runners that contain out-of-process tests.
## Browser-WASM enablement and fixes
- **Discovery:** only buildable projects with runnable wrappers are
added to
merged-runner OOP plans.
- **Interpreter:** `InterpreterTester` runs `Interpreter.dll` directly
through
the host OOP path with the required interpreter environment instead of
calling `Process.Start` inside the browser.
- **ReadyToRun assets:** host Crossgen2 assets are staged for
cross-architecture runs, and emitted WASM components, including
composite
output, are validated.
- **Composite ReadyToRun tests:** affected CoreCLR browser tests carry
an
ActiveIssue for
[#131767](#131767). Their
browser
projects do not force Crossgen2, allowing the managed wrapper to report
the
skip before CoreCLR probes the unsupported composite WebCIL layout.
Other
targets retain their existing composite R2R coverage.
- **Host paths:** Batch orchestration retains Windows paths for host
file
operations while exposing Unix-style absolute paths to browser managed
code.
- **Multithreading:** `FeatureMultithreading` is available during test
project
evaluation. Tests whose only requirement is managed multithreading use
that
global capability, so they remain excluded on single-threaded targets
and
become buildable when threads are enabled.
- **Precise platform scope:** tests requiring background/server GC,
native
threads, child processes, unsupported browser APIs, mutable host
filesystem
behavior, or impractical interpreter workloads are gated or excluded at
the
narrowest applicable level.
- **Shutdown lifecycle:** the CoreCLR browser shutdown wrapper is
installed
from Emscripten `preRun`, after native exports are bound, so explicit
`Environment.Exit` values are preserved and no finalization work is
scheduled while the runtime exits.
- **Background GC information test:** the browser CoreCLR
`GetGCMemoryInfo` test carries an ActiveIssue for
[#131766](#131766), which tracks
the
assertion from requesting `GCKind.Background` when background GC is not
compiled. This PR does not change the product behavior.
- **Test assumptions:** focused adaptations remove incidental process,
threading, filesystem, and host-tool assumptions while preserving the
behavior each test is intended to cover.
- **Post-merge CI coverage:** build 1528104 exposed 30 deterministic OOP
failures after newer `main` changes activated more browser scenarios.
The
eager-fixup lock-order failure is fixed on `main` by
[#131355](#131355). Composite
WebCIL
loading and background-GC information remain tracked separately by
#131767
and #131766. The `Int128` field-layout correctness fix is proceeding in
[#131421](#131421); other
unsupported
cases are gated only for CoreCLR browser-WASM with explicit re-enable
prerequisites.
No shipping public API is added.
## Deferred scope
Per-test native assets, UCO thunk generation, and native relinking are
intentionally deferred. Tests that need them remain guarded by their
existing
tracking issues.
The remaining non-multithreading/non-relinking exclusions were audited:
41 represent recoverable coverage and 16 exercise browser-inapplicable
contracts. The recoverable set and its prerequisites are tracked by
[#131321](#131321), with links
from each
suppression site. The newly exposed native-relinking test remains
tracked by
[#123946](#123946).
## Validation
The following complete-suite results were recorded before the two
product fixes
were moved to their dedicated tracking issues:
| CoreCLR browser-WASM run | Total | Passed | Skipped | Failed |
| --- | ---: | ---: | ---: | ---: |
| Priority 0 after the `main` merge | 3,970 | 3,412 | 558 | 0 |
| Priority 0 OOP subset | 485 | 408 | 77 | 0 |
| Earlier full priority 0+1 validation | 14,726 | 13,850 | 876 | 0 |
| Earlier priority 0+1 OOP subset | 740 | 651 | 89 | 0 |
Current-head validation after removing those fixes:
- rebuilt the Checked CoreCLR browser-WASM runtime and libraries with
zero
warnings or errors;
- cleanly built all ten affected browser test projects;
- ran all ten generated wrappers against the unfixed runtime: every
wrapper
exited with the expected status and reported #131766 or #131767 through
the
OOP skip-status protocol, without either runtime assertion;
- verified that the shared non-R2R browser `BasicTest` remains enabled;
- verified on macOS that the R2R variant still forces Crossgen2, emits
and
validates its composite image, and passes.
Additional earlier validation:
- composite and non-composite WASM ReadyToRun output;
- native `NativeLibraryTests` asset staging;
- plan/import success, failure, filtering, striping,
stale/malformed/missing
records, environment-sensitive wrappers, and all-skipped children;
- unset, empty, and non-empty plan/status environment settings;
- direct browser-WASM `InterpreterTester` execution under Node;
- generated Bash syntax and generated Batch structure/path conversion;
- Checked browser runtime rebuild plus a fresh priority-0 payload and
test
layout after the `main` merge;
- all 22 new gates across CoreCLR browser, WASI, desktop, and Mono
browser
evaluations, preserving the pre-existing Mono ReadyToRun exclusions;
- the complete 72-runner Node run, including the ReadyToRun, base
services,
JIT, Loader, and tracing work items that failed in build 1528104.
| Representative CoreCLR browser library suite | Total | Passed |
Skipped | Failed |
| --- | ---: | ---: | ---: | ---: |
| `System.Threading.Timer.Tests` | 33 | 16 | 17 | 0 |
| `System.Runtime.InteropServices.JavaScript.Tests` | 476 | 474 | 2 | 0
|
| `System.Reflection.Emit.Tests` (Debug) | 2,028 | 2,017 | 11 | 0 |
| `System.Runtime.Tests` (Debug) | 75,726 | 75,559 | 167 | 0 |
The generated Batch path has been inspected and generated successfully
but
still requires execution on Windows CI.
> [!NOTE]
> This pull request description was updated with GitHub Copilot.
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 29, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-VM-coreclr

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@lewing@davidwrighton
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks by lewing · Pull Request #131355 · dotnet/runtime · GitHub
Skip to content

[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks - #131355

Merged
lewing merged 1 commit into
dotnet:mainfrom
lewing:wasm-r2r-crst-nativeimage-eagerfixups
Jul 28, 2026
Merged

[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks#131355
lewing merged 1 commit into
dotnet:mainfrom
lewing:wasm-r2r-crst-nativeimage-eagerfixups

Conversation

@lewing

Copy link
Copy Markdown
Member

The WASM R2R path acquires the NativeImageEagerFixups and PregeneratedStringThunks Crsts without a defined acquisition order between them, which trips a Crst level violation.

Add an AcquiredBefore PregeneratedStringThunks edge to NativeImageEagerFixups in CrstTypes.def so the two locks have a well-defined ordering, and regenerate crsttypes_generated.h (CrstNativeImageEagerFixups level 7 -> 8). Nothing acquires NativeImageEagerFixups before another lock, so the change does not cascade to any other Crst level.

Note

This pull request was authored with assistance from GitHub Copilot.

…nd PregeneratedStringThunks
During a composite R2R load on WebAssembly, the eager-fixup path takes
CrstPregeneratedStringThunks while already holding CrstNativeImageEagerFixups.
Both were assigned the same rank (level 7) because neither declared an ordering
relative to the other, so the nested acquisition trips the Crst level
consistency check ("Can't take level 7 lock ... because you already holding
level 7 lock ...").
Declare NativeImageEagerFixups AcquiredBefore PregeneratedStringThunks in
CrstTypes.def and regenerate crsttypes_generated.h (NativeImageEagerFixups is
now level 8, above PregeneratedStringThunks at 7), making the nested
acquisition well-ordered.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 50ddfb2c-b6f8-4847-81e7-44d37d44a175
@azure-pipelines

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

CopilotAI 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.

Pull request overview

This PR adjusts CoreCLR Crst lock-order metadata to establish a defined ordering between NativeImageEagerFixups and PregeneratedStringThunks, preventing checked-build Crst level violations when both locks are acquired on the WASM R2R path.

Changes:

  • Updates CrstTypes.def to specify NativeImageEagerFixups is acquired before PregeneratedStringThunks (and still before UnresolvedClassLock).
  • Regenerates crsttypes_generated.h, updating CrstNativeImageEagerFixups’s computed level from 7 to 8 to satisfy the new ordering constraint.

Reviewed changes

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

FileDescription
src/coreclr/inc/CrstTypes.defAdds the AcquiredBefore PregeneratedStringThunks dependency for NativeImageEagerFixups to define lock acquisition order.
src/coreclr/inc/crsttypes_generated.hRegenerated Crst level map reflects the new ordering by bumping CrstNativeImageEagerFixups from level 7 to 8.

@lewinglewing added the arch-wasm WebAssembly architecture label Jul 24, 2026
@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.

@lewing

Copy link
Copy Markdown
MemberAuthor

/ba-g arm64 failure is infra

@lewing
lewing merged commit e99b8d4 into dotnet:mainJul 28, 2026
118 of 120 checks passed
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-rc1 milestone Jul 29, 2026
radekdoulik added a commit that referenced this pull request Aug 4, 2026
## Summary
CoreCLR browser-WASM cannot use `fork` or managed process creation, so
runtime
tests marked `RequiresProcessIsolation` were omitted from merged
runners. This
PR enables those tests without adding Node-specific process APIs to
managed
runtime code:
- the merged runner emits a plan using its existing filtering and
striping;
- the host Bash or Batch script executes each existing per-test wrapper
in a
fresh child shell;
- the merged runner imports the child results into its normal xUnit
report.
The PR also includes the runtime-test infrastructure, platform gating,
and
focused runtime/test fixes needed to make priority-0 and priority-1
CoreCLR
browser-WASM coverage pass consistently.
This reuses the existing CoreCLR `corerun` wrappers; it does not
introduce a
parallel `browserhost` scheduler or duplicate per-test execution
semantics.
## Execution model
The browser run has three phases:
1. **Plan:** the generated merged runner writes the selected
out-of-process
assembly paths.
2. **Execute:** the host runs each existing `.sh` or `.cmd` wrapper and
records
its output, exit code, pass/skip state, and skip reason.
3. **Import:** the normal merged run executes in-process tests and
reports the
precomputed child outcomes through the existing xUnit summary.
Existing wrappers remain authoritative for test arguments, environment
variables, pre/post commands, expected exit codes, and per-test
timeouts.
Merged-runner arguments and stripe state are cleared while child
wrappers run
and restored afterward.
The result format is versioned and bound to a per-run token. Missing
plans,
wrappers, results, malformed records, or stale tokens fail as
infrastructure
errors. A child in which every test is skipped is reported as skipped
rather
than passed. Empty plan/status environment settings are treated as
unset.
The host orchestration marker is emitted only for CoreCLR browser-WASM
merged
runners that contain out-of-process tests.
## Browser-WASM enablement and fixes
- **Discovery:** only buildable projects with runnable wrappers are
added to
merged-runner OOP plans.
- **Interpreter:** `InterpreterTester` runs `Interpreter.dll` directly
through
the host OOP path with the required interpreter environment instead of
calling `Process.Start` inside the browser.
- **ReadyToRun assets:** host Crossgen2 assets are staged for
cross-architecture runs, and emitted WASM components, including
composite
output, are validated.
- **Composite ReadyToRun tests:** affected CoreCLR browser tests carry
an
ActiveIssue for
[#131767](#131767). Their
browser
projects do not force Crossgen2, allowing the managed wrapper to report
the
skip before CoreCLR probes the unsupported composite WebCIL layout.
Other
targets retain their existing composite R2R coverage.
- **Host paths:** Batch orchestration retains Windows paths for host
file
operations while exposing Unix-style absolute paths to browser managed
code.
- **Multithreading:** `FeatureMultithreading` is available during test
project
evaluation. Tests whose only requirement is managed multithreading use
that
global capability, so they remain excluded on single-threaded targets
and
become buildable when threads are enabled.
- **Precise platform scope:** tests requiring background/server GC,
native
threads, child processes, unsupported browser APIs, mutable host
filesystem
behavior, or impractical interpreter workloads are gated or excluded at
the
narrowest applicable level.
- **Shutdown lifecycle:** the CoreCLR browser shutdown wrapper is
installed
from Emscripten `preRun`, after native exports are bound, so explicit
`Environment.Exit` values are preserved and no finalization work is
scheduled while the runtime exits.
- **Background GC information test:** the browser CoreCLR
`GetGCMemoryInfo` test carries an ActiveIssue for
[#131766](#131766), which tracks
the
assertion from requesting `GCKind.Background` when background GC is not
compiled. This PR does not change the product behavior.
- **Test assumptions:** focused adaptations remove incidental process,
threading, filesystem, and host-tool assumptions while preserving the
behavior each test is intended to cover.
- **Post-merge CI coverage:** build 1528104 exposed 30 deterministic OOP
failures after newer `main` changes activated more browser scenarios.
The
eager-fixup lock-order failure is fixed on `main` by
[#131355](#131355). Composite
WebCIL
loading and background-GC information remain tracked separately by
#131767
and #131766. The `Int128` field-layout correctness fix is proceeding in
[#131421](#131421); other
unsupported
cases are gated only for CoreCLR browser-WASM with explicit re-enable
prerequisites.
No shipping public API is added.
## Deferred scope
Per-test native assets, UCO thunk generation, and native relinking are
intentionally deferred. Tests that need them remain guarded by their
existing
tracking issues.
The remaining non-multithreading/non-relinking exclusions were audited:
41 represent recoverable coverage and 16 exercise browser-inapplicable
contracts. The recoverable set and its prerequisites are tracked by
[#131321](#131321), with links
from each
suppression site. The newly exposed native-relinking test remains
tracked by
[#123946](#123946).
## Validation
The following complete-suite results were recorded before the two
product fixes
were moved to their dedicated tracking issues:
| CoreCLR browser-WASM run | Total | Passed | Skipped | Failed |
| --- | ---: | ---: | ---: | ---: |
| Priority 0 after the `main` merge | 3,970 | 3,412 | 558 | 0 |
| Priority 0 OOP subset | 485 | 408 | 77 | 0 |
| Earlier full priority 0+1 validation | 14,726 | 13,850 | 876 | 0 |
| Earlier priority 0+1 OOP subset | 740 | 651 | 89 | 0 |
Current-head validation after removing those fixes:
- rebuilt the Checked CoreCLR browser-WASM runtime and libraries with
zero
warnings or errors;
- cleanly built all ten affected browser test projects;
- ran all ten generated wrappers against the unfixed runtime: every
wrapper
exited with the expected status and reported #131766 or #131767 through
the
OOP skip-status protocol, without either runtime assertion;
- verified that the shared non-R2R browser `BasicTest` remains enabled;
- verified on macOS that the R2R variant still forces Crossgen2, emits
and
validates its composite image, and passes.
Additional earlier validation:
- composite and non-composite WASM ReadyToRun output;
- native `NativeLibraryTests` asset staging;
- plan/import success, failure, filtering, striping,
stale/malformed/missing
records, environment-sensitive wrappers, and all-skipped children;
- unset, empty, and non-empty plan/status environment settings;
- direct browser-WASM `InterpreterTester` execution under Node;
- generated Bash syntax and generated Batch structure/path conversion;
- Checked browser runtime rebuild plus a fresh priority-0 payload and
test
layout after the `main` merge;
- all 22 new gates across CoreCLR browser, WASI, desktop, and Mono
browser
evaluations, preserving the pre-existing Mono ReadyToRun exclusions;
- the complete 72-runner Node run, including the ReadyToRun, base
services,
JIT, Loader, and tracing work items that failed in build 1528104.
| Representative CoreCLR browser library suite | Total | Passed |
Skipped | Failed |
| --- | ---: | ---: | ---: | ---: |
| `System.Threading.Timer.Tests` | 33 | 16 | 17 | 0 |
| `System.Runtime.InteropServices.JavaScript.Tests` | 476 | 474 | 2 | 0
|
| `System.Reflection.Emit.Tests` (Debug) | 2,028 | 2,017 | 11 | 0 |
| `System.Runtime.Tests` (Debug) | 75,726 | 75,559 | 167 | 0 |
The generated Batch path has been inspected and generated successfully
but
still requires execution on Windows CI.
> [!NOTE]
> This pull request description was updated with GitHub Copilot.
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 29, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-VM-coreclr

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@lewing@davidwrighton
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks by lewing · Pull Request #131355 · dotnet/runtime · GitHub
Skip to content

[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks - #131355

Merged
lewing merged 1 commit into
dotnet:mainfrom
lewing:wasm-r2r-crst-nativeimage-eagerfixups
Jul 28, 2026
Merged

[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks#131355
lewing merged 1 commit into
dotnet:mainfrom
lewing:wasm-r2r-crst-nativeimage-eagerfixups

Conversation

@lewing

Copy link
Copy Markdown
Member

The WASM R2R path acquires the NativeImageEagerFixups and PregeneratedStringThunks Crsts without a defined acquisition order between them, which trips a Crst level violation.

Add an AcquiredBefore PregeneratedStringThunks edge to NativeImageEagerFixups in CrstTypes.def so the two locks have a well-defined ordering, and regenerate crsttypes_generated.h (CrstNativeImageEagerFixups level 7 -> 8). Nothing acquires NativeImageEagerFixups before another lock, so the change does not cascade to any other Crst level.

Note

This pull request was authored with assistance from GitHub Copilot.

…nd PregeneratedStringThunks
During a composite R2R load on WebAssembly, the eager-fixup path takes
CrstPregeneratedStringThunks while already holding CrstNativeImageEagerFixups.
Both were assigned the same rank (level 7) because neither declared an ordering
relative to the other, so the nested acquisition trips the Crst level
consistency check ("Can't take level 7 lock ... because you already holding
level 7 lock ...").
Declare NativeImageEagerFixups AcquiredBefore PregeneratedStringThunks in
CrstTypes.def and regenerate crsttypes_generated.h (NativeImageEagerFixups is
now level 8, above PregeneratedStringThunks at 7), making the nested
acquisition well-ordered.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 50ddfb2c-b6f8-4847-81e7-44d37d44a175
@azure-pipelines

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

CopilotAI 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.

Pull request overview

This PR adjusts CoreCLR Crst lock-order metadata to establish a defined ordering between NativeImageEagerFixups and PregeneratedStringThunks, preventing checked-build Crst level violations when both locks are acquired on the WASM R2R path.

Changes:

  • Updates CrstTypes.def to specify NativeImageEagerFixups is acquired before PregeneratedStringThunks (and still before UnresolvedClassLock).
  • Regenerates crsttypes_generated.h, updating CrstNativeImageEagerFixups’s computed level from 7 to 8 to satisfy the new ordering constraint.

Reviewed changes

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

FileDescription
src/coreclr/inc/CrstTypes.defAdds the AcquiredBefore PregeneratedStringThunks dependency for NativeImageEagerFixups to define lock acquisition order.
src/coreclr/inc/crsttypes_generated.hRegenerated Crst level map reflects the new ordering by bumping CrstNativeImageEagerFixups from level 7 to 8.

@lewinglewing added the arch-wasm WebAssembly architecture label Jul 24, 2026
@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.

@lewing

Copy link
Copy Markdown
MemberAuthor

/ba-g arm64 failure is infra

@lewing
lewing merged commit e99b8d4 into dotnet:mainJul 28, 2026
118 of 120 checks passed
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-rc1 milestone Jul 29, 2026
radekdoulik added a commit that referenced this pull request Aug 4, 2026
## Summary
CoreCLR browser-WASM cannot use `fork` or managed process creation, so
runtime
tests marked `RequiresProcessIsolation` were omitted from merged
runners. This
PR enables those tests without adding Node-specific process APIs to
managed
runtime code:
- the merged runner emits a plan using its existing filtering and
striping;
- the host Bash or Batch script executes each existing per-test wrapper
in a
fresh child shell;
- the merged runner imports the child results into its normal xUnit
report.
The PR also includes the runtime-test infrastructure, platform gating,
and
focused runtime/test fixes needed to make priority-0 and priority-1
CoreCLR
browser-WASM coverage pass consistently.
This reuses the existing CoreCLR `corerun` wrappers; it does not
introduce a
parallel `browserhost` scheduler or duplicate per-test execution
semantics.
## Execution model
The browser run has three phases:
1. **Plan:** the generated merged runner writes the selected
out-of-process
assembly paths.
2. **Execute:** the host runs each existing `.sh` or `.cmd` wrapper and
records
its output, exit code, pass/skip state, and skip reason.
3. **Import:** the normal merged run executes in-process tests and
reports the
precomputed child outcomes through the existing xUnit summary.
Existing wrappers remain authoritative for test arguments, environment
variables, pre/post commands, expected exit codes, and per-test
timeouts.
Merged-runner arguments and stripe state are cleared while child
wrappers run
and restored afterward.
The result format is versioned and bound to a per-run token. Missing
plans,
wrappers, results, malformed records, or stale tokens fail as
infrastructure
errors. A child in which every test is skipped is reported as skipped
rather
than passed. Empty plan/status environment settings are treated as
unset.
The host orchestration marker is emitted only for CoreCLR browser-WASM
merged
runners that contain out-of-process tests.
## Browser-WASM enablement and fixes
- **Discovery:** only buildable projects with runnable wrappers are
added to
merged-runner OOP plans.
- **Interpreter:** `InterpreterTester` runs `Interpreter.dll` directly
through
the host OOP path with the required interpreter environment instead of
calling `Process.Start` inside the browser.
- **ReadyToRun assets:** host Crossgen2 assets are staged for
cross-architecture runs, and emitted WASM components, including
composite
output, are validated.
- **Composite ReadyToRun tests:** affected CoreCLR browser tests carry
an
ActiveIssue for
[#131767](#131767). Their
browser
projects do not force Crossgen2, allowing the managed wrapper to report
the
skip before CoreCLR probes the unsupported composite WebCIL layout.
Other
targets retain their existing composite R2R coverage.
- **Host paths:** Batch orchestration retains Windows paths for host
file
operations while exposing Unix-style absolute paths to browser managed
code.
- **Multithreading:** `FeatureMultithreading` is available during test
project
evaluation. Tests whose only requirement is managed multithreading use
that
global capability, so they remain excluded on single-threaded targets
and
become buildable when threads are enabled.
- **Precise platform scope:** tests requiring background/server GC,
native
threads, child processes, unsupported browser APIs, mutable host
filesystem
behavior, or impractical interpreter workloads are gated or excluded at
the
narrowest applicable level.
- **Shutdown lifecycle:** the CoreCLR browser shutdown wrapper is
installed
from Emscripten `preRun`, after native exports are bound, so explicit
`Environment.Exit` values are preserved and no finalization work is
scheduled while the runtime exits.
- **Background GC information test:** the browser CoreCLR
`GetGCMemoryInfo` test carries an ActiveIssue for
[#131766](#131766), which tracks
the
assertion from requesting `GCKind.Background` when background GC is not
compiled. This PR does not change the product behavior.
- **Test assumptions:** focused adaptations remove incidental process,
threading, filesystem, and host-tool assumptions while preserving the
behavior each test is intended to cover.
- **Post-merge CI coverage:** build 1528104 exposed 30 deterministic OOP
failures after newer `main` changes activated more browser scenarios.
The
eager-fixup lock-order failure is fixed on `main` by
[#131355](#131355). Composite
WebCIL
loading and background-GC information remain tracked separately by
#131767
and #131766. The `Int128` field-layout correctness fix is proceeding in
[#131421](#131421); other
unsupported
cases are gated only for CoreCLR browser-WASM with explicit re-enable
prerequisites.
No shipping public API is added.
## Deferred scope
Per-test native assets, UCO thunk generation, and native relinking are
intentionally deferred. Tests that need them remain guarded by their
existing
tracking issues.
The remaining non-multithreading/non-relinking exclusions were audited:
41 represent recoverable coverage and 16 exercise browser-inapplicable
contracts. The recoverable set and its prerequisites are tracked by
[#131321](#131321), with links
from each
suppression site. The newly exposed native-relinking test remains
tracked by
[#123946](#123946).
## Validation
The following complete-suite results were recorded before the two
product fixes
were moved to their dedicated tracking issues:
| CoreCLR browser-WASM run | Total | Passed | Skipped | Failed |
| --- | ---: | ---: | ---: | ---: |
| Priority 0 after the `main` merge | 3,970 | 3,412 | 558 | 0 |
| Priority 0 OOP subset | 485 | 408 | 77 | 0 |
| Earlier full priority 0+1 validation | 14,726 | 13,850 | 876 | 0 |
| Earlier priority 0+1 OOP subset | 740 | 651 | 89 | 0 |
Current-head validation after removing those fixes:
- rebuilt the Checked CoreCLR browser-WASM runtime and libraries with
zero
warnings or errors;
- cleanly built all ten affected browser test projects;
- ran all ten generated wrappers against the unfixed runtime: every
wrapper
exited with the expected status and reported #131766 or #131767 through
the
OOP skip-status protocol, without either runtime assertion;
- verified that the shared non-R2R browser `BasicTest` remains enabled;
- verified on macOS that the R2R variant still forces Crossgen2, emits
and
validates its composite image, and passes.
Additional earlier validation:
- composite and non-composite WASM ReadyToRun output;
- native `NativeLibraryTests` asset staging;
- plan/import success, failure, filtering, striping,
stale/malformed/missing
records, environment-sensitive wrappers, and all-skipped children;
- unset, empty, and non-empty plan/status environment settings;
- direct browser-WASM `InterpreterTester` execution under Node;
- generated Bash syntax and generated Batch structure/path conversion;
- Checked browser runtime rebuild plus a fresh priority-0 payload and
test
layout after the `main` merge;
- all 22 new gates across CoreCLR browser, WASI, desktop, and Mono
browser
evaluations, preserving the pre-existing Mono ReadyToRun exclusions;
- the complete 72-runner Node run, including the ReadyToRun, base
services,
JIT, Loader, and tracing work items that failed in build 1528104.
| Representative CoreCLR browser library suite | Total | Passed |
Skipped | Failed |
| --- | ---: | ---: | ---: | ---: |
| `System.Threading.Timer.Tests` | 33 | 16 | 17 | 0 |
| `System.Runtime.InteropServices.JavaScript.Tests` | 476 | 474 | 2 | 0
|
| `System.Reflection.Emit.Tests` (Debug) | 2,028 | 2,017 | 11 | 0 |
| `System.Runtime.Tests` (Debug) | 75,726 | 75,559 | 167 | 0 |
The generated Batch path has been inspected and generated successfully
but
still requires execution on Windows CI.
> [!NOTE]
> This pull request description was updated with GitHub Copilot.
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 29, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-VM-coreclr

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@lewing@davidwrighton
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' [wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks by lewing · Pull Request #131355 · dotnet/runtime · GitHub
Skip to content

[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks - #131355

Merged
lewing merged 1 commit into
dotnet:mainfrom
lewing:wasm-r2r-crst-nativeimage-eagerfixups
Jul 28, 2026
Merged

[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks#131355
lewing merged 1 commit into
dotnet:mainfrom
lewing:wasm-r2r-crst-nativeimage-eagerfixups

Conversation

@lewing

Copy link
Copy Markdown
Member

The WASM R2R path acquires the NativeImageEagerFixups and PregeneratedStringThunks Crsts without a defined acquisition order between them, which trips a Crst level violation.

Add an AcquiredBefore PregeneratedStringThunks edge to NativeImageEagerFixups in CrstTypes.def so the two locks have a well-defined ordering, and regenerate crsttypes_generated.h (CrstNativeImageEagerFixups level 7 -> 8). Nothing acquires NativeImageEagerFixups before another lock, so the change does not cascade to any other Crst level.

Note

This pull request was authored with assistance from GitHub Copilot.

…nd PregeneratedStringThunks
During a composite R2R load on WebAssembly, the eager-fixup path takes
CrstPregeneratedStringThunks while already holding CrstNativeImageEagerFixups.
Both were assigned the same rank (level 7) because neither declared an ordering
relative to the other, so the nested acquisition trips the Crst level
consistency check ("Can't take level 7 lock ... because you already holding
level 7 lock ...").
Declare NativeImageEagerFixups AcquiredBefore PregeneratedStringThunks in
CrstTypes.def and regenerate crsttypes_generated.h (NativeImageEagerFixups is
now level 8, above PregeneratedStringThunks at 7), making the nested
acquisition well-ordered.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 50ddfb2c-b6f8-4847-81e7-44d37d44a175
@azure-pipelines

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

CopilotAI 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.

Pull request overview

This PR adjusts CoreCLR Crst lock-order metadata to establish a defined ordering between NativeImageEagerFixups and PregeneratedStringThunks, preventing checked-build Crst level violations when both locks are acquired on the WASM R2R path.

Changes:

  • Updates CrstTypes.def to specify NativeImageEagerFixups is acquired before PregeneratedStringThunks (and still before UnresolvedClassLock).
  • Regenerates crsttypes_generated.h, updating CrstNativeImageEagerFixups’s computed level from 7 to 8 to satisfy the new ordering constraint.

Reviewed changes

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

FileDescription
src/coreclr/inc/CrstTypes.defAdds the AcquiredBefore PregeneratedStringThunks dependency for NativeImageEagerFixups to define lock acquisition order.
src/coreclr/inc/crsttypes_generated.hRegenerated Crst level map reflects the new ordering by bumping CrstNativeImageEagerFixups from level 7 to 8.

@lewinglewing added the arch-wasm WebAssembly architecture label Jul 24, 2026
@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.

@lewing

Copy link
Copy Markdown
MemberAuthor

/ba-g arm64 failure is infra

@lewing
lewing merged commit e99b8d4 into dotnet:mainJul 28, 2026
118 of 120 checks passed
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-rc1 milestone Jul 29, 2026
radekdoulik added a commit that referenced this pull request Aug 4, 2026
## Summary
CoreCLR browser-WASM cannot use `fork` or managed process creation, so
runtime
tests marked `RequiresProcessIsolation` were omitted from merged
runners. This
PR enables those tests without adding Node-specific process APIs to
managed
runtime code:
- the merged runner emits a plan using its existing filtering and
striping;
- the host Bash or Batch script executes each existing per-test wrapper
in a
fresh child shell;
- the merged runner imports the child results into its normal xUnit
report.
The PR also includes the runtime-test infrastructure, platform gating,
and
focused runtime/test fixes needed to make priority-0 and priority-1
CoreCLR
browser-WASM coverage pass consistently.
This reuses the existing CoreCLR `corerun` wrappers; it does not
introduce a
parallel `browserhost` scheduler or duplicate per-test execution
semantics.
## Execution model
The browser run has three phases:
1. **Plan:** the generated merged runner writes the selected
out-of-process
assembly paths.
2. **Execute:** the host runs each existing `.sh` or `.cmd` wrapper and
records
its output, exit code, pass/skip state, and skip reason.
3. **Import:** the normal merged run executes in-process tests and
reports the
precomputed child outcomes through the existing xUnit summary.
Existing wrappers remain authoritative for test arguments, environment
variables, pre/post commands, expected exit codes, and per-test
timeouts.
Merged-runner arguments and stripe state are cleared while child
wrappers run
and restored afterward.
The result format is versioned and bound to a per-run token. Missing
plans,
wrappers, results, malformed records, or stale tokens fail as
infrastructure
errors. A child in which every test is skipped is reported as skipped
rather
than passed. Empty plan/status environment settings are treated as
unset.
The host orchestration marker is emitted only for CoreCLR browser-WASM
merged
runners that contain out-of-process tests.
## Browser-WASM enablement and fixes
- **Discovery:** only buildable projects with runnable wrappers are
added to
merged-runner OOP plans.
- **Interpreter:** `InterpreterTester` runs `Interpreter.dll` directly
through
the host OOP path with the required interpreter environment instead of
calling `Process.Start` inside the browser.
- **ReadyToRun assets:** host Crossgen2 assets are staged for
cross-architecture runs, and emitted WASM components, including
composite
output, are validated.
- **Composite ReadyToRun tests:** affected CoreCLR browser tests carry
an
ActiveIssue for
[#131767](#131767). Their
browser
projects do not force Crossgen2, allowing the managed wrapper to report
the
skip before CoreCLR probes the unsupported composite WebCIL layout.
Other
targets retain their existing composite R2R coverage.
- **Host paths:** Batch orchestration retains Windows paths for host
file
operations while exposing Unix-style absolute paths to browser managed
code.
- **Multithreading:** `FeatureMultithreading` is available during test
project
evaluation. Tests whose only requirement is managed multithreading use
that
global capability, so they remain excluded on single-threaded targets
and
become buildable when threads are enabled.
- **Precise platform scope:** tests requiring background/server GC,
native
threads, child processes, unsupported browser APIs, mutable host
filesystem
behavior, or impractical interpreter workloads are gated or excluded at
the
narrowest applicable level.
- **Shutdown lifecycle:** the CoreCLR browser shutdown wrapper is
installed
from Emscripten `preRun`, after native exports are bound, so explicit
`Environment.Exit` values are preserved and no finalization work is
scheduled while the runtime exits.
- **Background GC information test:** the browser CoreCLR
`GetGCMemoryInfo` test carries an ActiveIssue for
[#131766](#131766), which tracks
the
assertion from requesting `GCKind.Background` when background GC is not
compiled. This PR does not change the product behavior.
- **Test assumptions:** focused adaptations remove incidental process,
threading, filesystem, and host-tool assumptions while preserving the
behavior each test is intended to cover.
- **Post-merge CI coverage:** build 1528104 exposed 30 deterministic OOP
failures after newer `main` changes activated more browser scenarios.
The
eager-fixup lock-order failure is fixed on `main` by
[#131355](#131355). Composite
WebCIL
loading and background-GC information remain tracked separately by
#131767
and #131766. The `Int128` field-layout correctness fix is proceeding in
[#131421](#131421); other
unsupported
cases are gated only for CoreCLR browser-WASM with explicit re-enable
prerequisites.
No shipping public API is added.
## Deferred scope
Per-test native assets, UCO thunk generation, and native relinking are
intentionally deferred. Tests that need them remain guarded by their
existing
tracking issues.
The remaining non-multithreading/non-relinking exclusions were audited:
41 represent recoverable coverage and 16 exercise browser-inapplicable
contracts. The recoverable set and its prerequisites are tracked by
[#131321](#131321), with links
from each
suppression site. The newly exposed native-relinking test remains
tracked by
[#123946](#123946).
## Validation
The following complete-suite results were recorded before the two
product fixes
were moved to their dedicated tracking issues:
| CoreCLR browser-WASM run | Total | Passed | Skipped | Failed |
| --- | ---: | ---: | ---: | ---: |
| Priority 0 after the `main` merge | 3,970 | 3,412 | 558 | 0 |
| Priority 0 OOP subset | 485 | 408 | 77 | 0 |
| Earlier full priority 0+1 validation | 14,726 | 13,850 | 876 | 0 |
| Earlier priority 0+1 OOP subset | 740 | 651 | 89 | 0 |
Current-head validation after removing those fixes:
- rebuilt the Checked CoreCLR browser-WASM runtime and libraries with
zero
warnings or errors;
- cleanly built all ten affected browser test projects;
- ran all ten generated wrappers against the unfixed runtime: every
wrapper
exited with the expected status and reported #131766 or #131767 through
the
OOP skip-status protocol, without either runtime assertion;
- verified that the shared non-R2R browser `BasicTest` remains enabled;
- verified on macOS that the R2R variant still forces Crossgen2, emits
and
validates its composite image, and passes.
Additional earlier validation:
- composite and non-composite WASM ReadyToRun output;
- native `NativeLibraryTests` asset staging;
- plan/import success, failure, filtering, striping,
stale/malformed/missing
records, environment-sensitive wrappers, and all-skipped children;
- unset, empty, and non-empty plan/status environment settings;
- direct browser-WASM `InterpreterTester` execution under Node;
- generated Bash syntax and generated Batch structure/path conversion;
- Checked browser runtime rebuild plus a fresh priority-0 payload and
test
layout after the `main` merge;
- all 22 new gates across CoreCLR browser, WASI, desktop, and Mono
browser
evaluations, preserving the pre-existing Mono ReadyToRun exclusions;
- the complete 72-runner Node run, including the ReadyToRun, base
services,
JIT, Loader, and tracing work items that failed in build 1528104.
| Representative CoreCLR browser library suite | Total | Passed |
Skipped | Failed |
| --- | ---: | ---: | ---: | ---: |
| `System.Threading.Timer.Tests` | 33 | 16 | 17 | 0 |
| `System.Runtime.InteropServices.JavaScript.Tests` | 476 | 474 | 2 | 0
|
| `System.Reflection.Emit.Tests` (Debug) | 2,028 | 2,017 | 11 | 0 |
| `System.Runtime.Tests` (Debug) | 75,726 | 75,559 | 167 | 0 |
The generated Batch path has been inspected and generated successfully
but
still requires execution on Windows CI.
> [!NOTE]
> This pull request description was updated with GitHub Copilot.
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 29, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-VM-coreclr

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@lewing@davidwrighton
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks by lewing · Pull Request #131355 · dotnet/runtime · GitHub
Skip to content

[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks - #131355

Merged
lewing merged 1 commit into
dotnet:mainfrom
lewing:wasm-r2r-crst-nativeimage-eagerfixups
Jul 28, 2026
Merged

[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks#131355
lewing merged 1 commit into
dotnet:mainfrom
lewing:wasm-r2r-crst-nativeimage-eagerfixups

Conversation

@lewing

Copy link
Copy Markdown
Member

The WASM R2R path acquires the NativeImageEagerFixups and PregeneratedStringThunks Crsts without a defined acquisition order between them, which trips a Crst level violation.

Add an AcquiredBefore PregeneratedStringThunks edge to NativeImageEagerFixups in CrstTypes.def so the two locks have a well-defined ordering, and regenerate crsttypes_generated.h (CrstNativeImageEagerFixups level 7 -> 8). Nothing acquires NativeImageEagerFixups before another lock, so the change does not cascade to any other Crst level.

Note

This pull request was authored with assistance from GitHub Copilot.

…nd PregeneratedStringThunks
During a composite R2R load on WebAssembly, the eager-fixup path takes
CrstPregeneratedStringThunks while already holding CrstNativeImageEagerFixups.
Both were assigned the same rank (level 7) because neither declared an ordering
relative to the other, so the nested acquisition trips the Crst level
consistency check ("Can't take level 7 lock ... because you already holding
level 7 lock ...").
Declare NativeImageEagerFixups AcquiredBefore PregeneratedStringThunks in
CrstTypes.def and regenerate crsttypes_generated.h (NativeImageEagerFixups is
now level 8, above PregeneratedStringThunks at 7), making the nested
acquisition well-ordered.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 50ddfb2c-b6f8-4847-81e7-44d37d44a175
@azure-pipelines

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

CopilotAI 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.

Pull request overview

This PR adjusts CoreCLR Crst lock-order metadata to establish a defined ordering between NativeImageEagerFixups and PregeneratedStringThunks, preventing checked-build Crst level violations when both locks are acquired on the WASM R2R path.

Changes:

  • Updates CrstTypes.def to specify NativeImageEagerFixups is acquired before PregeneratedStringThunks (and still before UnresolvedClassLock).
  • Regenerates crsttypes_generated.h, updating CrstNativeImageEagerFixups’s computed level from 7 to 8 to satisfy the new ordering constraint.

Reviewed changes

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

FileDescription
src/coreclr/inc/CrstTypes.defAdds the AcquiredBefore PregeneratedStringThunks dependency for NativeImageEagerFixups to define lock acquisition order.
src/coreclr/inc/crsttypes_generated.hRegenerated Crst level map reflects the new ordering by bumping CrstNativeImageEagerFixups from level 7 to 8.

@lewinglewing added the arch-wasm WebAssembly architecture label Jul 24, 2026
@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.

@lewing

Copy link
Copy Markdown
MemberAuthor

/ba-g arm64 failure is infra

@lewing
lewing merged commit e99b8d4 into dotnet:mainJul 28, 2026
118 of 120 checks passed
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-rc1 milestone Jul 29, 2026
radekdoulik added a commit that referenced this pull request Aug 4, 2026
## Summary
CoreCLR browser-WASM cannot use `fork` or managed process creation, so
runtime
tests marked `RequiresProcessIsolation` were omitted from merged
runners. This
PR enables those tests without adding Node-specific process APIs to
managed
runtime code:
- the merged runner emits a plan using its existing filtering and
striping;
- the host Bash or Batch script executes each existing per-test wrapper
in a
fresh child shell;
- the merged runner imports the child results into its normal xUnit
report.
The PR also includes the runtime-test infrastructure, platform gating,
and
focused runtime/test fixes needed to make priority-0 and priority-1
CoreCLR
browser-WASM coverage pass consistently.
This reuses the existing CoreCLR `corerun` wrappers; it does not
introduce a
parallel `browserhost` scheduler or duplicate per-test execution
semantics.
## Execution model
The browser run has three phases:
1. **Plan:** the generated merged runner writes the selected
out-of-process
assembly paths.
2. **Execute:** the host runs each existing `.sh` or `.cmd` wrapper and
records
its output, exit code, pass/skip state, and skip reason.
3. **Import:** the normal merged run executes in-process tests and
reports the
precomputed child outcomes through the existing xUnit summary.
Existing wrappers remain authoritative for test arguments, environment
variables, pre/post commands, expected exit codes, and per-test
timeouts.
Merged-runner arguments and stripe state are cleared while child
wrappers run
and restored afterward.
The result format is versioned and bound to a per-run token. Missing
plans,
wrappers, results, malformed records, or stale tokens fail as
infrastructure
errors. A child in which every test is skipped is reported as skipped
rather
than passed. Empty plan/status environment settings are treated as
unset.
The host orchestration marker is emitted only for CoreCLR browser-WASM
merged
runners that contain out-of-process tests.
## Browser-WASM enablement and fixes
- **Discovery:** only buildable projects with runnable wrappers are
added to
merged-runner OOP plans.
- **Interpreter:** `InterpreterTester` runs `Interpreter.dll` directly
through
the host OOP path with the required interpreter environment instead of
calling `Process.Start` inside the browser.
- **ReadyToRun assets:** host Crossgen2 assets are staged for
cross-architecture runs, and emitted WASM components, including
composite
output, are validated.
- **Composite ReadyToRun tests:** affected CoreCLR browser tests carry
an
ActiveIssue for
[#131767](#131767). Their
browser
projects do not force Crossgen2, allowing the managed wrapper to report
the
skip before CoreCLR probes the unsupported composite WebCIL layout.
Other
targets retain their existing composite R2R coverage.
- **Host paths:** Batch orchestration retains Windows paths for host
file
operations while exposing Unix-style absolute paths to browser managed
code.
- **Multithreading:** `FeatureMultithreading` is available during test
project
evaluation. Tests whose only requirement is managed multithreading use
that
global capability, so they remain excluded on single-threaded targets
and
become buildable when threads are enabled.
- **Precise platform scope:** tests requiring background/server GC,
native
threads, child processes, unsupported browser APIs, mutable host
filesystem
behavior, or impractical interpreter workloads are gated or excluded at
the
narrowest applicable level.
- **Shutdown lifecycle:** the CoreCLR browser shutdown wrapper is
installed
from Emscripten `preRun`, after native exports are bound, so explicit
`Environment.Exit` values are preserved and no finalization work is
scheduled while the runtime exits.
- **Background GC information test:** the browser CoreCLR
`GetGCMemoryInfo` test carries an ActiveIssue for
[#131766](#131766), which tracks
the
assertion from requesting `GCKind.Background` when background GC is not
compiled. This PR does not change the product behavior.
- **Test assumptions:** focused adaptations remove incidental process,
threading, filesystem, and host-tool assumptions while preserving the
behavior each test is intended to cover.
- **Post-merge CI coverage:** build 1528104 exposed 30 deterministic OOP
failures after newer `main` changes activated more browser scenarios.
The
eager-fixup lock-order failure is fixed on `main` by
[#131355](#131355). Composite
WebCIL
loading and background-GC information remain tracked separately by
#131767
and #131766. The `Int128` field-layout correctness fix is proceeding in
[#131421](#131421); other
unsupported
cases are gated only for CoreCLR browser-WASM with explicit re-enable
prerequisites.
No shipping public API is added.
## Deferred scope
Per-test native assets, UCO thunk generation, and native relinking are
intentionally deferred. Tests that need them remain guarded by their
existing
tracking issues.
The remaining non-multithreading/non-relinking exclusions were audited:
41 represent recoverable coverage and 16 exercise browser-inapplicable
contracts. The recoverable set and its prerequisites are tracked by
[#131321](#131321), with links
from each
suppression site. The newly exposed native-relinking test remains
tracked by
[#123946](#123946).
## Validation
The following complete-suite results were recorded before the two
product fixes
were moved to their dedicated tracking issues:
| CoreCLR browser-WASM run | Total | Passed | Skipped | Failed |
| --- | ---: | ---: | ---: | ---: |
| Priority 0 after the `main` merge | 3,970 | 3,412 | 558 | 0 |
| Priority 0 OOP subset | 485 | 408 | 77 | 0 |
| Earlier full priority 0+1 validation | 14,726 | 13,850 | 876 | 0 |
| Earlier priority 0+1 OOP subset | 740 | 651 | 89 | 0 |
Current-head validation after removing those fixes:
- rebuilt the Checked CoreCLR browser-WASM runtime and libraries with
zero
warnings or errors;
- cleanly built all ten affected browser test projects;
- ran all ten generated wrappers against the unfixed runtime: every
wrapper
exited with the expected status and reported #131766 or #131767 through
the
OOP skip-status protocol, without either runtime assertion;
- verified that the shared non-R2R browser `BasicTest` remains enabled;
- verified on macOS that the R2R variant still forces Crossgen2, emits
and
validates its composite image, and passes.
Additional earlier validation:
- composite and non-composite WASM ReadyToRun output;
- native `NativeLibraryTests` asset staging;
- plan/import success, failure, filtering, striping,
stale/malformed/missing
records, environment-sensitive wrappers, and all-skipped children;
- unset, empty, and non-empty plan/status environment settings;
- direct browser-WASM `InterpreterTester` execution under Node;
- generated Bash syntax and generated Batch structure/path conversion;
- Checked browser runtime rebuild plus a fresh priority-0 payload and
test
layout after the `main` merge;
- all 22 new gates across CoreCLR browser, WASI, desktop, and Mono
browser
evaluations, preserving the pre-existing Mono ReadyToRun exclusions;
- the complete 72-runner Node run, including the ReadyToRun, base
services,
JIT, Loader, and tracing work items that failed in build 1528104.
| Representative CoreCLR browser library suite | Total | Passed |
Skipped | Failed |
| --- | ---: | ---: | ---: | ---: |
| `System.Threading.Timer.Tests` | 33 | 16 | 17 | 0 |
| `System.Runtime.InteropServices.JavaScript.Tests` | 476 | 474 | 2 | 0
|
| `System.Reflection.Emit.Tests` (Debug) | 2,028 | 2,017 | 11 | 0 |
| `System.Runtime.Tests` (Debug) | 75,726 | 75,559 | 167 | 0 |
The generated Batch path has been inspected and generated successfully
but
still requires execution on Windows CI.
> [!NOTE]
> This pull request description was updated with GitHub Copilot.
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 29, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-VM-coreclr

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@lewing@davidwrighton
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks by lewing · Pull Request #131355 · dotnet/runtime · GitHub
Skip to content

[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks - #131355

Merged
lewing merged 1 commit into
dotnet:mainfrom
lewing:wasm-r2r-crst-nativeimage-eagerfixups
Jul 28, 2026
Merged

[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks#131355
lewing merged 1 commit into
dotnet:mainfrom
lewing:wasm-r2r-crst-nativeimage-eagerfixups

Conversation

@lewing

Copy link
Copy Markdown
Member

The WASM R2R path acquires the NativeImageEagerFixups and PregeneratedStringThunks Crsts without a defined acquisition order between them, which trips a Crst level violation.

Add an AcquiredBefore PregeneratedStringThunks edge to NativeImageEagerFixups in CrstTypes.def so the two locks have a well-defined ordering, and regenerate crsttypes_generated.h (CrstNativeImageEagerFixups level 7 -> 8). Nothing acquires NativeImageEagerFixups before another lock, so the change does not cascade to any other Crst level.

Note

This pull request was authored with assistance from GitHub Copilot.

…nd PregeneratedStringThunks
During a composite R2R load on WebAssembly, the eager-fixup path takes
CrstPregeneratedStringThunks while already holding CrstNativeImageEagerFixups.
Both were assigned the same rank (level 7) because neither declared an ordering
relative to the other, so the nested acquisition trips the Crst level
consistency check ("Can't take level 7 lock ... because you already holding
level 7 lock ...").
Declare NativeImageEagerFixups AcquiredBefore PregeneratedStringThunks in
CrstTypes.def and regenerate crsttypes_generated.h (NativeImageEagerFixups is
now level 8, above PregeneratedStringThunks at 7), making the nested
acquisition well-ordered.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 50ddfb2c-b6f8-4847-81e7-44d37d44a175
@azure-pipelines

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

CopilotAI 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.

Pull request overview

This PR adjusts CoreCLR Crst lock-order metadata to establish a defined ordering between NativeImageEagerFixups and PregeneratedStringThunks, preventing checked-build Crst level violations when both locks are acquired on the WASM R2R path.

Changes:

  • Updates CrstTypes.def to specify NativeImageEagerFixups is acquired before PregeneratedStringThunks (and still before UnresolvedClassLock).
  • Regenerates crsttypes_generated.h, updating CrstNativeImageEagerFixups’s computed level from 7 to 8 to satisfy the new ordering constraint.

Reviewed changes

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

FileDescription
src/coreclr/inc/CrstTypes.defAdds the AcquiredBefore PregeneratedStringThunks dependency for NativeImageEagerFixups to define lock acquisition order.
src/coreclr/inc/crsttypes_generated.hRegenerated Crst level map reflects the new ordering by bumping CrstNativeImageEagerFixups from level 7 to 8.

@lewinglewing added the arch-wasm WebAssembly architecture label Jul 24, 2026
@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.

@lewing

Copy link
Copy Markdown
MemberAuthor

/ba-g arm64 failure is infra

@lewing
lewing merged commit e99b8d4 into dotnet:mainJul 28, 2026
118 of 120 checks passed
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-rc1 milestone Jul 29, 2026
radekdoulik added a commit that referenced this pull request Aug 4, 2026
## Summary
CoreCLR browser-WASM cannot use `fork` or managed process creation, so
runtime
tests marked `RequiresProcessIsolation` were omitted from merged
runners. This
PR enables those tests without adding Node-specific process APIs to
managed
runtime code:
- the merged runner emits a plan using its existing filtering and
striping;
- the host Bash or Batch script executes each existing per-test wrapper
in a
fresh child shell;
- the merged runner imports the child results into its normal xUnit
report.
The PR also includes the runtime-test infrastructure, platform gating,
and
focused runtime/test fixes needed to make priority-0 and priority-1
CoreCLR
browser-WASM coverage pass consistently.
This reuses the existing CoreCLR `corerun` wrappers; it does not
introduce a
parallel `browserhost` scheduler or duplicate per-test execution
semantics.
## Execution model
The browser run has three phases:
1. **Plan:** the generated merged runner writes the selected
out-of-process
assembly paths.
2. **Execute:** the host runs each existing `.sh` or `.cmd` wrapper and
records
its output, exit code, pass/skip state, and skip reason.
3. **Import:** the normal merged run executes in-process tests and
reports the
precomputed child outcomes through the existing xUnit summary.
Existing wrappers remain authoritative for test arguments, environment
variables, pre/post commands, expected exit codes, and per-test
timeouts.
Merged-runner arguments and stripe state are cleared while child
wrappers run
and restored afterward.
The result format is versioned and bound to a per-run token. Missing
plans,
wrappers, results, malformed records, or stale tokens fail as
infrastructure
errors. A child in which every test is skipped is reported as skipped
rather
than passed. Empty plan/status environment settings are treated as
unset.
The host orchestration marker is emitted only for CoreCLR browser-WASM
merged
runners that contain out-of-process tests.
## Browser-WASM enablement and fixes
- **Discovery:** only buildable projects with runnable wrappers are
added to
merged-runner OOP plans.
- **Interpreter:** `InterpreterTester` runs `Interpreter.dll` directly
through
the host OOP path with the required interpreter environment instead of
calling `Process.Start` inside the browser.
- **ReadyToRun assets:** host Crossgen2 assets are staged for
cross-architecture runs, and emitted WASM components, including
composite
output, are validated.
- **Composite ReadyToRun tests:** affected CoreCLR browser tests carry
an
ActiveIssue for
[#131767](#131767). Their
browser
projects do not force Crossgen2, allowing the managed wrapper to report
the
skip before CoreCLR probes the unsupported composite WebCIL layout.
Other
targets retain their existing composite R2R coverage.
- **Host paths:** Batch orchestration retains Windows paths for host
file
operations while exposing Unix-style absolute paths to browser managed
code.
- **Multithreading:** `FeatureMultithreading` is available during test
project
evaluation. Tests whose only requirement is managed multithreading use
that
global capability, so they remain excluded on single-threaded targets
and
become buildable when threads are enabled.
- **Precise platform scope:** tests requiring background/server GC,
native
threads, child processes, unsupported browser APIs, mutable host
filesystem
behavior, or impractical interpreter workloads are gated or excluded at
the
narrowest applicable level.
- **Shutdown lifecycle:** the CoreCLR browser shutdown wrapper is
installed
from Emscripten `preRun`, after native exports are bound, so explicit
`Environment.Exit` values are preserved and no finalization work is
scheduled while the runtime exits.
- **Background GC information test:** the browser CoreCLR
`GetGCMemoryInfo` test carries an ActiveIssue for
[#131766](#131766), which tracks
the
assertion from requesting `GCKind.Background` when background GC is not
compiled. This PR does not change the product behavior.
- **Test assumptions:** focused adaptations remove incidental process,
threading, filesystem, and host-tool assumptions while preserving the
behavior each test is intended to cover.
- **Post-merge CI coverage:** build 1528104 exposed 30 deterministic OOP
failures after newer `main` changes activated more browser scenarios.
The
eager-fixup lock-order failure is fixed on `main` by
[#131355](#131355). Composite
WebCIL
loading and background-GC information remain tracked separately by
#131767
and #131766. The `Int128` field-layout correctness fix is proceeding in
[#131421](#131421); other
unsupported
cases are gated only for CoreCLR browser-WASM with explicit re-enable
prerequisites.
No shipping public API is added.
## Deferred scope
Per-test native assets, UCO thunk generation, and native relinking are
intentionally deferred. Tests that need them remain guarded by their
existing
tracking issues.
The remaining non-multithreading/non-relinking exclusions were audited:
41 represent recoverable coverage and 16 exercise browser-inapplicable
contracts. The recoverable set and its prerequisites are tracked by
[#131321](#131321), with links
from each
suppression site. The newly exposed native-relinking test remains
tracked by
[#123946](#123946).
## Validation
The following complete-suite results were recorded before the two
product fixes
were moved to their dedicated tracking issues:
| CoreCLR browser-WASM run | Total | Passed | Skipped | Failed |
| --- | ---: | ---: | ---: | ---: |
| Priority 0 after the `main` merge | 3,970 | 3,412 | 558 | 0 |
| Priority 0 OOP subset | 485 | 408 | 77 | 0 |
| Earlier full priority 0+1 validation | 14,726 | 13,850 | 876 | 0 |
| Earlier priority 0+1 OOP subset | 740 | 651 | 89 | 0 |
Current-head validation after removing those fixes:
- rebuilt the Checked CoreCLR browser-WASM runtime and libraries with
zero
warnings or errors;
- cleanly built all ten affected browser test projects;
- ran all ten generated wrappers against the unfixed runtime: every
wrapper
exited with the expected status and reported #131766 or #131767 through
the
OOP skip-status protocol, without either runtime assertion;
- verified that the shared non-R2R browser `BasicTest` remains enabled;
- verified on macOS that the R2R variant still forces Crossgen2, emits
and
validates its composite image, and passes.
Additional earlier validation:
- composite and non-composite WASM ReadyToRun output;
- native `NativeLibraryTests` asset staging;
- plan/import success, failure, filtering, striping,
stale/malformed/missing
records, environment-sensitive wrappers, and all-skipped children;
- unset, empty, and non-empty plan/status environment settings;
- direct browser-WASM `InterpreterTester` execution under Node;
- generated Bash syntax and generated Batch structure/path conversion;
- Checked browser runtime rebuild plus a fresh priority-0 payload and
test
layout after the `main` merge;
- all 22 new gates across CoreCLR browser, WASI, desktop, and Mono
browser
evaluations, preserving the pre-existing Mono ReadyToRun exclusions;
- the complete 72-runner Node run, including the ReadyToRun, base
services,
JIT, Loader, and tracing work items that failed in build 1528104.
| Representative CoreCLR browser library suite | Total | Passed |
Skipped | Failed |
| --- | ---: | ---: | ---: | ---: |
| `System.Threading.Timer.Tests` | 33 | 16 | 17 | 0 |
| `System.Runtime.InteropServices.JavaScript.Tests` | 476 | 474 | 2 | 0
|
| `System.Reflection.Emit.Tests` (Debug) | 2,028 | 2,017 | 11 | 0 |
| `System.Runtime.Tests` (Debug) | 75,726 | 75,559 | 167 | 0 |
The generated Batch path has been inspected and generated successfully
but
still requires execution on Windows CI.
> [!NOTE]
> This pull request description was updated with GitHub Copilot.
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 29, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-VM-coreclr

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@lewing@davidwrighton
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); [wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks by lewing · Pull Request #131355 · dotnet/runtime · GitHub
Skip to content

[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks - #131355

Merged
lewing merged 1 commit into
dotnet:mainfrom
lewing:wasm-r2r-crst-nativeimage-eagerfixups
Jul 28, 2026
Merged

[wasm][R2R] Fix Crst level violation between NativeImageEagerFixups and PregeneratedStringThunks#131355
lewing merged 1 commit into
dotnet:mainfrom
lewing:wasm-r2r-crst-nativeimage-eagerfixups

Conversation

@lewing

Copy link
Copy Markdown
Member

The WASM R2R path acquires the NativeImageEagerFixups and PregeneratedStringThunks Crsts without a defined acquisition order between them, which trips a Crst level violation.

Add an AcquiredBefore PregeneratedStringThunks edge to NativeImageEagerFixups in CrstTypes.def so the two locks have a well-defined ordering, and regenerate crsttypes_generated.h (CrstNativeImageEagerFixups level 7 -> 8). Nothing acquires NativeImageEagerFixups before another lock, so the change does not cascade to any other Crst level.

Note

This pull request was authored with assistance from GitHub Copilot.

…nd PregeneratedStringThunks
During a composite R2R load on WebAssembly, the eager-fixup path takes
CrstPregeneratedStringThunks while already holding CrstNativeImageEagerFixups.
Both were assigned the same rank (level 7) because neither declared an ordering
relative to the other, so the nested acquisition trips the Crst level
consistency check ("Can't take level 7 lock ... because you already holding
level 7 lock ...").
Declare NativeImageEagerFixups AcquiredBefore PregeneratedStringThunks in
CrstTypes.def and regenerate crsttypes_generated.h (NativeImageEagerFixups is
now level 8, above PregeneratedStringThunks at 7), making the nested
acquisition well-ordered.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 50ddfb2c-b6f8-4847-81e7-44d37d44a175
@azure-pipelines

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

CopilotAI 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.

Pull request overview

This PR adjusts CoreCLR Crst lock-order metadata to establish a defined ordering between NativeImageEagerFixups and PregeneratedStringThunks, preventing checked-build Crst level violations when both locks are acquired on the WASM R2R path.

Changes:

  • Updates CrstTypes.def to specify NativeImageEagerFixups is acquired before PregeneratedStringThunks (and still before UnresolvedClassLock).
  • Regenerates crsttypes_generated.h, updating CrstNativeImageEagerFixups’s computed level from 7 to 8 to satisfy the new ordering constraint.

Reviewed changes

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

FileDescription
src/coreclr/inc/CrstTypes.defAdds the AcquiredBefore PregeneratedStringThunks dependency for NativeImageEagerFixups to define lock acquisition order.
src/coreclr/inc/crsttypes_generated.hRegenerated Crst level map reflects the new ordering by bumping CrstNativeImageEagerFixups from level 7 to 8.

@lewinglewing added the arch-wasm WebAssembly architecture label Jul 24, 2026
@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.

@lewing

Copy link
Copy Markdown
MemberAuthor

/ba-g arm64 failure is infra

@lewing
lewing merged commit e99b8d4 into dotnet:mainJul 28, 2026
118 of 120 checks passed
@dotnet-milestone-botdotnet-milestone-botBot added this to the 11.0-rc1 milestone Jul 29, 2026
radekdoulik added a commit that referenced this pull request Aug 4, 2026
## Summary
CoreCLR browser-WASM cannot use `fork` or managed process creation, so
runtime
tests marked `RequiresProcessIsolation` were omitted from merged
runners. This
PR enables those tests without adding Node-specific process APIs to
managed
runtime code:
- the merged runner emits a plan using its existing filtering and
striping;
- the host Bash or Batch script executes each existing per-test wrapper
in a
fresh child shell;
- the merged runner imports the child results into its normal xUnit
report.
The PR also includes the runtime-test infrastructure, platform gating,
and
focused runtime/test fixes needed to make priority-0 and priority-1
CoreCLR
browser-WASM coverage pass consistently.
This reuses the existing CoreCLR `corerun` wrappers; it does not
introduce a
parallel `browserhost` scheduler or duplicate per-test execution
semantics.
## Execution model
The browser run has three phases:
1. **Plan:** the generated merged runner writes the selected
out-of-process
assembly paths.
2. **Execute:** the host runs each existing `.sh` or `.cmd` wrapper and
records
its output, exit code, pass/skip state, and skip reason.
3. **Import:** the normal merged run executes in-process tests and
reports the
precomputed child outcomes through the existing xUnit summary.
Existing wrappers remain authoritative for test arguments, environment
variables, pre/post commands, expected exit codes, and per-test
timeouts.
Merged-runner arguments and stripe state are cleared while child
wrappers run
and restored afterward.
The result format is versioned and bound to a per-run token. Missing
plans,
wrappers, results, malformed records, or stale tokens fail as
infrastructure
errors. A child in which every test is skipped is reported as skipped
rather
than passed. Empty plan/status environment settings are treated as
unset.
The host orchestration marker is emitted only for CoreCLR browser-WASM
merged
runners that contain out-of-process tests.
## Browser-WASM enablement and fixes
- **Discovery:** only buildable projects with runnable wrappers are
added to
merged-runner OOP plans.
- **Interpreter:** `InterpreterTester` runs `Interpreter.dll` directly
through
the host OOP path with the required interpreter environment instead of
calling `Process.Start` inside the browser.
- **ReadyToRun assets:** host Crossgen2 assets are staged for
cross-architecture runs, and emitted WASM components, including
composite
output, are validated.
- **Composite ReadyToRun tests:** affected CoreCLR browser tests carry
an
ActiveIssue for
[#131767](#131767). Their
browser
projects do not force Crossgen2, allowing the managed wrapper to report
the
skip before CoreCLR probes the unsupported composite WebCIL layout.
Other
targets retain their existing composite R2R coverage.
- **Host paths:** Batch orchestration retains Windows paths for host
file
operations while exposing Unix-style absolute paths to browser managed
code.
- **Multithreading:** `FeatureMultithreading` is available during test
project
evaluation. Tests whose only requirement is managed multithreading use
that
global capability, so they remain excluded on single-threaded targets
and
become buildable when threads are enabled.
- **Precise platform scope:** tests requiring background/server GC,
native
threads, child processes, unsupported browser APIs, mutable host
filesystem
behavior, or impractical interpreter workloads are gated or excluded at
the
narrowest applicable level.
- **Shutdown lifecycle:** the CoreCLR browser shutdown wrapper is
installed
from Emscripten `preRun`, after native exports are bound, so explicit
`Environment.Exit` values are preserved and no finalization work is
scheduled while the runtime exits.
- **Background GC information test:** the browser CoreCLR
`GetGCMemoryInfo` test carries an ActiveIssue for
[#131766](#131766), which tracks
the
assertion from requesting `GCKind.Background` when background GC is not
compiled. This PR does not change the product behavior.
- **Test assumptions:** focused adaptations remove incidental process,
threading, filesystem, and host-tool assumptions while preserving the
behavior each test is intended to cover.
- **Post-merge CI coverage:** build 1528104 exposed 30 deterministic OOP
failures after newer `main` changes activated more browser scenarios.
The
eager-fixup lock-order failure is fixed on `main` by
[#131355](#131355). Composite
WebCIL
loading and background-GC information remain tracked separately by
#131767
and #131766. The `Int128` field-layout correctness fix is proceeding in
[#131421](#131421); other
unsupported
cases are gated only for CoreCLR browser-WASM with explicit re-enable
prerequisites.
No shipping public API is added.
## Deferred scope
Per-test native assets, UCO thunk generation, and native relinking are
intentionally deferred. Tests that need them remain guarded by their
existing
tracking issues.
The remaining non-multithreading/non-relinking exclusions were audited:
41 represent recoverable coverage and 16 exercise browser-inapplicable
contracts. The recoverable set and its prerequisites are tracked by
[#131321](#131321), with links
from each
suppression site. The newly exposed native-relinking test remains
tracked by
[#123946](#123946).
## Validation
The following complete-suite results were recorded before the two
product fixes
were moved to their dedicated tracking issues:
| CoreCLR browser-WASM run | Total | Passed | Skipped | Failed |
| --- | ---: | ---: | ---: | ---: |
| Priority 0 after the `main` merge | 3,970 | 3,412 | 558 | 0 |
| Priority 0 OOP subset | 485 | 408 | 77 | 0 |
| Earlier full priority 0+1 validation | 14,726 | 13,850 | 876 | 0 |
| Earlier priority 0+1 OOP subset | 740 | 651 | 89 | 0 |
Current-head validation after removing those fixes:
- rebuilt the Checked CoreCLR browser-WASM runtime and libraries with
zero
warnings or errors;
- cleanly built all ten affected browser test projects;
- ran all ten generated wrappers against the unfixed runtime: every
wrapper
exited with the expected status and reported #131766 or #131767 through
the
OOP skip-status protocol, without either runtime assertion;
- verified that the shared non-R2R browser `BasicTest` remains enabled;
- verified on macOS that the R2R variant still forces Crossgen2, emits
and
validates its composite image, and passes.
Additional earlier validation:
- composite and non-composite WASM ReadyToRun output;
- native `NativeLibraryTests` asset staging;
- plan/import success, failure, filtering, striping,
stale/malformed/missing
records, environment-sensitive wrappers, and all-skipped children;
- unset, empty, and non-empty plan/status environment settings;
- direct browser-WASM `InterpreterTester` execution under Node;
- generated Bash syntax and generated Batch structure/path conversion;
- Checked browser runtime rebuild plus a fresh priority-0 payload and
test
layout after the `main` merge;
- all 22 new gates across CoreCLR browser, WASI, desktop, and Mono
browser
evaluations, preserving the pre-existing Mono ReadyToRun exclusions;
- the complete 72-runner Node run, including the ReadyToRun, base
services,
JIT, Loader, and tracing work items that failed in build 1528104.
| Representative CoreCLR browser library suite | Total | Passed |
Skipped | Failed |
| --- | ---: | ---: | ---: | ---: |
| `System.Threading.Timer.Tests` | 33 | 16 | 17 | 0 |
| `System.Runtime.InteropServices.JavaScript.Tests` | 476 | 474 | 2 | 0
|
| `System.Reflection.Emit.Tests` (Debug) | 2,028 | 2,017 | 11 | 0 |
| `System.Runtime.Tests` (Debug) | 75,726 | 75,559 | 167 | 0 |
The generated Batch path has been inspected and generated successfully
but
still requires execution on Windows CI.
> [!NOTE]
> This pull request description was updated with GitHub Copilot.
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 44f4b4ea-409c-4a52-89a0-f488a89488b9
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Aug 29, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-VM-coreclr

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@lewing@davidwrighton