Skip to content

fix: preserve tombstone stack traces in Crashlytics - #3071

Merged
hussainmohd-a merged 2 commits into
celzero:mainfrom
mvanhorn:fix/2990-preserve-tombstone-stacktraces
Sep 5, 2026
Merged

fix: preserve tombstone stack traces in Crashlytics#3071
hussainmohd-a merged 2 commits into
celzero:mainfrom
mvanhorn:fix/2990-preserve-tombstone-stacktraces

Conversation

@mvanhorn

@mvanhorn mvanhorn commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Saved tombstones are currently uploaded by EnhancedBugReport.sendFileToFirebase as text inside a newly created RuntimeException. Crashlytics therefore attributes the event to the uploader and obscures the JVM or Go frames contained in the file, as seen in the reported SQLiteFullException. Kotlin tombstones also prepend timestamp, token, and diagnostic headers before the exception text, while Go dumps pair function lines with subsequent .go:<line> locations. The supplied issue evidence contains no claim, competing PR, or closed-unmerged prior attempt.

A Kotlin tombstone containing timestamp/token headers and the issue's SQLiteFullException trace produces a report exception whose message identifies the saved failure and whose first frames point to SQLiteConnection, RoomDatabase, and the original source line rather than EnhancedBugReport.sendFileToFirebase.

Summary

Replace the message-only synthetic exception construction in EnhancedBugReport with a production-used builder that derives a concise exception message and assigns parsed StackTraceElement entries from the tombstone content before calling FirebaseErrorReporting.recordException. For Kotlin/JVM tombstones, locate the exception header and parse standard at package.Class.method(File.kt:line) frames despite the metadata prefix; for Go crash content, associate function records with their following .go file/line records, including created by sections. Keep the existing 64 KiB read cap, Crashlytics log chunking, file retry/deletion semantics, and a safe fallback for malformed or non-stacktrace log files so reporting never drops an otherwise uploadable tombstone.

Fixes #2990

Summary by CodeRabbit

  • Bug Fixes

    • Crash reports now preserve clearer exception messages and reconstructed stack-trace details for Kotlin/JVM and Go crashes.
    • Improved handling of incomplete, malformed, and non-crash logs with safe fallback reporting and bounded messages.
  • Tests

    • Added coverage for JVM and Go crash parsing, native and unknown frames, malformed logs, and fallback labels.

@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 02793c90-85ab-43a2-8396-2d05faf70ef4

📥 Commits

Reviewing files that changed from the base of the PR and between c1b8349 and 3e38ab3.

📒 Files selected for processing (2)
  • app/src/main/java/com/celzero/bravedns/scheduler/EnhancedBugReport.kt
  • app/src/test/java/com/celzero/bravedns/scheduler/EnhancedBugReportTest.kt

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.

📜 Recent review details
🔇 Additional comments (2)
app/src/main/java/com/celzero/bravedns/scheduler/EnhancedBugReport.kt (1)

64-72: LGTM!

Also applies to: 325-327, 343-467, 554-554

app/src/test/java/com/celzero/bravedns/scheduler/EnhancedBugReportTest.kt (1)

1-110: LGTM!


📝 Walkthrough

Walkthrough

Crash report handling now reconstructs JVM and Go stack traces from report content. It extracts failure headers, preserves parsed frames in RuntimeException, and retains bounded labeled previews for malformed or non-crash logs. JUnit tests cover valid and malformed reports.

Changes

Crash report reconstruction

Layer / File(s) Summary
Exception construction and parsing
app/src/main/java/com/celzero/bravedns/scheduler/EnhancedBugReport.kt
sendFileToFirebase delegates exception creation to buildReportException. The helper identifies report types, extracts JVM or Go failure headers, parses stack frames, and applies bounded fallback messages.
Parser behavior validation
app/src/test/java/com/celzero/bravedns/scheduler/EnhancedBugReportTest.kt
Tests validate JVM and Go frame reconstruction, malformed frame handling, and labeled fallback messages with bounded lengths.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 63afc

This change preserves JVM and Go stack traces when saved tombstones are uploaded to Crashlytics without altering the existing upload flow. No actionable merge-blocking risk remains beyond normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant FirebaseUpload as sendFileToFirebase
  participant ExceptionBuilder as buildReportException
  participant CrashParsers as JVM and Go parsers

  FirebaseUpload->>ExceptionBuilder: Pass report filename and content
  ExceptionBuilder->>CrashParsers: Select parser and extract failure header
  CrashParsers-->>ExceptionBuilder: Return message and StackTraceElement frames
  ExceptionBuilder-->>FirebaseUpload: Return labeled RuntimeException
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The changes improve Crashlytics stack-trace reconstruction, but they do not investigate or fix the SQLiteFullException, address the Room/WorkManager failure path, or prevent that exception from crashi… Add or link implementation changes that address the SQLITE_FULL failure in RoomDatabase.endTransaction and the related WorkManager scheduling path. Ensure the exception no longer causes an application crash, or link the correct issue for th…
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 14 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: preserving tombstone stack traces in Crashlytics.
Out of Scope Changes check ✅ Passed The code changes are focused on Crashlytics tombstone parsing, stack-trace preservation, and bounded fallback messages. No unrelated functional changes are present.
Full details: Linked Issues check

Explanation

The changes improve Crashlytics stack-trace reconstruction, but they do not investigate or fix the SQLiteFullException, address the Room/WorkManager failure path, or prevent that exception from crashing the application as required by issue #2990.

Resolution

Add or link implementation changes that address the SQLITE_FULL failure in RoomDatabase.endTransaction and the related WorkManager scheduling path. Ensure the exception no longer causes an application crash, or link the correct issue for this Crashlytics reporting work.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread app/src/test/java/com/celzero/bravedns/scheduler/EnhancedBugReportTest.kt Dismissed

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Graphify reviewed this change.

Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).


Graphify review — findings

Reconstructs real stack traces for Crashlytics reports instead of dumping raw text: buildReportException now parses JVM frames from Kotlin tombstones and function/source-location pairs from Go crashes (including created by goroutines), sets them as the exception's stackTrace, and uses the detected exception/panic header as the message. Falls back to the previous bounded content preview (capped at MAX_EXCEPTION_PREVIEW_CHARS) when no header is found or the format is malformed, and extracts the report-type classification into a shared reportType helper. Adds EnhancedBugReportTest covering frame parsing, malformed-frame handling, and the fallback path.

No blocking issues surfaced. 4 lower-confidence candidates did not survive cross-model review.

Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 65 functions depend on the 31 functions this change touches.

Health — grade A; no new coupling hotspots.

Verification — 65 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 53 function(s) in the blast radius were not formally verified this run

@hussainmohd-a
hussainmohd-a merged commit 2b9f5b2 into celzero:main Sep 5, 2026
10 checks passed
@hussainmohd-a

Copy link
Copy Markdown
Collaborator

@mvanhorn Thanks a lot for the pull request. Merging! 💯

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.

v055u: SQLiteFullException database or disk is full in RoomDatabase.endTransaction

3 participants