Skip to content

Commit a183163

Browse files
authored
Do not report parsing ANR error when there are no threads (#3888)
* Ensure android event processors are added even if options configuration block throws * Changelog * Do not report parsing ANR error when there are no threads * Changelog * Fix tests
1 parent 091f84e commit a183163

File tree

5 files changed

+1093
-7
lines changed

5 files changed

+1093
-7
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
### Fixes
1111

1212
- Ensure android initialization process continues even if options configuration block throws an exception ([#3887](https://github.com/getsentry/sentry-java/pull/3887))
13+
- Do not report parsing ANR error when there are no threads ([#3888](https://github.com/getsentry/sentry-java/pull/3888))
14+
- This should significantly reduce the number of events with message "Sentry Android SDK failed to parse system thread dump..." reported
1315

1416
### Dependencies
1517

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,11 @@ private void reportAsSentryEvent(
313313
final ThreadDumpParser threadDumpParser = new ThreadDumpParser(options, isBackground);
314314
final List<SentryThread> threads = threadDumpParser.parse(lines);
315315
if (threads.isEmpty()) {
316-
// if the list is empty this means our regex matching is garbage and this is still error
317-
return new ParseResult(ParseResult.Type.ERROR, dump);
316+
// if the list is empty this means the system failed to capture a proper thread dump of
317+
// the android threads, and only contains kernel-level threads and statuses, those ANRs
318+
// are not actionable and neither they are reported by Google Play Console, so we just
319+
// fall back to not reporting them
320+
return new ParseResult(ParseResult.Type.NO_DUMP);
318321
}
319322
return new ParseResult(ParseResult.Type.DUMP, dump, threads);
320323
} catch (Throwable e) {

sentry-android-core/src/test/java/io/sentry/android/core/AnrV2IntegrationTest.kt

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ class AnrV2IntegrationTest {
101101
reason: Int? = ApplicationExitInfo.REASON_ANR,
102102
timestamp: Long? = null,
103103
importance: Int? = null,
104-
addTrace: Boolean = true
104+
addTrace: Boolean = true,
105+
addBadTrace: Boolean = false
105106
) {
106107
val builder = ApplicationExitInfoBuilder.newBuilder()
107108
if (reason != null) {
@@ -117,8 +118,36 @@ class AnrV2IntegrationTest {
117118
if (!addTrace) {
118119
return
119120
}
120-
whenever(mock.traceInputStream).thenReturn(
121-
"""
121+
if (addBadTrace) {
122+
whenever(mock.traceInputStream).thenReturn(
123+
"""
124+
Subject: Input dispatching timed out (7985007 com.example.app/com.example.app.ui.MainActivity (server) is not responding. Waited 5000ms for FocusEvent(hasFocus=false))
125+
Here are no Binder-related exception messages available.
126+
Pid(12233) have D state thread(tid:12236 name:Signal Catcher)
127+
128+
129+
RssHwmKb: 823716
130+
RssKb: 548348
131+
RssAnonKb: 382156
132+
RssShmemKb: 13304
133+
VmSwapKb: 82484
134+
135+
136+
--- CriticalEventLog ---
137+
capacity: 20
138+
timestamp_ms: 1731507490032
139+
window_ms: 300000
140+
141+
----- dumping pid: 12233 at 313446151
142+
libdebuggerd_client: unexpected registration response: 0
143+
144+
----- Waiting Channels: pid 12233 at 2024-11-13 19:48:09.980104540+0530 -----
145+
Cmd line: com.example.app:mainProcess
146+
""".trimIndent().byteInputStream()
147+
)
148+
} else {
149+
whenever(mock.traceInputStream).thenReturn(
150+
"""
122151
"main" prio=5 tid=1 Blocked
123152
| group="main" sCount=1 ucsCount=0 flags=1 obj=0x72a985e0 self=0xb400007cabc57380
124153
| sysTid=28941 nice=-10 cgrp=top-app sched=0/0 handle=0x7deceb74f8
@@ -147,8 +176,9 @@ class AnrV2IntegrationTest {
147176
native: #02 pc 00000000000b63b0 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)
148177
native: #03 pc 00000000000530b8 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)
149178
(no managed stack frames)
150-
""".trimIndent().byteInputStream()
151-
)
179+
""".trimIndent().byteInputStream()
180+
)
181+
}
152182
}
153183
shadowActivityManager.addApplicationExitInfo(exitInfo)
154184
}
@@ -551,4 +581,14 @@ class AnrV2IntegrationTest {
551581

552582
verify(fixture.hub, never()).captureEvent(any(), anyOrNull<Hint>())
553583
}
584+
585+
@Test
586+
fun `when traceInputStream has bad data, does not report ANR`() {
587+
val integration = fixture.getSut(tmpDir, lastReportedAnrTimestamp = oldTimestamp)
588+
fixture.addAppExitInfo(timestamp = newTimestamp, addBadTrace = true)
589+
590+
integration.register(fixture.hub, fixture.options)
591+
592+
verify(fixture.hub, never()).captureEvent(any(), anyOrNull<Hint>())
593+
}
554594
}

sentry-android-core/src/test/java/io/sentry/android/core/internal/threaddump/ThreadDumpParserTest.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import kotlin.test.Test
77
import kotlin.test.assertEquals
88
import kotlin.test.assertNotNull
99
import kotlin.test.assertNull
10+
import kotlin.test.assertTrue
1011

1112
class ThreadDumpParserTest {
1213

@@ -95,4 +96,15 @@ class ThreadDumpParserTest {
9596
assertEquals(28, lastFrame.lineno)
9697
assertNull(lastFrame.isInApp)
9798
}
99+
100+
@Test
101+
fun `thread dump garbage`() {
102+
val lines = Lines.readLines(File("src/test/resources/thread_dump_bad_data.txt"))
103+
val parser = ThreadDumpParser(
104+
SentryOptions().apply { addInAppInclude("io.sentry.samples") },
105+
false
106+
)
107+
val threads = parser.parse(lines)
108+
assertTrue(threads.isEmpty())
109+
}
98110
}

0 commit comments

Comments
 (0)