Strip local symbols from macOS and Linux release bundles (#63429)

Not sure if this PR is 100% good, since it removes symbols from local
traces, leaving addresses only — but this what Windows seem to do
already, and we have those symbols on Sentry to restore from, which were
needed to normally read Linux perf traces already (see `perf.zip` in
https://github.com/zed-industries/zed/issues/59689#issuecomment-5452720248)

On the upside, uncompressed binaries' are now ~100MB less, which is a
lot — hence decided to open the PR for the review

-------------------

Strips debug info and local symbols from shipped macOS and Linux
binaries, matching what Windows already does with PDBs: `bundle-mac` now
always runs `dsymutil` before a new `strip -x` step, and `bundle-linux`
adds `--discard-all` plus `zed.dbg`/`remote_server.dbg` extraction via
`--only-keep-debug`.

Sentry uploads are unchanged and precede stripping.

The macOS binary UUID and the GNU build id survive stripping, so
user-provided traces stay recoverable without rebuilding at the
reporter's commit: `sample` output resolves via `atos` against the
archived `zed.dwarf`, and `perf.data` via `perf buildid-cache` against
the Sentry-archived binary.

zed binary:
macOS (2026-08-29 nightly): 420478976 -> 316503984 bytes (-24.7%,
-104.0MB)
Linux (v1.17.2 aarch64): 439417448 -> 336967256 bytes (-23.3%, -102.5MB)
Downloads shrink far less, symbols compress ~7:1: the macOS DMG loses
only ~15MB.

Release Notes:

- Improved installed size on macOS and Linux by stripping debug symbols
from release binaries (roughly -25%)
This commit is contained in:
Kirill Bulatov authored and GitHub committed 2026-09-02 19:38:12 +00:00
1 parent 8b32975a05
commit 9be65a8dfe
4 files changed
+80 -20

No files matched your search

+8 -3
View File
@@ -129,7 +129,7 @@ Use this when Zed is using a lot of CPU. It is not useful for hangs.
- Perf record:
Run `sudo perf record -g --call-graph dwarf -p <pid you just found>`, wait a few seconds to gather data, then press Ctrl+C. You should now have a `perf.data` file.
The `--call-graph dwarf` part records the callers of every sampled function: without it, the profile shows isolated hot symbols with no way to tell who invoked them, which is rarely enough to act on.
The `--call-graph dwarf` option records callers of every sampled function and unwinds through the `.eh_frame` data kept in stripped release binaries; plain `-g` does not work without frame pointers.
- Make the output file user owned:
run `sudo chown $USER:$USER perf.data`
@@ -143,8 +143,13 @@ The `perf.data` file can be sent to Zed together with the exact commit.
This can be done by Zed staff.
- Build Zed with symbols:
Check out the commit found previously and modify `Cargo.toml`.
Released Linux binaries are stripped, but the unstripped binary for every release is archived in Sentry (uploaded by `script/bundle-linux`).
Download it from the Sentry project's Debug Files page (search by the release version or the binary's build id), then continue with the `perf buildid-cache` step below.
Stripping preserves the build id, so the downloaded binary matches the user's `perf.data`.
Alternatively, rebuild the binary with symbols:
- Check out the commit found previously and modify `Cargo.toml`.
Apply the following diff, then make a release build.
```diff
+34
View File
@@ -106,6 +106,40 @@ UPDATE_BASELINE=1 cargo run -p zed --bin zed_visual_test_runner --features visua
> **Note:** In the future, baselines may be stored externally. For now, they
> remain local-only to keep the git repository lightweight.
## Sampling released builds
How to get a symbolicated CPU profile from a released (non-dev) Zed instance.
Use this when Zed is using a lot of CPU.
Released macOS binaries are stripped of local symbols, so `sample` and Instruments show raw addresses for most frames.
The debug symbols for every release are archived: `script/bundle-mac` uploads `zed.dwarf` to Sentry before stripping.
### During the incident
- Run `sample Zed 10 -f zed-sample.txt` (adjust the process name for Preview or Nightly).
- Get the exact build: type {#action zed::About} in the command palette and copy the version and commit.
The `zed-sample.txt` file can be sent to Zed together with the exact version.
### Later
This can be done by Zed staff.
- Find the binary UUID in the `Binary Images` section at the bottom of the sample output.
- Download the matching `zed.dwarf` from the Sentry project's Debug Files page by searching for that UUID.
- Resolve the addresses:
`atos -o zed.dwarf -l <load address> <address...>`
Each unresolved frame in the sample output prints its `load address` and absolute address.
To profile a released build on your own machine with full symbols, download the matching `zed.dwarf`, convert it into a `.dSYM` bundle Spotlight can index, and re-run `sample`:
```sh
mkdir -p Zed.dSYM/Contents/Resources/DWARF
cp zed.dwarf Zed.dSYM/Contents/Resources/DWARF/zed
```
Frames then resolve automatically, including file and line information.
## Troubleshooting
### Error compiling metal shaders