Harden Windows crash handling, IPC lifetimes, and release symbols - #15
Merged
Merged
Conversation
middaysan
marked this pull request as ready for review
August 31, 2026 20:15
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
mimallocoverride from both the Windows application and Linux beta binary, allowing each binary to use Rust's platform default allocatorOVERLAPPEDstate, event handles, and caller-owned I/O buffers alive until Windows reports a terminal completion resultWAIT_TIMEOUTandERROR_IO_INCOMPLETEas pending overlapped completion statescpu_affinity_tool.pdbRelationship to #14 and causal limits
Issue #14 currently contains reports from two distinct GitHub accounts: the original report describes the application closing after it was minimized and a game was launched, while a later report describes a reproducible exit when closing Black Desert Online after the application changed its affinity. These may or may not share a failure mechanism.
The later Windows Application Error event reports exception
0xc0000005, module timestamp0x6A581616, and fault RVA0xA8B6F6. The timestamp matches the official v1.5.0 release EXE, whose SHA-256 is:97a24947b961b59de2436ed1f75af182ba6320fc88f3c65bbe5840269386c271The reporter did not provide their executable hash, so the matching timestamp is build-consistency evidence rather than cryptographic proof of identical files.
Binary and source mapping of the official v1.5.0 EXE places RVA
0xA8B6F6at_mi_page_malloc_zero+0x26in the mimalloc allocation fast path, at a read through the page free-list pointer. This establishes where the access violation surfaced, not where or by whom the invalid state was created.mimalloc 0.1.48libmimalloc-sys 0.1.442.2.4mimalloc 0.1.52libmimalloc-sys 0.1.493.3.2Version 1.5.0 upgraded an allocator already present in v1.4.0; it did not introduce mimalloc for the first time. Removing the custom allocator is an isolation and mitigation change, not a claim that an internal mimalloc defect is the root cause. It may also mask an earlier invalid write, use-after-free, double-free, or another bug whose manifestation depends on heap layout. No anti-cheat or specific upstream mimalloc issue is treated as proven causal evidence.
Independently found Windows IPC defects
The audit found a separate lifetime defect in the saved-rule named-pipe transport. After
CancelIoEx, the old timeout path could return while Windows still owned an asynchronousReadFileorWriteFile. It preserved only theOVERLAPPEDand event, while the caller-owned buffer could be dropped.The updated path:
GetOverlappedResultExreportsWAIT_TIMEOUTorERROR_IO_INCOMPLETEThe affected IPC code existed in both v1.4.0 and v1.5.0. There is no evidence that saved-rule IPC was active in either reported game scenario, so this is independent hardening rather than a claimed explanation for #14.
Local crash reports and user logs
On Windows, a main/UI-thread Rust panic or an
eframe::run_nativeerror writes a bounded, UTF-8 local report before the process exits. The report is stored under the active data directory, never uploaded automatically, and remains the complete artifact a user can review and attach to an issue.The next startup indexes reports on a background thread. Once that validated scan completes, Activity keeps the newest report's type, timestamp, reason, and full-report path as a dedicated crash-context entry. Activity Clear removes ordinary activity but leaves this latest crash context visible until a refresh replaces it or the report is deleted deliberately from Crash reports.
This is diagnostics support, not a claim that every native crash is captured: forced termination, native access violations, aborts, stack overflow, OOM, power loss, anti-cheat termination, and background task panics can still leave no report.
Windows symbol and release contract
Windows CI and the stable release workflow now use the same
line-tables-onlyrelease helper. Before publication, the verifier requires:cpu_affinity_tool.pdbartifact pathCI exercises positive plus missing, empty, wrong-basename, and mismatched-identity cases. The stable workflow fails before upload if either required file is absent, and GitHub Release publication remains fail-closed for missing declared artifacts.
This does not retroactively create a matching PDB for the already published v1.5.0 EXE: rebuilding produces a different CodeView identity. The PDB is not loaded at runtime, but it is a new public release asset and can contain diagnostic symbol, source-path, and line metadata.
The shared Cargo release profile and Linux beta artifact set/debug-information policy remain unchanged. The allocator change itself affects both Windows and Linux binaries.
Compatibility and risk
Verification
Local checks completed on
3eae2446e26600b305a8a8b41750bac709e9c049:git diff --checkcargo fmt --all -- --checkcargo test --locked --manifest-path libs/os_api/Cargo.toml— 47 passedcargo test --locked --features windows --bin cpu-affinity-tool— 280 passedcargo test --locked --features linux --bin cpu-affinity-tool-linux— 269 passedcargo clippy --locked ... -D warningsscripts/build-windows-release.ps1—[optimized + debuginfo]scripts/test-windows-pdb-verifier.ps1— positive and four negative cases passedscripts/assert-windows-release-manifest.ps1—requireAdministrator,uiAccess=falsescripts/test-windows-crash-reports.ps1— passedGitHub Actions for
3eae2446e26600b305a8a8b41750bac709e9c049:Manual validation still required before leaving draft
cpu-affinity-tool.exeand matchingcpu_affinity_tool.pdbRefs #14