feat(session-replay): embed crash event breadcrumbs into replay recordings#1875
Merged
Conversation
`sentry__value_from_msgpack` decodes a buffer holding a single value to that bare value, so consumers of append-only files like the breadcrumb ring files had to wrap single objects manually. Add `sentry__value_from_msgpack_stream` which always returns a list and use it in the crash daemon's breadcrumb ring reader.
Convert the breadcrumbs carried by the crash event that fall inside the replay window into rrweb `breadcrumb` custom events and append them to the `replay_recording` payload, matching how the Cocoa and Android SDKs surface breadcrumbs on the replay timeline. The breakpad and inproc backends already pass a crash event with scope breadcrumbs applied, so they pick this up without further changes.
The crashpad handler applies the scope to the crash event without breadcrumbs since those are streamed to the `__sentry-breadcrumb1/2` ring files on the hot path. Read and merge the ring files onto the in-memory crash event before flushing the staged session replay, so the replay recording can embed them. The on-disk `__sentry-event` and the regular crash delivery path are unaffected.
The crash event the daemon re-reads from `__sentry-event` for the session replay flush is scope-applied without breadcrumbs; those only get merged from the `__sentry-breadcrumb1/2` ring files into the in-memory event used for the crash envelope. Apply the same merge to the replay flush copy so the replay recording can embed the breadcrumbs.
The example already adds three breadcrumbs in its default setup before crashing, so extend the shared replay envelope assertion to verify they are embedded in the recording as rrweb `breadcrumb` custom events with correct payload fields, ms/s timestamp duality, replay window bounds, and chronological ordering. Covers the crashpad, breakpad, inproc and native daemon backends via the existing replay tests.
|
tustanivsky
added a commit
to getsentry/sentry-unreal
that referenced
this pull request
Jul 16, 2026
Temporary pin to getsentry/sentry-native#1875 so CI builds binaries that embed breadcrumbs into crash replay recordings; revert to a tagged release once it ships.
jpnurmi
reviewed
Jul 16, 2026
mujacica
approved these changes
Jul 17, 2026
Now that stream consumers use sentry__value_from_msgpack_stream, the implicit wrap-multiple-values-in-a-list behavior only obscures misuse. Require a single value spanning the whole buffer and decode the breadcrumb ring files in report_to_envelope with the stream variant, which also stops dropping breadcrumbs when a ring file holds a single entry.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #1875 +/- ##
=======================================
Coverage 75.54% 75.54%
=======================================
Files 90 90
Lines 21043 21127 +84
Branches 3737 3751 +14
=======================================
+ Hits 15897 15961 +64
- Misses 4324 4342 +18
- Partials 822 824 +2 🚀 New features to boost your workflow:
|
jpnurmi
reviewed
Jul 17, 2026
The handler runs in-process, so the scope ring buffer is available directly - no need to read the ring files back; those remain for the out-of-process daemon and next-launch report processing. This also matches how breakpad and inproc get breadcrumbs onto crash events.
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.
This PR adds breadcrumbs to session replay recordings: breadcrumbs carried by the crash event that fall inside the replay window are converted into rrweb
breadcrumbcustom events and embedded into thereplay_recordingpayload, matching how the Cocoa and Android SDKs surface breadcrumbs on the replay timeline.Key changes
sentry__value_from_msgpack_streamdecodes append-only msgpack streams (like the breadcrumb ring files) into a list even when the buffer holds a single value; the crash daemon's ring-file reader andreport_to_envelopenow use it.sentry__value_from_msgpackrejects buffers holding concatenated values instead of implicitly wrapping them in a list, so each call site declares its intent. This also fixesreport_to_envelopedropping breadcrumbs when a ring file holds exactly one entry.sentry__session_replay_flush_pendingembeds the crash event's in-window breadcrumbs into the rrweb recording as type-5 custom events withtag: "breadcrumb"(outer timestamps in ms, payload timestamps in seconds, chronological order). The breakpad and inproc backends pick this up without further changes since their crash event already carries the scope breadcrumbs.__sentry-breadcrumb1/2ring files onto the in-memory crash event before flushing the staged replay; the on-disk__sentry-eventand the regular crash delivery path are unaffected.__sentry-eventsnapshot is scope-applied without breadcrumbs).Testing
value_from_msgpack_streamunit test.