Crash reports can go to Sentry, with symbols from the release build - #74
Merged
Merged
Conversation
IAmJSD
force-pushed
the
t3code/integrate-sentry-release-pipeline
branch
from
August 29, 2026 21:17
4c44223 to
c17ac64
Compare
…uild Schist could already write a crash report to the user's own machine and that was all it could do with one. A stripped Linux release makes the result nearly useless anyway: the backtrace is addresses. This adds an upload, and the symbols to read it against. The upload is off behind two locks rather than one. The user has to tick it in Preferences, separately from the local report, because writing a file to their machine and sending one to ours are not the same decision. And the build has to have been given a DSN, which only the release workflow does -- so a build from source, or from a distribution's packaging, has none, never reaches `sentry::init`, and does not even show the checkbox rather than showing one that sends reports nowhere. What leaves is scrubbed. No PII, no breadcrumbs, and no release-health sessions, logs or metrics -- the SDK is taken with `default-features = false` and only the four integrations a crash needs. `server_name` is set rather than left alone, because `sentry-contexts` fills it with the machine's hostname and a hostname is very often a person's name. The panic message has the home directory rewritten to `~`: an image editor panic tends to quote the path it choked on, and that path is somebody's document. The transport is ureq over rustls, which is the stack the update check already links, so this adds a reason to talk to the network but no new means of doing it and no C dependency. The flush is forced from inside the panic hook rather than left to the guard's `Drop`. A crash in a GUI often never gets as far as `main` returning -- GPUI unwinds through platform callbacks and an unwind across one of those aborts outright -- so by the time `Drop` would run there may be no process left to run it in. Symbols are uploaded per platform, each in the form its object format keeps them in. Linux goes first, before the strip that already happens, because ELF carries DWARF inside the executable and that is the last moment it exists; what ships keeps its build id, which is what the upload is matched on. That id is now pinned with `--build-id=sha1` on both Linux targets instead of being left to the toolchain: mold writes one by default and Ubuntu's GNU ld does not, and the two Linux jobs use one linker each. macOS runs `dsymutil` after packaging, since `bundle.sh` invokes cargo again and a relink there would change the `LC_UUID` the dSYM is matched on; signing is harmless, it appends a signature and leaves the UUID alone. Windows uploads the .pdb files MSVC writes beside the executables, matched rather than named because rustc derives their names from the binaries'. `SENTRY_AUTH_TOKEN` is the one switch for all of it. Without it every step here is skipped and the release is built exactly as it was before, so forks and any repository without the secrets are unaffected. Verified locally that the build id is byte-identical before and after `strip --strip-debug` and that the DWARF is gone after, and that a DSN produces an enabled client carrying each of these options. The upload itself is not verifiable from here: the first tagged release after the settings exist is the first real test of it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
IAmJSD
force-pushed
the
t3code/integrate-sentry-release-pipeline
branch
from
August 29, 2026 21:37
c17ac64 to
7866127
Compare
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.
Schist could already write a crash report to the user's own machine and that was all it could do with one. On a stripped Linux release the result is nearly useless anyway — the backtrace is addresses. This adds an upload, and the symbols to read it against.
Two locks, not one
The upload needs both:
sentry::init, and hides the checkbox rather than offering one that sends reports nowhere.What leaves
No PII, no breadcrumbs, and no release-health sessions, logs or metrics — the SDK is taken with
default-features = falseand only the four integrations a crash needs.server_nameis set rather than left alone, becausesentry-contextsotherwise fills it with the machine's hostname, and a hostname is very often a person's name. The panic message has the home directory rewritten to~: an image editor panic tends to quote the path it choked on, and that path is somebody's document.Transport is ureq over rustls — the stack the update check already links — so this adds a reason to talk to the network but no new means of doing it, and no C dependency.
The flush is forced from inside the panic hook rather than left to the guard's
Drop. A crash in a GUI often never gets as far asmainreturning: GPUI unwinds through platform callbacks, and an unwind across one of those aborts outright, so by then there may be no process left to flush in.Symbols
Each platform in the form its object format keeps them:
--build-id=sha1on both Linux targets instead of left to the toolchain: mold writes one by default and Ubuntu's GNU ld does not, and the two Linux jobs use one linker each.dsymutilafter packaging, becausebundle.shinvokes cargo again and a relink would change theLC_UUIDthe dSYM is matched on. Signing is harmless; it appends a signature and leaves the UUID alone..pdbs MSVC writes beside the executables, matched rather than named because rustc derives their names from the binaries'.SENTRY_AUTH_TOKENis the one switch for all of it. Without it every step here is skipped and the release is built exactly as before, so forks and any repository without the secrets are unaffected.Before this does anything
The Sentry project does not exist yet, and neither do the settings. Until they are added the pipeline runs green and uploads nothing:
SENTRY_AUTH_TOKENproject:releases. The master switch.SCHIST_SENTRY_DSNSENTRY_ORGSENTRY_PROJECTFull mechanics in
docs/versioning.md§ Crash reporting and symbols.Testing
cargo fmt --check,clippy -D warningsand all 43 tests pass. Five new unit tests cover the redaction and the fails-closed behaviour.Verified by hand: the build id is byte-identical before and after
strip --strip-debugand the DWARF is gone after; and a DSN produces an enabled client actually carryingserver_name=redacted, no PII and no breadcrumbs.Not verified, and not verifiable from here: the upload itself, and whether a stripped Linux release really symbolicates. The first tagged release after the settings land is the first real test of that path.
One judgement call worth a look
schist-mcp's debug files are uploaded too, though only the app links the SDK — the Linux strip is destructive, so it is the one chance to keep anything that could explain a fault there later. It costs quota for symbols nothing currently reports against. Easy to cut toschistalone if you would rather.🤖 Generated with Claude Code