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

java.lang.ClassCastException: kotlin.coroutines.jvm.internal.CompletedContinuation cannot be cast to kotlinx.coroutines.internal.DispatchedContinuation #2736

Closed
auras opened this issue May 31, 2021 · 20 comments

Comments

@auras
Copy link

auras commented May 31, 2021

21:05:05	ERROR:	AndroidRuntime : kotlinx.coroutines.CoroutinesInternalError: Fatal exception in coroutines machinery for CancellableContinuation(DispatchedContinuation[Dispatchers.IO, Continuation at kotlinx.coroutines.channels.AbstractChannel.receiveCatching-JP2dKIU(AbstractChannel.kt:632)@8d8755]){Completed}@c3cb56a. Please read KDoc to 'handleFatalException' method and report this incident to maintainers
21:05:05	ERROR:	AndroidRuntime : at kotlinx.coroutines.DispatchedTask.handleFatalException(DispatchedTask.kt:144)
21:05:05	ERROR:	AndroidRuntime : at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:115)
21:05:05	ERROR:	AndroidRuntime : at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
21:05:05	ERROR:	AndroidRuntime : at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
21:05:05	ERROR:	AndroidRuntime : at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
21:05:05	ERROR:	AndroidRuntime : at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
21:05:05	ERROR:	AndroidRuntime : Caused by: java.lang.ClassCastException: kotlin.coroutines.jvm.internal.CompletedContinuation cannot be cast to kotlinx.coroutines.internal.DispatchedContinuation
21:05:05	ERROR:	AndroidRuntime : at kotlinx.coroutines.CoroutineDispatcher.releaseInterceptedContinuation(CoroutineDispatcher.kt:108)
21:05:05	ERROR:	AndroidRuntime : at kotlin.coroutines.jvm.internal.ContinuationImpl.releaseIntercepted(ContinuationImpl.kt:118)
21:05:05	ERROR:	AndroidRuntime : at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:39)
21:05:05	ERROR:	AndroidRuntime : at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
21:05:05	ERROR:	AndroidRuntime : ... 4 more

kotlin version: 1.5.10
coroutines version: 1.5.0

I'm not sure how to reproduce, it sometimes happens during espresso tests

@kozaxinan
Copy link

We still don't have reproducible case but all of our crashes happen in background. Is it same for everyone?

@qwwdfsad
Copy link
Member

qwwdfsad commented Jun 4, 2021

It would be really helpful if anybody could provide a reproduced even if it's a set of espresso tests that fail 1 in 1000 times.
Without that, it's quite hard to do anything meaningful about this error

@kozaxinan
Copy link

Last 2 days we are working on reproducing but we had not luck. Only interesting thing is it only happens background according to firebase crashlytics.

We are downgrading kotlin and coroutine. We don't have any reproducible case. We can try kotlin 1.5.20 when it is released.

@kozaxinan
Copy link

This issue looks similar to #2719. Is there any version of kotlin released with fix of https://youtrack.jetbrains.com/issue/KT-45685?

@qwwdfsad
Copy link
Member

qwwdfsad commented Jun 4, 2021

The fix will be released with Kotlin 1.5.20-RC (~roughly next week)

@auras
Copy link
Author

auras commented Jun 14, 2021

Still crashes with Kotlin 1.5.20-RC

@kozaxinan
Copy link

@auras Do you have reproducible case? And dont we need to have a coroutine release with 1.5.20 to test this issue again?

@auras
Copy link
Author

auras commented Jun 14, 2021

Not reliably, no. But if I run the app/test I'm working on a few times it will happen. Usually during app launch.

I thought since it was a kotlin issue, no coroutines release was required.

@qwwdfsad
Copy link
Member

@auras are these tests run on JVM or in an emulator?

It could be some tricky race in kotlinx.coroutine, so even if it's reproducible 1/50 runs, I still would like to investigate it, especially if you could provide any reproducer

@auras
Copy link
Author

auras commented Jun 15, 2021

@qwwdfsad running on both emulator and real devices

I can provide apks but not source code

@qwwdfsad
Copy link
Member

qwwdfsad commented Jun 15, 2021

Does it reproduce when running unit-tests locally, not on an emulator, but on plain JVM?

@auras
Copy link
Author

auras commented Jun 15, 2021

I never saw it when running unit tests. We usually run those with TestCoroutineScope, runBlocking

@denis-bezrukov
Copy link

In our android app it crashes when using stateflow/sharedflow + debounce. So I was able to repro this with just launching ton of different coroutines which use stateflow+debounce.

class TestRunner(private val scope: CoroutineScope) {

    fun run() {
        scope.launch {
            runStressTest()
        }
    }

    suspend fun runStressTest() = withContext(Dispatchers.Default) {
        repeat(100) { a ->
            repeat(100) { b ->
                launch {
                    runStressTestOnce((a + 1) * 10, (b + 1) * 10)
                }
            }
        }
    }

