Skip to content

Commit 5df4e18

Browse files
authored
Merge 322a294 into f6cdbf0
2 parents f6cdbf0 + 322a294 commit 5df4e18

9 files changed

Lines changed: 69 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
### Features
66

7+
- Add option to attach raw tombstone protobuf on native crash events ([#5446](https://github.com/getsentry/sentry-java/pull/5446))
8+
- Enable via `options.isAttachTombstone = true` or manifest: `<meta-data android:name="io.sentry.tombstone.attach" android:value="true" />`
79
- Add support to configure reporting historical ANRs via `AndroidManifest.xml` using the `io.sentry.anr.report-historical` attribute ([#5387](https://github.com/getsentry/sentry-java/pull/5387))
810

911
### Dependencies

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ public final class io/sentry/android/core/SentryAndroidOptions : io/sentry/Sentr
375375
public fun isAnrReportInDebug ()Z
376376
public fun isAttachAnrThreadDump ()Z
377377
public fun isAttachScreenshot ()Z
378+
public fun isAttachTombstone ()Z
378379
public fun isAttachViewHierarchy ()Z
379380
public fun isCollectAdditionalContext ()Z
380381
public fun isCollectExternalStorageContext ()Z
@@ -402,6 +403,7 @@ public final class io/sentry/android/core/SentryAndroidOptions : io/sentry/Sentr
402403
public fun setAnrTimeoutIntervalMillis (J)V
403404
public fun setAttachAnrThreadDump (Z)V
404405
public fun setAttachScreenshot (Z)V
406+
public fun setAttachTombstone (Z)V
405407
public fun setAttachViewHierarchy (Z)V
406408
public fun setBeforeScreenshotCaptureCallback (Lio/sentry/android/core/SentryAndroidOptions$BeforeCaptureCallback;)V
407409
public fun setBeforeViewHierarchyCaptureCallback (Lio/sentry/android/core/SentryAndroidOptions$BeforeCaptureCallback;)V

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ final class ManifestMetadataReader {
3636
static final String ANR_REPORT_HISTORICAL = "io.sentry.anr.report-historical";
3737

3838
static final String TOMBSTONE_ENABLE = "io.sentry.tombstone.enable";
39+
static final String TOMBSTONE_ATTACH = "io.sentry.tombstone.attach";
3940

4041
static final String AUTO_INIT = "io.sentry.auto-init";
4142
static final String NDK_ENABLE = "io.sentry.ndk.enable";
@@ -226,6 +227,8 @@ static void applyMetadata(
226227
options.setAnrEnabled(readBool(metadata, logger, ANR_ENABLE, options.isAnrEnabled()));
227228
options.setTombstoneEnabled(
228229
readBool(metadata, logger, TOMBSTONE_ENABLE, options.isTombstoneEnabled()));
230+
options.setAttachTombstone(
231+
readBool(metadata, logger, TOMBSTONE_ATTACH, options.isAttachTombstone()));
229232

230233
// use enableAutoSessionTracking as fallback
231234
options.setEnableAutoSessionTracking(

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,12 @@ public interface BeforeCaptureCallback {
238238
*/
239239
private boolean attachAnrThreadDump = false;
240240

241+
/**
242+
* Controls whether to send raw tombstone as an attachment with plain text. The tombstone is being
243+
* attached from {@link ApplicationExitInfo#getTraceInputStream()}, if available.
244+
*/
245+
private boolean attachTombstone = false;
246+
241247
private boolean enablePerformanceV2 = true;
242248

243249
private @Nullable SentryFrameMetricsCollector frameMetricsCollector;
@@ -643,6 +649,14 @@ public void setAttachAnrThreadDump(final boolean attachAnrThreadDump) {
643649
this.attachAnrThreadDump = attachAnrThreadDump;
644650
}
645651

652+
public boolean isAttachTombstone() {
653+
return attachTombstone;
654+
}
655+
656+
public void setAttachTombstone(final boolean attachTombstone) {
657+
this.attachTombstone = attachTombstone;
658+
}
659+
646660
/**
647661
* @return true if performance-v2 is enabled. See {@link #setEnablePerformanceV2(boolean)} for
648662
* more details.

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import io.sentry.transport.ICurrentDateProvider;
3737
import io.sentry.util.HintUtils;
3838
import io.sentry.util.Objects;
39+
import java.io.ByteArrayInputStream;
40+
import java.io.ByteArrayOutputStream;
3941
import java.io.Closeable;
4042
import java.io.IOException;
4143
import java.io.InputStream;
@@ -150,6 +152,7 @@ public boolean shouldReportHistorical() {
150152
public @Nullable ApplicationExitInfoHistoryDispatcher.Report buildReport(
151153
final @NotNull ApplicationExitInfo exitInfo, final boolean enrich) {
152154
SentryEvent event;
155+
final byte[] rawTombstone;
153156
try {
154157
final InputStream tombstoneInputStream = exitInfo.getTraceInputStream();
155158
if (tombstoneInputStream == null) {
@@ -163,9 +166,11 @@ public boolean shouldReportHistorical() {
163166
return null;
164167
}
165168

169+
rawTombstone = readBytes(tombstoneInputStream);
170+
166171
try (final TombstoneParser parser =
167172
new TombstoneParser(
168-
tombstoneInputStream,
173+
new ByteArrayInputStream(rawTombstone),
169174
this.options.getInAppIncludes(),
170175
this.options.getInAppExcludes(),
171176
this.context.getApplicationInfo().nativeLibraryDir)) {
@@ -190,6 +195,10 @@ public boolean shouldReportHistorical() {
190195
options.getFlushTimeoutMillis(), options.getLogger(), tombstoneTimestamp, enrich);
191196
final Hint hint = HintUtils.createWithTypeCheckHint(tombstoneHint);
192197

198+
if (options.isAttachTombstone()) {
199+
hint.setTombstone(Attachment.fromTombstone(rawTombstone));
200+
}
201+
193202
try {
194203
final @Nullable SentryEvent mergedEvent =
195204
mergeWithMatchingNativeEvents(tombstoneTimestamp, event, hint);
@@ -304,6 +313,17 @@ private void mergeNativeCrashes(
304313
nativeEvent.setThreads(tombstoneThreads);
305314
}
306315
}
316+
317+
private byte[] readBytes(final @NotNull InputStream stream) throws IOException {
318+
try (final ByteArrayOutputStream buffer = new ByteArrayOutputStream()) {
319+
int nRead;
320+
final byte[] data = new byte[1024];
321+
while ((nRead = stream.read(data, 0, data.length)) != -1) {
322+
buffer.write(data, 0, nRead);
323+
}
324+
return buffer.toByteArray();
325+
}
326+
}
307327
}
308328

309329
@ApiStatus.Internal

sentry/api/sentry.api

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public final class io/sentry/Attachment {
1919
public static fun fromByteProvider (Ljava/util/concurrent/Callable;Ljava/lang/String;Ljava/lang/String;Z)Lio/sentry/Attachment;
2020
public static fun fromScreenshot ([B)Lio/sentry/Attachment;
2121
public static fun fromThreadDump ([B)Lio/sentry/Attachment;
22+
public static fun fromTombstone ([B)Lio/sentry/Attachment;
2223
public static fun fromViewHierarchy (Lio/sentry/protocol/ViewHierarchy;)Lio/sentry/Attachment;
2324
public fun getAttachmentType ()Ljava/lang/String;
2425
public fun getByteProvider ()Ljava/util/concurrent/Callable;
@@ -613,13 +614,15 @@ public final class io/sentry/Hint {
613614
public fun getReplayRecording ()Lio/sentry/ReplayRecording;
614615
public fun getScreenshot ()Lio/sentry/Attachment;
615616
public fun getThreadDump ()Lio/sentry/Attachment;
617+
public fun getTombstone ()Lio/sentry/Attachment;
616618
public fun getViewHierarchy ()Lio/sentry/Attachment;
617619
public fun remove (Ljava/lang/String;)V
618620
public fun replaceAttachments (Ljava/util/List;)V
619621
public fun set (Ljava/lang/String;Ljava/lang/Object;)V
620622
public fun setReplayRecording (Lio/sentry/ReplayRecording;)V
621623
public fun setScreenshot (Lio/sentry/Attachment;)V
622624
public fun setThreadDump (Lio/sentry/Attachment;)V
625+
public fun setTombstone (Lio/sentry/Attachment;)V
623626
public fun setViewHierarchy (Lio/sentry/Attachment;)V
624627
public static fun withAttachment (Lio/sentry/Attachment;)Lio/sentry/Hint;
625628
public static fun withAttachments (Ljava/util/List;)Lio/sentry/Hint;

sentry/src/main/java/io/sentry/Attachment.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,4 +396,14 @@ boolean isAddToTransactions() {
396396
public static @NotNull Attachment fromThreadDump(final byte[] bytes) {
397397
return new Attachment(bytes, "thread-dump.txt", "text/plain", false);
398398
}
399+
400+
/**
401+
* Creates a new Tombstone Attachment
402+
*
403+
* @param bytes the array bytes
404+
* @return the Attachment
405+
*/
406+
public static @NotNull Attachment fromTombstone(final byte[] bytes) {
407+
return new Attachment(bytes, "tombstone.pb", "application/x-protobuf", false);
408+
}
399409
}

sentry/src/main/java/io/sentry/Hint.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public final class Hint {
3232
private @Nullable Attachment screenshot = null;
3333
private @Nullable Attachment viewHierarchy = null;
3434
private @Nullable Attachment threadDump = null;
35+
private @Nullable Attachment tombstone = null;
3536
private @Nullable ReplayRecording replayRecording = null;
3637

3738
public static @NotNull Hint withAttachment(@Nullable Attachment attachment) {
@@ -147,6 +148,14 @@ public void setThreadDump(final @Nullable Attachment threadDump) {
147148
return threadDump;
148149
}
149150

151+
public void setTombstone(final @Nullable Attachment tombstone) {
152+
this.tombstone = tombstone;
153+
}
154+
155+
public @Nullable Attachment getTombstone() {
156+
return tombstone;
157+
}
158+
150159
@Nullable
151160
public ReplayRecording getReplayRecording() {
152161
return replayRecording;

sentry/src/main/java/io/sentry/SentryClient.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,11 @@ private boolean shouldSendSessionUpdateForDroppedEvent(
399399
attachments.add(threadDump);
400400
}
401401

402+
@Nullable final Attachment tombstone = hint.getTombstone();
403+
if (tombstone != null) {
404+
attachments.add(tombstone);
405+
}
406+
402407
return attachments;
403408
}
404409

0 commit comments

Comments
 (0)