perf(build): Windows ship binaries strip the panic backtrace (build-std) - #547
Merged
Conversation
… backtrace Field binaries are stripped, so a *symbolized* panic backtrace is dead weight: the gimli/addr2line DWARF machinery inside std is ~10% of the CLI. Add a dedicated `[profile.ship]` (inherits `release`, `panic = "immediate-abort"`), built with `-Z build-std`, so a field panic is a bare, process-local `abort()` (no message, no backtrace) — matching the workspace no-panic lint policy. Dev + CI keep normal panics + full backtraces. Measured (x86_64-pc-windows-msvc, uffs.exe): 1,292,800 -> 1,167,872 (-9.7%), and it applies to every shipped binary. Deliberately NOT wired into the default release — build-std is unstable + rebuilds std; opt in from the ship build when ready. Normal dev/release/clippy builds are unaffected (used only with `--profile ship -Z build-std`).
…std) Wire the `ship` profile into the release build for the WINDOWS target only: rebuild std with `panic=immediate-abort` + `optimize_for_size` via `-Z build-std`, so shipped Windows binaries drop the field-useless backtrace machinery (~10% off the CLI: uffs.exe 1,292,800 -> 1,167,872). Linux/macOS stay on `--release`. The `ship` profile outputs to target/<triple>/ship/; mirror the built .exe files into release/ so the packaging steps need no path changes. Windows builds natively on windows-latest with the pinned nightly + rust-src (both from rust-toolchain.toml), so build-std resolves. CAVEATS (validate with a pre-release tag before a real ship): build-std is unstable (panic_immediate_abort changed shape across a recent nightly) and rebuilds std, so watch the 75-min Windows timeout on a cold cache; `optimize_for_size` was not measured locally (only `build-std=std,panic_abort` was, at -9.7%) — a test release will confirm both.
githubrobbi
enabled auto-merge
July 9, 2026 04:04
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Jul 9, 2026
deep-soft
pushed a commit
to deep-soft/UltraFastFileSearch-Rust
that referenced
this pull request
Jul 16, 2026
…emove, udeps) (skyllc-ai#556) * feat(status): physical drive view in `uffs --daemon status -v` Add a `── Physical drives ──` section to the verbose daemon status so a drive letter in the status has concrete hardware behind it: kind (NVMe/SSD/HDD), capacity, used%, and free space, cross-referenced with what the daemon has indexed. The gathering is a new, single library API — `uffs_mft::platform:: physical_drives()` returning `PhysicalDrive` — built entirely from NON-privileged Win32 calls (`GetDiskFreeSpaceExW`, `GetVolumeInformationW`, and the query-only drive-type probe), so it works even when the daemon / CLI run non-elevated via the Access Broker. Returns empty on non-Windows. Reuse over duplication (no back-compat shims kept): - `uffs-mft drives` (`cmd_drives`) now builds on `physical_drives()` and layers `$MFT` geometry on top; its bespoke `collect_drive_infos` and `get_volume_label` are deleted. - Drive-kind labelling collapses to one canonical `DriveType::label()`; the `drive_type_label` wrapper is removed and `info.rs`/`save.rs` call the method directly. Validated: host lint-prod + lint-tests, Windows-target (xwin) clippy, rustdoc-clean docs, fmt, and 411 uffs-mft/uffs-cli tests. * fix(parse): bounds-check resident attr header; guard parser against truncated records The nightly `fuzz_parse_record` target crashed (libFuzzer exit 77) on a 72-byte `FILE` record: `parse_standard_info_full` read the resident- attribute header fields `data[attr_offset+16..20]` and `[..22]` with direct slice indexing, so a record truncated mid-header indexed past the buffer and panicked. Switch to `slice::get`, returning early on a short record instead of panicking. Why Tier-1 missed it: the existing `parse_record_never_panics` / `parse_record_full_never_panics` proptests fed pure random bytes, which essentially never carry the `FILE` magic, so the whole attribute-walk path (where malformed header offsets bite) was never exercised. Enhance both proptests to also run a forced-`FILE`-magic pass and to cover `parse_record_zero_alloc`, and add `repro_fuzz_crash_881b95` — the exact fuzz input as a deterministic regression test. This class now fails in Tier-1 unit tests, not only in nightly fuzzing. Validated: 50k-case proptest run clean, full uffs-mft suite, host lint-prod + lint-tests, fmt. * ci(tier-2): let cargo-udeps parse past the panic-immediate-abort ship gate cargo-udeps embeds an older cargo that cannot parse the nightly-only `cargo-features = ["panic-immediate-abort"]` gate the ship profile needs (root Cargo.toml, PR skyllc-ai#547); it aborts the whole dep scan with "unknown Cargo.toml feature `panic-immediate-abort`", failing the Tier 2 udeps job for reasons unrelated to dependencies. Neutralize the gate for the scan only: drop the `cargo-features` line and set the ship profile's `panic` to the stable "abort", then always restore the manifest via an EXIT trap. Removing a profile / cargo-feature does not affect dependency resolution, so `--locked` stays valid and the analysis is unchanged. Verified locally: stripped manifest parses, real manifest is restored with no leftover backup file. * fix(security): secure_remove no-ops on an absent path (Windows); split fs win FFI Bug: secure_remove documents that removing a missing path is a no-op success, and the open-for-write step already maps NotFound to Ok. But on Windows the win_clear_readonly(path)? pre-clear ran first and surfaced GetFileAttributesW's "file not found" as a hard error, so secure_remove wrongly returned Err on an absent path. This is why the Tier 2 cargo-mutants baseline failed: the cross-platform test secure_remove_absent_is_ok panicked on the Windows runner, so cargo-mutants never reached the mutation phase. Fix: treat a NotFound attribute-probe result as a no-op; only non-NotFound failures propagate. The fix nudged fs.rs to 805 LOC, past the 800 file-size gate. Rather than trim the fix's docs to sneak under (hiding the real issue), extract the ~250 lines of cfg(windows) security FFI helpers (win_set_hidden / win_clear_readonly / path_to_wide / win_get_file_attributes / win_set_file_attributes / win_set_owner_only_acl / win_apply_owner_ace) into a new fs/win.rs module. fs.rs is now 559 LOC and win.rs 264 — both honestly under the limit with FULL documentation, and the unsafe Win32 calls are isolated in one auditable place. No size exception added. The regression test (secure_remove_absent_is_ok) already exists and is cross-platform; it simply is not run on Windows in the PR-fast path. Validated: file-size policy, host uffs-security suite (49 tests), Windows-target (xwin) compile.
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.
Shrinks the shipped Windows binaries by rebuilding std with
panic="immediate-abort"in the release flow — a field panic becomes a bare, process-localabort()with no backtrace. Thegimli/addr2lineDWARF symbolization is ~10% of the CLI and is dead weight on a stripped binary; a panic is a should-never-happen bug anyway (the workspace lints forbid unwrap/panic in prod).Commits
[profile.ship](Cargo.toml): inheritsrelease,panic = "immediate-abort", plus thecargo-featuresopt-in. Only ever built with-Z build-std; dev/normal-release/clippy are unaffected (verified).release.yml: the Windows matrix row only builds--profile ship -Z build-std=std,panic_abort -Z build-std-features=optimize_for_size, then mirrors the.exes fromship/→release/so no packaging path changes. Linux/macOS stay on--release.Measured
x86_64-pc-windows-msvc,uffs.exe: 1,292,800 → 1,167,872 (−9.7%) forbuild-std=std,panic_abort(validated locally).optimize_for_sizeis included but not separately measured — the release run confirms it.Validation plan
Merge →
just shipfrom clean main → watch the Windows leg ofrelease.yml: it must build green, finish under the 75-min timeout, and the zip'suffs.exeshould be ~1.17 MB. A build failure fails the whole release safely (nothing ships); the winget PR is a slow, cancellable downstream. Windows-only, so any revert leaves Linux/macOS untouched.