Open
Description
Reproducer:
@Test
fun testProbes() = runBlocking {
val b1 = CompletableDeferred<Unit>()
val b2 = CompletableDeferred<Unit>()
println("runBlocking context: ${currentCoroutineContext()}")
launch { // in the context of runBlocking
withContext(Dispatchers.IO + CoroutineName("A")) {
println("launched job context: ${currentCoroutineContext()}")
b1.complete(Unit)
b2.await()
}
}
b1.await()
println("debug probes")
println(DebugProbes.dumpCoroutinesInfo())
}
Outputs:
runBlocking context: [CoroutineId(1), "coroutine#1":BlockingCoroutine{Active}@b665f0a, BlockingEventLoop@3c0fe39d]
launched job context: [CoroutineId(2), CoroutineName(A), "A#2":DispatchedCoroutine{Active}@2cd23013, Dispatchers.IO]
debug probes
[CoroutineInfo(state=RUNNING,context=[CoroutineId(1), "coroutine#1":BlockingCoroutine{Active}@b665f0a, BlockingEventLoop@3c0fe39d]), CoroutineInfo(state=SUSPENDED,context=[CoroutineId(2), "coroutine#2":StandaloneCoroutine{Active}@7ed255c1, BlockingEventLoop@3c0fe39d])]
Note that the debug info for the second coroutine does not show the effect of withContext switch.
This is likely because kotlinx.coroutines.debug.internal.DebugCoroutineInfoImpl
has immutable context and it is not updated from the frame
in updateState
.
The issue occasionally shows up in problem investigations, wrong context in the debug probes causes confusion.