Skip to content

perf(build): Windows ship binaries strip the panic backtrace (build-std) - #547

Merged
githubrobbi merged 2 commits into
mainfrom
perf/strip-release-binary
Jul 9, 2026
Merged

perf(build): Windows ship binaries strip the panic backtrace (build-std)#547
githubrobbi merged 2 commits into
mainfrom
perf/strip-release-binary

Conversation

@githubrobbi

Copy link
Copy Markdown
Collaborator

Shrinks the shipped Windows binaries by rebuilding std with panic="immediate-abort" in the release flow — a field panic becomes a bare, process-local abort() with no backtrace. The gimli/addr2line DWARF 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): inherits release, panic = "immediate-abort", plus the cargo-features opt-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 from ship/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%) for build-std=std,panic_abort (validated locally). optimize_for_size is included but not separately measured — the release run confirms it.

Validation plan

Merge → just ship from clean main → watch the Windows leg of release.yml: it must build green, finish under the 75-min timeout, and the zip's uffs.exe should 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.

… 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
githubrobbi enabled auto-merge July 9, 2026 04:04
@githubrobbi
githubrobbi added this pull request to the merge queue Jul 9, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 9, 2026
@githubrobbi
githubrobbi added this pull request to the merge queue Jul 9, 2026
Merged via the queue into main with commit 833355b Jul 9, 2026
39 of 40 checks passed
@githubrobbi
githubrobbi deleted the perf/strip-release-binary branch July 9, 2026 05:00
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant