Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not report parsing ANR error when there are no threads #3888

Merged
merged 7 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
### Fixes

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

### Dependencies

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,11 @@ private void reportAsSentryEvent(
final ThreadDumpParser threadDumpParser = new ThreadDumpParser(options, isBackground);
final List<SentryThread> threads = threadDumpParser.parse(lines);
if (threads.isEmpty()) {
// if the list is empty this means our regex matching is garbage and this is still error
return new ParseResult(ParseResult.Type.ERROR, dump);
// if the list is empty this means the system failed to capture a proper thread dump of
// the android threads, and only contains kernel-level threads and statuses, those ANRs
// are not actionable and neither they are reported by Google Play Console, so we just
// fall back to not reporting them
return new ParseResult(ParseResult.Type.NO_DUMP);
}
return new ParseResult(ParseResult.Type.DUMP, dump, threads);
} catch (Throwable e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ class AnrV2IntegrationTest {
reason: Int? = ApplicationExitInfo.REASON_ANR,
timestamp: Long? = null,
importance: Int? = null,
addTrace: Boolean = true
addTrace: Boolean = true,
addBadTrace: Boolean = false
) {
val builder = ApplicationExitInfoBuilder.newBuilder()
if (reason != null) {
Expand All @@ -117,8 +118,36 @@ class AnrV2IntegrationTest {
if (!addTrace) {
return
}
whenever(mock.traceInputStream).thenReturn(
"""
if (addBadTrace) {
whenever(mock.traceInputStream).thenReturn(
"""
Subject: Input dispatching timed out (7985007 com.example.app/com.example.app.ui.MainActivity (server) is not responding. Waited 5000ms for FocusEvent(hasFocus=false))
Here are no Binder-related exception messages available.
Pid(12233) have D state thread(tid:12236 name:Signal Catcher)


RssHwmKb: 823716
RssKb: 548348
RssAnonKb: 382156
RssShmemKb: 13304
VmSwapKb: 82484


--- CriticalEventLog ---
capacity: 20
timestamp_ms: 1731507490032
window_ms: 300000

----- dumping pid: 12233 at 313446151
libdebuggerd_client: unexpected registration response: 0

----- Waiting Channels: pid 12233 at 2024-11-13 19:48:09.980104540+0530 -----
Cmd line: com.example.app:mainProcess
""".trimIndent().byteInputStream()
)
} else {
whenever(mock.traceInputStream).thenReturn(
"""
"main" prio=5 tid=1 Blocked
| group="main" sCount=1 ucsCount=0 flags=1 obj=0x72a985e0 self=0xb400007cabc57380
| sysTid=28941 nice=-10 cgrp=top-app sched=0/0 handle=0x7deceb74f8
Expand Down Expand Up @@ -147,8 +176,9 @@ class AnrV2IntegrationTest {
native: #02 pc 00000000000b63b0 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)
native: #03 pc 00000000000530b8 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 01331f74b0bb2cb958bdc15282b8ec7b)
(no managed stack frames)
""".trimIndent().byteInputStream()
)
""".trimIndent().byteInputStream()
)
}
}
shadowActivityManager.addApplicationExitInfo(exitInfo)
}
Expand Down Expand Up @@ -551,4 +581,14 @@ class AnrV2IntegrationTest {

verify(fixture.hub, never()).captureEvent(any(), anyOrNull<Hint>())
}

@Test
fun `when traceInputStream has bad data, does not report ANR`() {
val integration = fixture.getSut(tmpDir, lastReportedAnrTimestamp = oldTimestamp)
fixture.addAppExitInfo(timestamp = newTimestamp, addBadTrace = true)

integration.register(fixture.hub, fixture.options)

verify(fixture.hub, never()).captureEvent(any(), anyOrNull<Hint>())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertTrue

class ThreadDumpParserTest {

Expand Down Expand Up @@ -95,4 +96,15 @@ class ThreadDumpParserTest {
assertEquals(28, lastFrame.lineno)
assertNull(lastFrame.isInApp)
}

@Test
fun `thread dump garbage`() {
val lines = Lines.readLines(File("src/test/resources/thread_dump_bad_data.txt"))
val parser = ThreadDumpParser(
SentryOptions().apply { addInAppInclude("io.sentry.samples") },
false
)
val threads = parser.parse(lines)
assertTrue(threads.isEmpty())
}
}
Loading
Loading