Coroutines debugger may overwrite the actual state of coroutine during asynchronous resume
Consider the following situation when the dispatcher in the context is multithreaded
suspend fun foo() = yield()
It basically can be boiled down to the following pseudocode:
fun foo(...) {
uCont.intercepted().dispatchUsingDispatcher()
// Notify the debugger the coroutine is suspended
probeCoroutineSuspended()
return COROUTINE_SUSPENDED // Unroll the stack
}
where dispatch concurrently invokes probeCoroutineResumed to notify the debugger the coroutine is actually executing right now.
The problem is straightforward -- if timings are unlucky enough, probeCoroutineResumed can be invoked before probeCoroutineSuspended, with probeCoroutineSuspended overwriting the state and leaving it as SUSPENDED
Steps to reproduce:
- add
while (true)toRunningThreadStackMergeTest - Re-run it once every 5 secs, the bug reproducer only before C2 JIT kicks in
Failing build https://teamcity.jetbrains.com/buildConfiguration/KotlinTools_KotlinxCoroutines_Build/3793970?showRootCauses=false&expandBuildChangesSection=true&expandBuildProblemsSection=true&expandBuildTestsSection=true