    suspend fun runStressTestOnce(delay: Int, debounce: Int) = coroutineScope {
        val stateflow = MutableStateFlow(0)
        launch {
            repeat(Integer.MAX_VALUE) { i ->
                stateflow.emit(i)
                delay(delay.toLong())
            }
        }
        var last = 0
        stateflow.debounce(debounce.toLong()).collect { i ->
            if (i - last > 100) {
                println("${delay}x${debounce} => $i")
                last = i
            }
        }
    }
}

Then I ran TestRunner(scope).run() in Application.

it's always (5 out 5 launches) crashing with the following stacktrace:

java.lang.IllegalStateException: Inconsistent state CancellableContinuation(DispatchedContinuation[Dispatchers.Default, Continuation at kotlinx.coroutines.flow.StateFlowImpl.collect(StateFlow.kt:353)@deec246]){Active}@5fe3c07
        at kotlinx.coroutines.internal.DispatchedContinuation.tryReleaseClaimedContinuation(DispatchedContinuation.kt:169)
        at kotlinx.coroutines.CancellableContinuationImpl.releaseClaimedReusableContinuation(CancellableContinuationImpl.kt:323)
        at kotlinx.coroutines.CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:280)
        at kotlinx.coroutines.channels.AbstractSendChannel.sendSuspend(AbstractChannel.kt:1152)
        at kotlinx.coroutines.channels.AbstractSendChannel.send(AbstractChannel.kt:136)
        at kotlinx.coroutines.channels.ChannelCoroutine.send(Unknown Source:2)
        at kotlinx.coroutines.flow.FlowKt__DelayKt$debounceInternal$1$values$1$invokeSuspend$$inlined$collect$1.emit(Collect.kt:135)
        at kotlinx.coroutines.flow.StateFlowImpl.collect(StateFlow.kt:348)
        at kotlinx.coroutines.flow.StateFlowImpl$collect$1.invokeSuspend(Unknown Source:15)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
    
    java.lang.IllegalStateException: Inconsistent state CancellableContinuation(DispatchedContinuation[Dispatchers.Default, Continuation at kotlinx.coroutines.flow.StateFlowImpl.collect(StateFlow.kt:353)@deec246]){Active}@5fe3c07
        at kotlinx.coroutines.internal.DispatchedContinuation.tryReleaseClaimedContinuation(DispatchedContinuation.kt:169)
        at kotlinx.coroutines.CancellableContinuationImpl.releaseClaimedReusableContinuation(CancellableContinuationImpl.kt:323)
        at kotlinx.coroutines.CancellableContinuationImpl.getResult(CancellableContinuationImpl.kt:280)
        at kotlinx.coroutines.channels.AbstractSendChannel.sendSuspend(AbstractChannel.kt:1152)
        at kotlinx.coroutines.channels.AbstractSendChannel.send(AbstractChannel.kt:136)
        at kotlinx.coroutines.channels.ChannelCoroutine.send(Unknown Source:2)
        at kotlinx.coroutines.flow.FlowKt__DelayKt$debounceInternal$1$values$1$invokeSuspend$$inlined$collect$1.emit(Collect.kt:135)
        at kotlinx.coroutines.flow.StateFlowImpl.collect(StateFlow.kt:348)
        at kotlinx.coroutines.flow.StateFlowImpl$collect$1.invokeSuspend(Unknown Source:15)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)

@denis-bezrukov
Copy link

It's reproducible even without launching android app just by adding:

fun main() {
    TestRunner(CoroutineScope(Dispatchers.Default + Job())).run()
    Thread.sleep(1_000_000)
}

@qwwdfsad
Copy link
Member

Kudos for the self-contained reproducer!

It's hard to tell whether it is a root cause for ClassCastException before further investigation, but it has to be fixed anyway.
Filed #2768

@denis-bezrukov
Copy link

@qwwdfsad it is, run it multiple times and sometimes it fails with exact classcastexception:
to increase your chances (i don't know why) run more coroutines:

suspend fun runTest() = withContext(Dispatchers.Default) {
        repeat(300) { a ->
            repeat(300) { b ->
                launch {
                    runTestOnce(a + 50, b + 50)
                }
            }
        }
    }

produces

Exception in thread "DefaultDispatcher-worker-8" kotlinx.coroutines.CoroutinesInternalError: Fatal exception in coroutines machinery for CancellableContinuation(DispatchedContinuation[Dispatchers.Default, Continuation at kotlinx.coroutines.flow.StateFlowImpl.collect(StateFlow.kt:353)@6476f03]){Cancelled}@10ee2b07. Please read KDoc to 'handleFatalException' method and report this incident to maintainers
	at kotlinx.coroutines.DispatchedTask.handleFatalException(DispatchedTask.kt:144)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:115)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
