Resources

Crash Reporting for App Developers: Fix Missing Symbols and ANRs

Set up app crash reporting with readable symbols, ANR coverage, logs that protect privacy, and a fast triage workflow to catch release regressions early.

Alex Dow

Article by

Alex Dow

Resources

•

10

mins to read

Crash Reporting for App Developers: Fix Missing Symbols and ANRs

Crash reporting sketch title card

Crash reporting captures crashes and contextual signals, symbolicates stack traces, and groups issues so your team fixes the highest-impact regressions fast. The key choices are whether you report from an in-app SDK, from platform diagnostics, or from both, and how you handle symbol uploads and privacy controls. Watch the user-perceived crash rate first, since store signals shape your app’s visibility.


TL;DR:

  • Android Vitals flags user perceived crash rates above 1.09% overall, 8% per phone model, or 4% per watch model; data arrives 24–48 hours late.
  • Automate Android mapping file and Apple dSYM uploads in CI, and fail builds when uploads break; otherwise obfuscated traces and raw addresses impede diagnosis.
  • Keep tokens, personal data, cookies, and full request or response bodies out of reports; use high level breadcrumbs and test payloads for leaks.
  • SDK reporting supplies rapid alerts, while platform diagnostics add OS level coverage with delays; running both broadens visibility but increases maintenance.
  • Prioritize issues by affected users and new release regressions, verify symbolication first, then reproduce using breadcrumbs, device details, and session context.

Let’s Build My App
Build More Reliable Apps
Let’s Build My App develops and supports web and mobile applications, helping teams address engineering needs from launch through post-launch maintenance.
Explore app development

Table of Contents

How does crash reporting work from capture to storage?

Every crash reporting pipeline has several moving parts: capture, grouping, symbolication, and storage. Knowing each one tells you what to integrate and where reports tend to break.

Capture covers more than fatal crashes. A solid setup records:

  • Unhandled exceptions and native signals
  • ANRs and hangs, where the app freezes instead of closing
  • Non-fatal errors your code catches but still wants to count
  • Breadcrumbs and session metadata, such as the screen, device model, and OS version

Grouping turns thousands of raw events into a short list of issues. When similar stack traces land in one bucket, you triage a handful of problems instead of a flood. Poor grouping hides regressions inside noise, so check how your tool groups before you trust its counts.

Symbolication converts raw memory addresses into readable function names. It depends on debug symbols: dSYM files on Apple platforms and mapping files on Android. On Apple platforms, missing dSYM files leave crash logs as raw addresses that are unusable until the symbols are re-mapped or uploaded.

Debug symbols translate raw crash addresses

Finally, consider where events come from. SDK events arrive in near real time, while platform diagnostics are tied to the OS or store and can lag. Many teams run both so they get speed from one and coverage from the other. Firebase Crashlytics is one example of an SDK that offers real-time reporting, issue grouping, and non-fatal logging across iOS, Android, Flutter, and Unity.

Which crash metrics and platform signals should you watch?

Which crash metrics and platform signals should you watch? — overview diagram

Start with the user-perceived crash rate. It counts crashes that users actually notice while using the app in the foreground, which is different from raw session-level counts in an SDK. A crash in a background process may never show up in this number, so the two views can disagree.

Google gives you hard lines to work with. Android Vitals flags bad behavior when the user-perceived crash rate passes a threshold:

Android Vitals bad-behavior thresholds: 1.09% overall, 8% per phone model, and 4% per watch model. Play Console measures the last 28 days of data, so crossing a line is a signal to act before store visibility suffers.

Keep in mind that Play Console data has a 24 to 48 hour delay. It complements real-time SDK reporting and does not replace it. Google also notes that Android vitals affects app visibility on Google Play.

On your own dashboard, track these KPIs:

  • Crash-free users and crash-free sessions
  • Affected users per issue
  • Regressions by release
  • ANR rate
  • Crash distribution by device model

Device model breakdowns matter most. One bad model can push you over a per-model threshold even when your overall rate looks healthy.

What platform setup tasks keep reports readable?

Most broken crash reporting comes down to symbols that never reached your tool. Automate these steps in CI so no release ships blind:

  1. Android mapping files: Make sure your build generates R8 or ProGuard mapping files, and upload them from CI on every release build. Without them, obfuscated traces are unreadable.
  2. Apple dSYM files: Configure Xcode to produce dSYMs and upload them automatically. Crashlytics for Apple platforms needs Xcode set up to upload dSYM files and recommends forcing a test crash to confirm reporting works.
  3. MetricKit diagnostics: MetricKit delivers on-device reports for crashes, hangs, and memory exceptions to your app on its next launch, so you can forward them to your backend. Use Xcode Organizer and TestFlight feedback for faster early triage.
  4. Native and NDK symbols: Upload native symbol files separately, and confirm your SDK or pipeline supports native crash symbolication.
  5. Android configuration: The Crashlytics Android setup adds a Gradle plugin and handles crashes, non-fatal errors, and ANRs once configured.

Pro Tip: Fail the CI build when a symbol or mapping upload fails. A red build costs minutes, while a release full of unreadable crashes costs days.

How do you log crash context without exposing private data?

Good crash context helps you reproduce a bug. Careless context turns your reports into a data leak. OWASP’s logging guidance says logs should carry useful context, avoid noise, and never include secrets that could harm the application if exposed.

Apply these rules to production crash reports:

  • Never include personal data, session tokens, cookies, or full request and response bodies.
  • Redact or mask sensitive fields before they leave the device.
  • Use logging levels and compile-time flags to strip verbose debug logs from release builds.
  • Record breadcrumbs as high-level actions, such as “opened checkout”, not raw field values.
  • Keep only the data you need to debug, and set a short retention window.

OWASP’s mobile guidance on sensitive data in logs backs the same approach: mask values where needed and disable verbose logging in production.

Pro Tip: Add a test that fails if a known fake token or email address ever appears in a generated crash payload.

What does a fast crash triage workflow look like?

A repeatable routine keeps your team from chasing noisy issues. Prioritize by affected users, regression status, and severity. A crash that hit many users, or one that appeared in the latest release, goes first.

Then work each issue in this order:

  1. Confirm symbolication. If the trace shows raw addresses, fix the symbol upload before anything else.
  2. Inspect breadcrumbs and session data. Look at what the user did and which device and OS version were involved.
  3. Reproduce the crash. Use instrumentation or device logs. Session replay can help here: Sentry’s mobile replay can attach up to 30 seconds of session context to an error event when the SDK supports it and sampling is configured.
  4. Fix and release. Ship the patch with a clear note on which issue it targets.
  5. Monitor the result. Check that the issue stops appearing and that no new regression replaces it.

Our bug triage process goes deeper on prioritization if you want to build a longer routine for your team.

How do you choose between SDK-first, platform-first, and hybrid?

Pick the pattern that fits your risk and your resources. Weigh these criteria:

  • Integration effort
  • Symbolication automation
  • Real-time alerting needs
  • Offline resilience
  • Privacy and compliance constraints
  • Cost model, such as events versus seats

Three patterns cover most teams:

  • SDK-first: Fast to set up with rich features and real-time alerts. You depend on the SDK vendor and must manage symbol uploads.
  • Platform-first: Built on OS and store diagnostics. Less to integrate, but data can arrive late and coverage is narrower.
  • Hybrid: The widest coverage, since each source fills the other’s gaps. It takes more work to maintain.

To compare them, score each pattern from 1 to 5 on every criterion, multiply by a weight that reflects your priorities, and add up the results. Say your app handles payments and needs instant alerts: weight real-time alerting and privacy at 3, and effort at 1. A team with a tiny staff and low risk might flip those weights. The totals show which pattern matches your situation without guesswork.

