Skip to content

Commit 3636c81

Browse files
feat: merge tombstone and native sdk events (#5037)
* feat: merge tombstone and native sdk events * add preliminary change log * add preliminary change log * apply review+sync feedback * add tombstone manifest flag * remove tombstone-native correlation via processStateSummary * 2-phase streaming NativeEventCollector (#5065) * extract inner inApp check into a reusable static method * reduce I/O in the collect() method of the NativeEventCollector. * add native attachments to TombstoneHint. * introduce VMA -> module coalescing via ModuleAccumulator * ensure native crash survives the merge * handle null nativeLibraryDir in TombstoneParser * clarify inApp vs nativeLibraryDir usage in code comment * ignore stack frames from anonymous VMAs that don't resolve to a function name * use the right nativeLibraryDir for the tombstone test fixture * add proguard rule for protobuf-lite * make BoundedInputStream safer wrt double closes * override empty function name behavior from SentryStackTraceFactory.isInApp() because it applies to class-names generically whereas we use it only for function name prefixes. * pre merge preps. --------- Co-authored-by: Markus Hintersteiner <markus.hintersteiner@sentry.io>
1 parent 319f256 commit 3636c81

27 files changed

Lines changed: 1506 additions & 39 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.DS_Store
2+
.java-version
23
.idea/
34
.gradle/
45
.run/

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,20 @@
1515
sentry:
1616
enable-database-transaction-tracing: true
1717
```
18+
- Add support for collecting native crashes using Tombstones ([#4933](https://github.com/getsentry/sentry-java/pull/4933), [#5037](https://github.com/getsentry/sentry-java/pull/5037))
19+
- Added Tombstone integration that detects native crashes using `ApplicationExitInfo.REASON_CRASH_NATIVE` on Android 12+
20+
- Crashes enriched with Tombstones contain more crash details and detailed thread info
21+
- Tombstone and NDK integrations are now automatically merged into a single crash event, eliminating duplicate reports
22+
- To enable it, add the integration in your Sentry initialization:
23+
```kotlin
24+
SentryAndroid.init(context, options -> {
25+
options.isTombstoneEnabled = true
26+
})
27+
```
28+
or in the `AndroidManifest.xml` using:
29+
```xml
30+
<meta-data android:name="io.sentry.tombstone.enable" android:value="true" />
31+
```
1832

1933
### Fixes
2034

sentry-android-core/api/sentry-android-core.api

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,19 @@ public final class io/sentry/android/core/LoadClass : io/sentry/util/LoadClass {
291291
public fun loadClass (Ljava/lang/String;Lio/sentry/ILogger;)Ljava/lang/Class;
292292
}
293293

294+
public final class io/sentry/android/core/NativeEventCollector {
295+
public fun <init> (Lio/sentry/android/core/SentryAndroidOptions;)V
296+
public fun collect ()V
297+
public fun deleteNativeEventFile (Lio/sentry/android/core/NativeEventCollector$NativeEventData;)Z
298+
public fun findAndRemoveMatchingNativeEvent (J)Lio/sentry/android/core/NativeEventCollector$NativeEventData;
299+
}
300+
301+
public final class io/sentry/android/core/NativeEventCollector$NativeEventData {
302+
public fun getEnvelope ()Lio/sentry/SentryEnvelope;
303+
public fun getEvent ()Lio/sentry/SentryEvent;
304+
public fun getFile ()Ljava/io/File;
305+
}
306+
294307
public final class io/sentry/android/core/NdkHandlerStrategy : java/lang/Enum {
295308
public static final field SENTRY_HANDLER_STRATEGY_CHAIN_AT_START Lio/sentry/android/core/NdkHandlerStrategy;
296309
public static final field SENTRY_HANDLER_STRATEGY_DEFAULT Lio/sentry/android/core/NdkHandlerStrategy;
@@ -500,7 +513,7 @@ public final class io/sentry/android/core/TombstoneIntegration$TombstoneHint : i
500513
}
501514

502515
public class io/sentry/android/core/TombstoneIntegration$TombstonePolicy : io/sentry/android/core/ApplicationExitInfoHistoryDispatcher$ApplicationExitInfoPolicy {
503-
public fun <init> (Lio/sentry/android/core/SentryAndroidOptions;)V
516+
public fun <init> (Lio/sentry/android/core/SentryAndroidOptions;Landroid/content/Context;)V
504517
public fun buildReport (Landroid/app/ApplicationExitInfo;Z)Lio/sentry/android/core/ApplicationExitInfoHistoryDispatcher$Report;
505518
public fun getLabel ()Ljava/lang/String;
506519
public fun getLastReportedTimestamp ()Ljava/lang/Long;

sentry-android-core/proguard-rules.pro

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@
5454

5555
-keepnames class io.sentry.android.core.ApplicationNotResponding
5656

57+
# protobuf-java lite
58+
# https://github.com/protocolbuffers/protobuf/blob/5d876c9fec1a6f2feb0750694f803f89312bffff/java/lite.md#r8-rule-to-make-production-app-builds-work
59+
-keep class * extends com.google.protobuf.GeneratedMessageLite { *; }
60+
5761
##---------------End: proguard configuration for android-core ----------
5862

5963
##---------------Begin: proguard configuration for sentry-apollo-3 ----------

sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ static void initializeIntegrationsAndProcessors(
244244
if (options.getSocketTagger() instanceof NoOpSocketTagger) {
245245
options.setSocketTagger(AndroidSocketTagger.getInstance());
246246
}
247+
247248
if (options.getPerformanceCollectors().isEmpty()) {
248249
options.addPerformanceCollector(new AndroidMemoryCollector());
249250
options.addPerformanceCollector(new AndroidCpuCollector(options.getLogger()));

sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ final class ManifestMetadataReader {
3434
static final String ANR_TIMEOUT_INTERVAL_MILLIS = "io.sentry.anr.timeout-interval-millis";
3535
static final String ANR_ATTACH_THREAD_DUMPS = "io.sentry.anr.attach-thread-dumps";
3636

37+
static final String TOMBSTONE_ENABLE = "io.sentry.tombstone.enable";
38+
3739
static final String AUTO_INIT = "io.sentry.auto-init";
3840
static final String NDK_ENABLE = "io.sentry.ndk.enable";
3941
static final String NDK_SCOPE_SYNC_ENABLE = "io.sentry.ndk.scope-sync.enable";
@@ -205,6 +207,8 @@ static void applyMetadata(
205207
}
206208

207209
options.setAnrEnabled(readBool(metadata, logger, ANR_ENABLE, options.isAnrEnabled()));
210+
options.setTombstoneEnabled(
211+
readBool(metadata, logger, TOMBSTONE_ENABLE, options.isTombstoneEnabled()));
208212

209213
// use enableAutoSessionTracking as fallback
210214
options.setEnableAutoSessionTracking(

0 commit comments

Comments
 (0)