Integration
sentry-android
Build System
Gradle
AGP Version
7.2.1
Proguard
Enabled
Version
6.3.0
Steps to Reproduce
Unknown
Expected Result
The app shouln't crash because of tracing
Actual Result
I'm randomly getting a bunch of crashes caused by the call to timer.cancel() on SentryTracer (both using navigation-compose integration and also without it). Actually taking a look into it seems like it's failing because of this block of code.
You can see it's checking if the timer != null outside of the syncronized block, so presumably another thread could change it to null but the check has already passed on another thread. So I think the fix would be to just change it like it's been done on the cancelTimer method.
Also, i'm using the gradle plugin on my build.gradle file, like so:
plugins {
id("com.android.application")
//other plugins ...
id("io.sentry.android.gradle") version "3.1.3"
}
Here are the crash logs (you can see one of them are even unrelated to navigation or compose):
Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.util.Timer.cancel()' on a null object reference
at io.sentry.SentryTracer.finish(SentryTracer.java:347)
at io.sentry.SentryTracer$1.run(SentryTracer.java:130)
at java.util.TimerThread.mainLoop(TimerThread.java:562)
at java.util.TimerThread.run(TimerThread.java:512)
Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.util.Timer.cancel()' on a null object reference
at io.sentry.SentryTracer.finish(SentryTracer.java:347)
at io.sentry.android.navigation.SentryNavigationListener.stopTracing(SentryNavigationListener.kt:137)
at io.sentry.android.navigation.SentryNavigationListener.startTracing(SentryNavigationListener.kt:93)
at io.sentry.android.navigation.SentryNavigationListener.onDestinationChanged(SentryNavigationListener.kt:49)
at androidx.navigation.NavController.dispatchOnDestinationChanged(NavController.kt:902)
at androidx.navigation.NavController.navigate(NavController.kt:1730)
at androidx.navigation.NavController.navigate(NavController.kt:1662)
at androidx.navigation.NavController.navigate(NavController.kt:1984)
at androidx.navigation.NavController.navigate$default(NavController.kt:1979)
at androidx.navigation.NavController.navigate(NavController.kt:1965)
at com.ramcosta.composedestinations.navigation.DestinationsNavController.navigate(DestinationsNavController.kt:27)
at com.ramcosta.composedestinations.navigation.DestinationsNavigator$DefaultImpls.navigate(DestinationsNavigator.java:40)
at com.ramcosta.composedestinations.navigation.DestinationsNavController.navigate(DestinationsNavController.kt:13)
at com.ramcosta.composedestinations.navigation.DestinationsNavigator$DefaultImpls.navigate$default(DestinationsNavigator.kt:35)
at com.myapp.ui.MyScreenKt$MyScreenContent$1$3.invoke(MyScreen.kt:120)
at com.myapp.ui.MyScreenKt$MyScreenContent$1$3.invoke(MyScreen.kt:115)
at com.myapp.ui.MyScreenItemKt$MyScreenItem$1$1.invoke(MyScreenItem.kt:33)
at androidx.compose.foundation.ClickableKt$clickable$4$gesture$1$2.invoke-k-4lQ0M(Clickable.kt:153)
at androidx.compose.foundation.ClickableKt$clickable$4$gesture$1$2.invoke(Clickable.kt:142)
at androidx.compose.foundation.gestures.TapGestureDetectorKt$detectTapAndPress$2$1$1.invokeSuspend(TapGestureDetector.kt:222)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:178)
at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTaskKt.java:166)
at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:397)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:431)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:420)
at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:328)
at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter$PointerEventHandlerCoroutine.offerPointerEvent(SuspendingPointerInputFilter.java:566)
at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter.dispatchPointerEvent(SuspendingPointerInputFilter.kt:456)
at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter.onPointerEvent-H0pRuoY(SuspendingPointerInputFilter.kt:469)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:310)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
at androidx.compose.ui.input.pointer.NodeParent.dispatchMainEventPass(NodeParent.java:179)
at androidx.compose.ui.input.pointer.HitPathTracker.dispatchChanges(HitPathTracker.kt:98)
at androidx.compose.ui.input.pointer.PointerInputEventProcessor.process-BIzXfog(PointerInputEventProcessor.kt:97)
at androidx.compose.ui.platform.AndroidComposeView.sendMotionEvent-8iAsVTc(AndroidComposeView.android.kt:1321)
at androidx.compose.ui.platform.AndroidComposeView.handleMotionEvent-8iAsVTc(AndroidComposeView.android.kt:1267)
at androidx.compose.ui.platform.AndroidComposeView.dispatchTouchEvent(AndroidComposeView.android.kt:1206)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3597)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3597)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3597)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3597)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3597)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3923)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3597)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:1015)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1962)
at android.app.Activity.dispatchTouchEvent(Activity.java:4265)
at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:70)
at io.sentry.android.core.internal.gestures.WindowCallbackAdapter.dispatchTouchEvent(WindowCallbackAdapter.java:39)
at io.sentry.android.core.internal.gestures.SentryWindowCallback.dispatchTouchEvent(SentryWindowCallback.java:64)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:973)
at android.view.View.dispatchPointerEvent(View.java:15335)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:7807)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:7580)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:6914)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:6971)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:6937)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:7135)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:6945)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:7192)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:6918)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:6971)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:6937)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:6945)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:6918)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:10367)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:10215)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:10171)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:10499)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:259)
at android.os.MessageQueue.nativePollOnce(MessageQueue.java)
at android.os.MessageQueue.next(MessageQueue.java:335)
at android.os.Looper.loopOnce(Looper.java:186)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8680)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
Integration
sentry-android
Build System
Gradle
AGP Version
7.2.1
Proguard
Enabled
Version
6.3.0
Steps to Reproduce
Unknown
Expected Result
The app shouln't crash because of tracing
Actual Result
I'm randomly getting a bunch of crashes caused by the call to timer.cancel() on SentryTracer (both using navigation-compose integration and also without it). Actually taking a look into it seems like it's failing because of this block of code.
You can see it's checking if the timer != null outside of the syncronized block, so presumably another thread could change it to null but the check has already passed on another thread. So I think the fix would be to just change it like it's been done on the cancelTimer method.
Also, i'm using the gradle plugin on my build.gradle file, like so:
plugins { id("com.android.application") //other plugins ... id("io.sentry.android.gradle") version "3.1.3" }Here are the crash logs (you can see one of them are even unrelated to navigation or compose):