What should you verify before release?

Run through this checklist before every production launch:

  1. Integrate the SDK or diagnostic listener and confirm it is enabled in release builds.
  2. Automate symbol and mapping uploads in CI.
  3. Turn on breadcrumbs and offline caching.
  4. Force a test crash and confirm it appears symbolicated in the dashboard.
  5. Watch the dashboard closely after release.

Why we treat crash reporting as part of delivery

We bake crash reporting into every project from the first build, not after launch. When symbol uploads and monitoring live in CI, triage gets faster because every report arrives readable. We integrate crash reporting early in the development process. We put crash reporting on the release checklist next to testing, not in the optional pile.

— Alex

Let us set up crash reporting for you

If you would rather ship features than wire up pipelines, we handle it. We integrate reporting into CI, automate symbol uploads, and set up dashboards and triage workflows as part of our MVP development and post-launch support. Pricing is fixed, so you know the cost up front, and our plans are listed in full. Ready to talk? Scope your project with us.

Let’s Build My App

FAQ

How do you get a crash report on iOS?

Add a crash reporting SDK and make sure your dSYM files upload automatically, or use MetricKit to receive on-device diagnostics. You can also check Xcode Organizer and TestFlight feedback. Force a test crash to confirm reports arrive symbolicated.

How do you report app problems as a developer?

Capture crashes automatically with an SDK, and log non-fatal errors with context such as breadcrumbs and device details. Keep personal data out of every report. Group issues by cause so your team sees the highest-impact problems first.

Which apps and platforms have crash detection?

Most mobile stacks support it. Firebase Crashlytics covers iOS, Android, Flutter, and Unity, and some React Native SDKs add automatic native crash tracking and ANR detection. Platform tools such as Android Vitals and MetricKit add OS-level coverage.

Why do my crash reports show memory addresses instead of function names?

The debug symbols never reached your reporting tool. On Apple platforms that means missing dSYM files, and on Android it means missing mapping files. Fix the upload step in CI and verify it with a test crash.

Sources

About Let’s Build My App

Let’s Build My App is a US-based AI development agency. We design, build, and launch production-grade custom software using AI coding tools including Claude Code and OpenAI Codex, and we migrate legacy Bubble apps onto AI-coded stacks such as React, Supabase, and Firebase. We are the #1 US-Based Bubble Agency, founded and run by Alex Dow. Book a free strategy call to scope your project.

You liked this article ? Share it!

Ready to turn
your idea into reality?

LetsBuildMyApp Team is ready to take on your challenge. Contact us for a free quote today!

Alex Dow, founder of Let's Build My App

Got a question?

We have an answer for you! 

How can I get a quote?

Jump on a free strategy call with our founder, Alex. You can schedule here or reach out to us directly.

How long will it take to complete my project?

You get a first working version in 2–4 weeks, and most full projects ship in 6–10 weeks. Timeline depends on feature complexity. Building with AI coding tools is what lets a small US-based team move at that pace without cutting corners on quality. Schedule a call for an exact estimate based on your scope.

What is AI-powered app development?

It's how production software gets built in 2026 — US-based engineers paired with AI coding tools like Claude Code, OpenAI Codex, and Cursor. You get real production code (React, Next.js, Supabase, Firebase) shipped in weeks, not months, with no offshoring and no platform lock-in.

Can AI-coded apps handle complex production workloads?

Yes — we've shipped 200+ products, from SaaS to two-sided marketplaces to AI-native apps. Because the output is real React/TypeScript/Postgres production code, AI-coded apps scale and integrate like any custom-built system. No platform ceiling, no vendor lock-in.

What happens after the application is deployed?

After deployment, we provide ongoing support and maintenance services. This includes regular updates, bug fixes, and addressing any changes. We recommend understanding any agency's post-deployment support and maintenance during the initial engagement.