getsentry / getsentry/sentry-java

ANR not captured on Android 10 due to getProcessesInErrorState() gate in ANRWatchDog

Open
#5,332 2 comments 0 reactions 0 assignees View on GitHub
Android Bug Errors
Dominant language
Kotlin
Stars
1.4k
Forks
478
Avg merge
2d 23h
Merged PRs (30d)
67

Description

### Integration

sentry-android

### Build System

Gradle

### AGP Version

-

### Proguard

Enabled

### Other Error Monitoring Solution

No

### Version

8.40.0

### Steps to Reproduce

1. Run an app on an Android 10 (API 29) device with `io.sentry:sentry-android` 8.40.0 initialized via AndroidManifest (auto-init, `io.sentry.anr.enable=true`, default 5s timeout).
2. From a UI callback, block the Java main thread indefinitely, e.g. `Thread.sleep(Long.MAX_VALUE)`.
3. Wait for the system "App isn't responding" dialog, then tap "Kill".
4. Relaunch the app and let it flush cached envelopes.
5. Check the Sentry project for an ANR event.

### Expected Result

An ANR event is captured and delivered to Sentry, with mechanism `ANR` / `anr_foreground`, matching the behavior on Android 11+ where `AnrV2Integration` reports it via `ApplicationExitInfo`.

### Actual Result

No ANR event is produced on Android 10. Debug logs show:

- `AnrIntegration enabled: true`
- `ANR timeout in milliseconds: 5000`
- `AnrIntegration installed.`
- no `"ANR triggered with message: ..."` INFO line at the time of the hang
- previous session is closed on next launch as `"status": "exited", "errors": 0`

Root cause appears to be the gate in `ANRWatchDog.isProcessNotResponding()`
(`sentry-android-core/.../ANRWatchDog.java` lines 168-194). The watchdog correctly
detects the main-thread hang via its own timer, but then calls
`ActivityManager.getProcessesInErrorState()`. On Android 10, this API returns
`null` / an empty list / does not include the caller's own process for non-system
apps, so `isProcessNotResponding()` returns `false` and `onAppNotResponding` is
never invoked. The hang was real enough for the OS to show the system ANR dialog,
so the gate is rejecting a genuine ANR.

Reproducible 100% on Android 10. Same repro on Android 11+ is captured correctly
via `AnrV2Integration` (ApplicationExitInfo). Single-process app, no custom
`SentryOptions` beyond manifest meta-data.

Suggested fix: when `getProcessesInErrorState()` returns `null` or an empty list
(i.e. "don't know"), trust the watchdog's own timer result instead of silently
dropping the event, or remove the gate entirely on API < 30 where this API is
unreliable.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.