Caused by: java.lang.ClassCastException: class kotlin.coroutines.jvm.internal.CompletedContinuation cannot be cast to class kotlinx.coroutines.internal.DispatchedContinuation (kotlin.coroutines.jvm.internal.CompletedContinuation and kotlinx.coroutines.internal.DispatchedContinuation are in unnamed module of loader 'app')
	at kotlinx.coroutines.CoroutineDispatcher.releaseInterceptedContinuation(CoroutineDispatcher.kt:108)
	at kotlin.coroutines.jvm.internal.ContinuationImpl.releaseIntercepted(ContinuationImpl.kt:118)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:39)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
	... 4 more

in most of the runs (and it fails faster)

@qwwdfsad
Copy link
Member

Amazing! Looking into it

@Woren
Copy link

Woren commented Jul 8, 2021

Is there any release schedule how often is coroutines library released? This issue hit us very hard, so if we should choose path of building whole library by ourselves or try another fallback (older version, ...). Thanks

@gildor
Copy link
Contributor

gildor commented Oct 27, 2021

I have the same issue with Kotlin 1.5.31 and kotlinx.coroutines 1.5.2
Should I report it separately?

kotlinx.coroutines.CoroutinesInternalError: Fatal exception in coroutines machinery for CancellableContinuation(DispatchedContinuation[Dispatchers.Main.immediate, Continuation at com.bandlab.listmanager.pagination.impl.PaginationListManagerImpl.reload$suspendImpl(PaginationListManagerImpl.kt:223)@ed822fb]){Cancelled}@5d18f18. Please read KDoc to 'handleFatalException' method and report this incident to maintainers
        at kotlinx.coroutines.DispatchedTask.handleFatalException(DispatchedTask.kt:144)
        at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(DispatchedTask.kt:251)
        at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:161)
        at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:397)
        at kotlinx.coroutines.CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:183)
        at kotlinx.coroutines.CancellableContinuationImpl.parentCancelled$kotlinx_coroutines_core(CancellableContinuationImpl.kt:190)
        at kotlinx.coroutines.ChildContinuation.invoke(JobSupport.kt:1474)
        at kotlinx.coroutines.JobSupport.completeStateFinalization(JobSupport.kt:318)
        at kotlinx.coroutines.JobSupport.tryFinalizeSimpleState(JobSupport.kt:295)
        at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:856)
        at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core(JobSupport.kt:828)
        at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:100)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
        at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:234)
        at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt: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.resumeUndispatched(CancellableContinuationImpl.kt:518)
        at kotlinx.coroutines.android.HandlerContext$scheduleResumeAfterDelay$$inlined$Runnable$1.run(Runnable.kt:19)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7842)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
     Caused by: java.lang.ClassCastException: kotlin.coroutines.jvm.internal.CompletedContinuation cannot be cast to kotlinx.coroutines.internal.DispatchedContinuation
        at kotlinx.coroutines.CoroutineDispatcher.releaseInterceptedContinuation(CoroutineDispatcher.kt:107)
        at kotlin.coroutines.jvm.internal.ContinuationImpl.releaseIntercepted(ContinuationImpl.kt:118)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:39)
        at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:234)
        at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(DispatchedTask.kt:190)
        at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:161) 
        at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:397) 
        at kotlinx.coroutines.CancellableContinuationImpl.cancel(CancellableContinuationImpl.kt:183) 
        at kotlinx.coroutines.CancellableContinuationImpl.parentCancelled$kotlinx_coroutines_core(CancellableContinuationImpl.kt:190) 
        at kotlinx.coroutines.ChildContinuation.invoke(JobSupport.kt:1474) 
        at kotlinx.coroutines.JobSupport.completeStateFinalization(JobSupport.kt:318) 
        at kotlinx.coroutines.JobSupport.tryFinalizeSimpleState(JobSupport.kt:295) 
        at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:856) 
        at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core(JobSupport.kt:828) 
        at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:100) 
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46) 
        at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:234) 
        at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt: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.resumeUndispatched(CancellableContinuationImpl.kt:518) 
        at kotlinx.coroutines.android.HandlerContext$scheduleResumeAfterDelay$$inlined$Runnable$1.run(Runnable.kt:19) 
        at android.os.Handler.handleCallback(Handler.java:938) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loopOnce(Looper.java:201) 
        at android.os.Looper.loop(Looper.java:288) 
        at android.app.ActivityThread.main(ActivityThread.java:7842) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) 

@gildor
Copy link
Contributor

gildor commented Oct 29, 2021

Reported a new issue #3005

pablobaxter pushed a commit to pablobaxter/kotlinx.coroutines that referenced this issue Sep 14, 2022
Kotlin#2772)

* Properly detect non-released reusable continuations in non-reusable ones and await for reusability to have a consistent state
* Ensure that the caller to DispatchedContinuation.isReusable is reusable itself
* Using the previous invariant, simplify DispatchedContinuation.isReusable to a single null-check
* It also restores the invariant that `cc.isReusable() == cc.resumeMode.isReusableMode`

Fixes Kotlin#2736
Fixes Kotlin#2768
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants