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
Avoid polling when detecting ANRs by invoking JNI from SIGQUIT handler #741
Conversation
1e33022
to
5003a11
Compare
Android notifier sizes
Generated by 🚫 Danger |
5003a11
to
54eef6c
Compare
54eef6c
to
b2ab4e0
Compare
bugsnag-plugin-android-anr/src/main/java/com/bugsnag/android/AnrInterface.java
Outdated
Show resolved
Hide resolved
b2ab4e0
to
68e7a97
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stopped early on obj_plugin
68e7a97
to
32619ef
Compare
Apologies - it seems as those an old stale artefact must have been lying around the system, which meant ANRs appeared to work fine in the example app. I've altered |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Very streamlined implementation. Noted a few smaller things but looks just about there.
bugsnag-plugin-android-anr/src/main/java/com/bugsnag/android/AnrPlugin.kt
Outdated
Show resolved
Hide resolved
bugsnag-plugin-android-anr/src/main/java/com/bugsnag/android/AnrDetailsCollector.kt
Outdated
Show resolved
Hide resolved
32619ef
to
fa03c11
Compare
The previous implementation of ANR detection used a SIGQUIT handler. When SIGQUIT was raised, a shared ByteBuffer was modified, and the JVM layer polled every 5ms to check whether an ANR had occurred. Polling every 5ms is inefficient and risks an app being killed if it is in the background due to excessive work. This alternative approach invokes the JNI from the SIGQUIT handler and avoids the need for polling entirely.
fa03c11
to
cf466bd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Goal
The previous implementation of ANR detection used a SIGQUIT handler. When SIGQUIT was raised, a shared ByteBuffer was modified, and the JVM layer polled every 5ms to check whether an ANR had occurred.
Polling every 5ms is inefficient and risks an app being killed if it is in the background due to excessive work. This alternative approach invokes the JNI from the SIGQUIT handler and avoids the need for polling entirely.
Changeset
AnrInterface
class which is responsible for all communication from the ANR layer to the JVM layerAnrPlugin
initialisation so that aByteBuffer
is no longer requiredcollectAnrErrorDetails()
accessible fromAnrInterface
(the containing class is still non-public)AppNotRespondingMonitor
classANR handler
AnrInterface
inJni_On_Load
, as JNIEnv is not thread safe and we need to obtain a reference each time the ANR handler is invokedSA_ONSTACK
flag from SIGQUIT handler installation as we don't require information about the signal; we just need to know that it happenedAnrInterface
through JNI in the SIGQUIT handlerTests
I have verified that ANRs are detected on the following devices, and that changing
releaseStage
alters whether the error is detected or not: