Skip to content

Strip symbols from release binaries - #522

Merged
cscheid merged 1 commit into
mainfrom
chore/strip-release-symbols
Aug 13, 2026
Merged

Strip symbols from release binaries#522
cscheid merged 1 commit into
mainfrom
chore/strip-release-symbols

Conversation

@shikokuchuo

Copy link
Copy Markdown
Member

What

Adds strip = "symbols" to [profile.release]. The release build already ships no DWARF debug info (debug = false`); this removes the remaining symbol table — 172k mangled Rust symbol names + addresses, measured 21.6 MiB of the binary — that is never used at runtime.

What we lose (and why it's fine)

  • RUST_BACKTRACE=1 frames and user OS crash reports become address-only. Nothing in the tree captures backtraces programmatically (no Backtrace::capture, no native panic hook), so no feature regresses; if crash symbolication is ever needed, the release job can archive an unstripped binary as a CI artifact (follow-up, not here).
  • Panic file:line:col messages are unaffected (core::panic::Location lives in rodata, not the symtab). Unwinding is untouched (__unwind_info/__eh_frame stay). Dynamic symbols survive (linking unaffected).
  • Profiling is unaffected by design: [profile.release-perf] already carries strip = false for samply/perf.

Verification (local, macOS arm64)

  • cargo build --release --locked --bin q2: binary stripped — nm shows 369 residual dynamic symbols (was 166,964), __LINKEDIT 23.1 → 2.0 MiB.
  • Release workflow gates run green on the stripped bytes: q2 --version, q2 mcp --launcher-info (real bundle, no placeholder). The --print-asset-manifest-hashes gate doesn't exist on main yet (lands with Live share for q2 preview #464).
  • Packaging/signing path dry-run mirroring release.yml: tar -czf single-member tarball → shasum -a 256 -c roundtrip → minisign -S/-V with a throwaway key and filename trusted comment: signature and comment verified. Signing happens in the release job over the tarball bytes, so stripping (a link-time change) cannot break it by construction; this proves the mechanics end-to-end on the new bytes.

Strand: bd-p0p4r9b2

Add strip = "symbols" to [profile.release]. The release build ships no
DWARF debug info; this removes the remaining symbol table (172k mangled
Rust symbols, measured 21.6 MiB) that is never used at runtime. Panic
file:line messages are unaffected (Location lives in rodata, not the
symtab); unwinding is untouched; profiling uses [profile.release-perf],
which already overrides with strip = false.

Verified on a local release build: binary stripped (369 dynamic symbols
remain, LINKEDIT 23.1 -> 2.0 MiB), q2 --version and q2 mcp
--launcher-info gates pass, and the release packaging path (tar.gz +
sha256 + minisign sign/verify with filename trusted comment)
round-trips on the stripped bytes using a throwaway key.
@posit-snyk-bot

posit-snyk-bot commented Aug 13, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@cscheid
cscheid merged commit ba65f5f into main Aug 13, 2026
8 checks passed
@cscheid
cscheid deleted the chore/strip-release-symbols branch August 13, 2026 20:30
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.

3 participants