CI: skip framework-dependent bootstrapper in self-contained /perf Rust harness (fix #674 0xC0000135)#690
Merged
Merged
Conversation
…t harness (fix #674 0xC0000135) The on-demand /perf workflow's cross-framework Rust column still read n/a with test_reactor_perf.exe exiting 0xC0000135 (DLL-not-found), even after the self-contained build (#662) and WebView2 staging (#689) fixes. Root cause (reproduced locally, hermetically, with PATH scrubbed to System32): the windows-rs reactor_perf harness main() unconditionally calls bootstrap() (MddBootstrapInitialize2) to locate a *machine-wide* Windows App SDK runtime. windows_reactor_setup::as_self_contained() never stages the framework-dependent bootstrapper, so the exe carries an unsatisfiable load-time import on Microsoft.WindowsAppRuntime.Bootstrap.dll. On the runtime-less runner the loader fails before main runs -> 0xC0000135, 0-byte output, watchdog reports n/a. (Even with the bootstrap DLL staged, MddBootstrapInitialize2 fail-fasts headless with no machine-wide package -> 0xC0000602, so staging the DLL is necessary-but-insufficient.) Fix: in the "Prepare Rust harness" step, alongside the existing build.rs -> as_self_contained() patch, comment out the single bootstrap()?; call in the harness main(). Self-contained apps don't need it: the embedded reg-free app.manifest activates the runtime app-local. Dropping the call removes the import; a loaded-module snapshot confirms all WinAppSDK DLLs then resolve from the app-local staging dir (zero from C:\Program Files\WindowsApps). Benchmark-neutral (it changes runtime discovery, not the measured StockGrid workload, analogous to the build.rs patch) and best-effort: the patch warns (does not fail) if upstream moves the call, leaving the Rust column at n/a without affecting the PR-vs-main C# comparison. Verified end-to-end locally: applying the exact workflow patches to the pinned windows-rs checkout, rebuilding, and running hermetically yields exit 0 with full metrics; dumpbin confirms the Bootstrap.dll import is gone. Final acceptance is a live /perf re-run on a PR (e.g. #656). Refs #674, #662, #677, #689. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes the /perf workflow’s Rust cross-framework column by ensuring the pinned windows-rs perf harness can launch on runners without a machine-wide Windows App SDK runtime, by neutralizing the harness’s framework-dependent bootstrapper call while keeping the self-contained staging approach.
Changes:
- Patch the pinned
windows-rsreactor_perfharness to comment outbootstrap()?;inmain.rs, preventing load-time dependency onMicrosoft.WindowsAppRuntime.Bootstrap.dllon runtime-less CI runners. - Update the stress perf CI README to document why the bootstrap call must be removed for the self-contained Rust harness and how the failure surfaces (
0xC0000135/0xC0000602).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
.github/workflows/perf-compare.yml |
Adds a best-effort PowerShell patch that comments out the Rust harness bootstrap() call to avoid framework-dependent bootstrapper imports on CI. |
tests/stress_perf/ci/README.md |
Documents the Rust self-contained harness patching rationale and troubleshooting guidance for 0xC0000135 “n/a” failures. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The on-demand
/perfworkflow's cross-framework Rust column still readn/a, withtest_reactor_perf.exeexiting0xC0000135(DLL-not-found) at launch — even after the self-contained build (#662) and WebView2 Core staging (#689) fixes. This PR fixes the remaining root cause so the Rust column produces live numbers.This is CI/build-script + docs only — no framework runtime code is touched.
Root cause (reproduced locally, hermetically)
I reproduced the runner failure on a local box with
PATHscrubbed toSystem32only (so a machine-wide Windows App SDK runtime cannot mask missing app-local DLLs), mirroring the GitHubwindows-latestrunner which has no machine-wide WinAppSDK runtime:reactor_perfharnessmain()unconditionally callsbootstrap()(MddBootstrapInitialize2) to locate a machine-wide Windows App SDK runtime.windows_reactor_setup::as_self_contained()(which the workflow already patchesbuild.rsto call) never stages the framework-dependent bootstrapper — onlyas_framework_dependentcallscopy_bootstrap_to.Microsoft.WindowsAppRuntime.Bootstrap.dll(confirmed withdumpbin /imports). On the runtime-less runner the loader fails beforemainruns →0xC0000135, instant exit, 0-byte stdout/stderr → the 100s watchdog reportsn/a.MddBootstrapInitialize2(..., OnNoMatch_ShowUI | ...)looks for a machine-wide framework package and fail-fasts headless (0xC0000602) when none is present. So staging the DLL is necessary-but-insufficient — the bootstrap call itself must be neutralized. (This is why CI: stage WebView2 Core DLL so the /perf Rust column runs (fix #674) #689's staging alone didn't fix it.)MddBootstrapInitialize2's own documentation: "Self-contained apps do not need to call this." The harness's embedded reg-freeapp.manifestactivates the runtime app-local.The fix
In the workflow's "Prepare Rust harness" step, alongside the existing
build.rs→as_self_contained()patch, comment out the singlebootstrap()?;call in the cloned harnessmain.rs:Why it's safe:
main()'sbootstrap()is deployment-mode setup (runtime discovery), not the measured StocksGrid workload. Removing it is directly analogous to the existingbuild.rsas_self_contained()patch and does not affect the four target metrics.n/a— it never fails the job, and the PR-vs-mainC# comparison is entirely unaffected (the Rust leg iscontinue-on-error).Stage-RustRuntimeis unchanged — the runtime MSIX payload +Microsoft.Web.WebView2.Core.dll(manifest-declared SxS) are still staged app-local; this fix removes the need for the bootstrapper, it doesn't change staging.Local verification
Applying the exact workflow patches (
build.rs+main.rsregex) to the pinnedwindows-rscheckout, rebuilding, and running hermetically:dumpbinconfirms theMicrosoft.WindowsAppRuntime.Bootstrap.dllimport is gone from the rebuilt exe.PATH-scrubbed run → exit 0 with full metrics (Renders/sec, Reconcile, Diff, Memory).C:\Program Files\WindowsApps) — proving the fix is genuinely runtime-independent, not masked by my box's installed runtime.bootstrap()?;.I also confirmed the before state: the unpatched exit is
0xC0000135(matching the runner), and the DLL-staged-but-call-present exit is0xC0000602(the fail-fast), exactly as the root-cause analysis predicts.Validation run locally
tests/stress_perf/ci/PerfLib.Tests.ps1→ 61/61 ✅tests/stress_perf/ci/RunPerfBenchmark.Tests.ps1→ 21/21 ✅Final acceptance test
This can only be fully validated by a live
/perfre-run on a pre-gate PR (e.g. comment/perfon #656). A maintainer should run that as the final acceptance step; the local hermetic repro + module-path proof above are the strongest evidence achievable off-runner.Refs
0xC0000135symptom tracked in Perf CI: Rust cross-framework column n/a — test_reactor_perf exits 0xC0000135 (DLL-not-found) at runtime #674 (auto-closed by CI: stage WebView2 Core DLL so the /perf Rust column runs (fix #674) #689, but the bug persisted on the live re-run).Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com