Deep-dive: why every Rust test binary died on Windows before running a single test (STATUS_ENTRYPOINT_NOT_FOUND) #1552
debpalash
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Part of a series of engineering deep-dives from VoiceStudio's reliability work. This one is about a Windows failure mode that will bite anyone adding integration tests to a Tauri app.
The symptom
While building our new backend-lifecycle fault-injection harness (#1551) — Rust integration tests that boot the real Tauri bootstrap code against scripted fake backends — Windows CI failed with:
No test output. No panic. No stack. The binary died before
mainran, and only on Windows — macOS and Linux were green.Bisecting a loader failure with CI
STATUS_ENTRYPOINT_NOT_FOUNDmeans the Windows loader couldn't resolve an entry point in some imported DLL — it happens at load time, before any of your code executes. So nothing inside the test could be the cause, but which import was it?We proved it with a one-round bisect: a temporary probe test file (
tests/win_load_probe.rs) that linked the same crates but contained a single trivial test. It died with the same code — confirming the failure was pure link/load, independent of any test logic. (The probe was removed in the same PR once it had served its purpose.)The root cause: comctl32 v5 vs v6
Tauri's dialog/tray stack imports
TaskDialogIndirectfromcomctl32.dll. That function only exists in Common-Controls v6 — and Windows resolves v6 only for binaries whose manifest declares a dependency on it. Without that declaration, the loader falls back to comctl32 v5, which has noTaskDialogIndirect, and the process dies at load withSTATUS_ENTRYPOINT_NOT_FOUND.The app binary never hits this because
tauri-buildembeds a proper manifest into it. But cargo gives test binaries no manifest at all. So the moment a test binary links anything that importsTaskDialogIndirect, it becomes unrunnable on Windows — regardless of whether any test ever opens a dialog.The fix
Embed a minimal Common-Controls v6 manifest into test binaries only, from
build.rs:with
tests/windows-test.manifestdeclaring the single dependency:rustc-link-arg-testsscopes the linker args to test binaries, so the app build (which already gets its manifest fromtauri-build) is untouched.Takeaways
cargo testintegration tests on Windows, the first one you add may die at load. The failure is invisible until then.STATUS_ENTRYPOINT_NOT_FOUNDon a test binary = look at imports and manifests, not at your code.The full harness this unblocked: #1551 — 9 fault-injection scenarios (crash loops, spawn failure, port conflict, startup timeout, deferred-init death) now run against the real supervisor code on all 3 OSes in CI.
All reactions