Skip to content

fix(android): Backfill pre-init ANR and native crash metadata#5762

Open
romtsn wants to merge 10 commits into
mainfrom
romtsn/fix/validate-app-update-timestamp
Open

fix(android): Backfill pre-init ANR and native crash metadata#5762
romtsn wants to merge 10 commits into
mainfrom
romtsn/fix/validate-app-update-timestamp

Conversation

@romtsn

@romtsn romtsn commented Jul 14, 2026

Copy link
Copy Markdown
Member

📜 Description

Backfill release, environment, distribution (dist), and app version/build on ANR and native crash events from the current SDK options when persisted values are unavailable.

This covers exits that happen before SDK initialization, when the SDK has not yet persisted those options. Current values are used only when the app has not been updated since the exit. A missing or invalid package update timestamp is treated conservatively so historical events are not attributed to a newer app version.

💡 Motivation and Context

ANR and native crash events are reported from ApplicationExitInfo on the next SDK initialization. If the terminated process exited before initializing the SDK, release-related options were never persisted and the reported event can be missing useful metadata.

The reporting process already has the same values in its current options when the package has not been updated. Comparing the exit timestamp with PackageInfo.lastUpdateTime allows those values to be used without attaching metadata from a newer app version.

Closes #4227
Closes #3287

💚 How did you test it?

  • ./gradlew ':sentry-android-core:testDebugUnitTest' --tests='*ApplicationExitInfoEventProcessorTest*' --info (42 tests passed)
  • ./gradlew spotlessApply apiDump

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.

🔮 Next steps

None.

Use current options when persisted values are missing and the app has not been updated since the exit. Avoid attributing historical crashes to a newer app version.
@sentry

sentry Bot commented Jul 14, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.49.0 (1) release

⚙️ sentry-android Build Distribution Settings

@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 316.81 ms 364.28 ms 47.47 ms
Size 0 B 0 B 0 B

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
382d6c1 306.85 ms 368.70 ms 61.85 ms
e63ad34 323.67 ms 390.33 ms 66.67 ms
91bb874 310.68 ms 359.24 ms 48.56 ms
5865051 324.24 ms 356.02 ms 31.78 ms
806307f 357.85 ms 424.64 ms 66.79 ms
b193867 331.08 ms 397.06 ms 65.98 ms
0eaac1e 322.53 ms 389.31 ms 66.78 ms
6405ec5 310.88 ms 354.56 ms 43.69 ms
d15471f 310.66 ms 368.19 ms 57.53 ms
951caf7 323.66 ms 392.82 ms 69.16 ms

App size

Revision Plain With Sentry Diff
382d6c1 1.58 MiB 2.29 MiB 719.85 KiB
e63ad34 0 B 0 B 0 B
91bb874 1.58 MiB 2.13 MiB 559.07 KiB
5865051 0 B 0 B 0 B
806307f 1.58 MiB 2.10 MiB 533.42 KiB
b193867 1.58 MiB 2.19 MiB 620.00 KiB
0eaac1e 1.58 MiB 2.19 MiB 619.17 KiB
6405ec5 1.58 MiB 2.12 MiB 552.23 KiB
d15471f 1.58 MiB 2.13 MiB 559.54 KiB
951caf7 1.58 MiB 2.13 MiB 558.77 KiB

Previous results on branch: romtsn/fix/validate-app-update-timestamp

Startup times

Revision Plain With Sentry Diff
d4ce194 321.51 ms 369.29 ms 47.78 ms
25fde38 314.47 ms 363.17 ms 48.70 ms
22c1033 369.33 ms 441.47 ms 72.14 ms
7a20e16 323.59 ms 368.29 ms 44.70 ms
17b29d9 311.50 ms 357.90 ms 46.40 ms
d19c570 292.57 ms 374.07 ms 81.50 ms

App size

Revision Plain With Sentry Diff
d4ce194 0 B 0 B 0 B
25fde38 0 B 0 B 0 B
22c1033 0 B 0 B 0 B
7a20e16 0 B 0 B 0 B
17b29d9 0 B 0 B 0 B
d19c570 0 B 0 B 0 B

@romtsn romtsn changed the title fix(android): Backfill exit options when app is unchanged fix(android): Backfill pre-init ANR and native crash metadata Jul 15, 2026
@romtsn romtsn marked this pull request as ready for review July 15, 2026 07:58
romtsn and others added 2 commits July 15, 2026 11:22
Populate app version and build for historical ANR and native crash events when the current package metadata is safe to use.

Co-Authored-By: Codex <noreply@openai.com>
Backfill only app version and build for historical exits. Avoid attaching current localized app names, identifiers, or split APK state to older events.

Co-Authored-By: Codex <noreply@openai.com>

@markushi markushi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Mostly minor nits, apart from the return handling of isAppNotUpdated()

return true;
}

final PackageInfo packageInfo = ContextUtils.getPackageInfo(context, buildInfoProvider);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
final PackageInfo packageInfo = ContextUtils.getPackageInfo(context, buildInfoProvider);
final @Nullable PackageInfo packageInfo = ContextUtils.getPackageInfo(context, buildInfoProvider);

timestamp = null;
}
if (timestamp == null) {
return true;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

shouldn't this be false? If we don't know the crash time, we can't say for sure if there was an update in between between the crash and now or not.

Suggested change
return true;
return false;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in e017d22. Unknown timestamps now fail closed, with a regression test confirming current release metadata is not used.

private void setDist(final @NotNull SentryBaseEvent event, final boolean canUseCurrentOptions) {
if (event.getDist() == null) {
final String dist = PersistingOptionsObserver.read(options, DIST_FILENAME, String.class);
String dist = PersistingOptionsObserver.read(options, DIST_FILENAME, String.class);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
String dist = PersistingOptionsObserver.read(options, DIST_FILENAME, String.class);
@Nullable String dist = PersistingOptionsObserver.read(options, DIST_FILENAME, String.class);

Do not use current SDK options when an exit timestamp is unavailable because an intervening app update cannot be ruled out.

Co-Authored-By: Codex <noreply@openai.com>
romtsn and others added 2 commits July 16, 2026 11:11
Persist the app update timestamp after writing the options snapshot. Trust cached release, environment, and dist only when the marker identifies the current app installation, preserving launch-specific values without leaking stale metadata across app updates.

Co-Authored-By: Codex <noreply@openai.com>
Apply the app-generation marker when selecting option tags and the replay-on-error sample rate. Preserve values from the crashed launch within one app version while rejecting stale values after an update.

Co-Authored-By: Codex <noreply@openai.com>
Document why the generation observer uses its release callback only after the options cache has been fully persisted.

Co-Authored-By: Codex <noreply@openai.com>

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a7436f4. Configure here.

romtsn and others added 2 commits July 16, 2026 13:53
Reject option caches created after an exit and keep immutable build metadata aligned with the event's app generation. This prevents intermediate releases and stale ProGuard or SDK metadata from being attached to historical exits.

Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: OpenAI Codex <noreply@openai.com>
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.

Auto release detection not working Enrich ANRs happened before Sentry.init

2 participants