fix(android): symbolicate APK-embedded tombstone frames - #5992
Merged
supervacuus merged 4 commits intoAug 25, 2026
Merged
Conversation
supervacuus
requested review from
0xadam-brown,
adinauer,
markushi,
romtsn and
runningcode
as code owners
August 25, 2026 11:30
📲 Install BuildsAndroid
|
supervacuus
deleted the
fix/android/symbolicate-APK-embedded-tombstone-frames
branch
August 25, 2026 14:29
3 tasks
bgriggs
added a commit
to bgriggs/redmist-timing-ui
that referenced
this pull request
Sep 15, 2026
The app's native crash events come from the Android SDK's signal handler, and for the GC crash they arrive in Sentry (REDMIST-APP-M) as SIGSEGV with a single unknown frame: no backtrace for debug files to be matched against, so uploading the runtime's symbols alone would not have named anything. Android 12 and later keep a tombstone for a native crash, with the whole backtrace and every loaded library's build id, and hand it back through ApplicationExitInfo. The Sentry Android SDK's tombstone integration reports that, merging it into the signal handler's event when that caught the same crash. It is now on. One consequence is deliberate to call out. Historical tombstones stay off, but the SDK always reports the most recent native crash it has not reported yet, up to 91 days old, and on the first launch with tombstones on nothing counts as reported. So each phone that crashed recently sends one extra event for a crash already reported, with the release the SDK saved on that earlier run rather than the new one. With the frames named, the crash will also group under its real stack instead of REDMIST-APP-M's single unknown frame. Both would skew judging the GC change by that issue's events per release, so the csproj comment now says to judge it by native crashes per release across issues, or by crash-free sessions. That needs Sentry 6.11. Sentry 6.9.0 bundles sentry-android 8.52.0, and reading a tombstone's frames for a library loaded straight out of the APK - which is how a Play install loads libmonosgen, from split_config.arm64_v8a.apk - only arrived in 8.54.0 (getsentry/sentry-java#5992). 8.55.0 also stopped a dropped tombstone being reported again at every app start (#6002). Sentry .NET 6.11.0 bundles 8.55.0. The upgrade makes SentryOptions.EnableMetrics obsolete and ignored (getsentry/sentry-dotnet#5509), so the line setting it false is gone: a metric is only sent through SentrySdk.Metrics, which the app never calls, or by the System.Diagnostics.Metrics integration, which stays disabled. On iOS the upgrade also brings a fix for managed exceptions being captured twice as NSExceptions; the iOS head has not been run on it here. All 528 tests pass on 6.11.0, and the Android release build restores the four Sentry packages at 6.11.0 with no new NuGet or obsolete-API warnings; its dex carries sentry-android 8.55.0 where the 6.9.0 build's carried 8.52.0. Installed on the SM-S135DL, the pinned smoke run passes: every screen, final PSS 368 MB against a 366 baseline, first frame 6342 ms against 5991 and inside the harness's tolerance. Its live patch check was skipped, since no live event had a session running. What has not been exercised is the tombstone path itself. A local build carries no Sentry DSN, so the SDK is never initialized on the test phone; the first native crash reported after the next release is where a full, symbolicated stack should show.
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.
📜 Description
Fix tombstone symbolication for native libraries loaded directly from uncompressed APK entries.
The parser now accepts ELF mappings with build IDs at nonzero APK offsets, distinguishes multiple ELFs sharing the same APK path, validates mapping continuations using the tombstone page size, and sets frame
image_addrfrompc - rel_pc.Correction during review:
PT_LOADvirtual addresses and file offsets can diverge by one segment-alignment unit at each boundary. Meaning continuations must be validated relative to the previous mapping rather than the module start, so we don't accumulate drift (across multi-segment ELFs).💡 Motivation and Context
TombstoneParserrequiredmapping.offset == 0, excluding ELFs mapped from inside an APK. This removed their debug images when tombstone data replaced the original native event metadata, resulting inunknown_image.But Android's
libunwindstackalready resolved the ELF and supplied its build ID, so Java doesn't need to reopen or parse the APK (as the Native SDK module loader does).Fixes #5986.
💚 How did you test it?
I added the following test cases (names taken directly from the test module):
creates images for multiple ELF files embedded in same APK: verifies distinct build IDs produce distinct images despite sharingbase.apk.coalesces multiple ELF continuations aligned for 16 KiB pages: covers an ELF with threePT_LOADmappings and verifies that per-segment alignment drift does not accumulate.does not include a different embedded ELF without build ID in previous image: prevents unrelated APK mappings from expanding the previous image.sets image address on frame for ELF embedded in APK: verifiesimage_addris derived frompc - rel_pc.parses APK embedded ELF from full tombstone fixture: validates an Android 15 tombstone produced by a non-legacy packaging build (but only the relevant diffs to the default fixture are asserted and not a full snapshot test which would just duplicate most of the existing tests). Now also verifies complete module sizes for 16KiB-aligned ELFs captured on a 4KiB device.Ran the tombstone tests.
Also "manually" compared the resulting envelopes when running from a non-legacy packaged sample build against the tombstone integration and the ndk integration (both now have the debug images for the APK, whereas previously they didn't).
📝 Checklist
sendDefaultPIIis enabled.🔮 Next steps