Coroutine Dumps
The
action creates a thread dump, which is useful when investigating freezes or deadlocks. Thread dumps include all application threads and coroutines existing at the moment of dump creation.Coroutine Dump Format
A coroutine dump format is:
Each coroutine entry starts with a -
character. Indentation represents parent-child relationships. A coroutine entry may not include a stacktrace (see child coroutine 1 header
) because it has no executable body, or it did not start executing yet.
An example coroutine header:
Its format is as follows:
[xN of]
A particular subtree is repeated N times (included only if N > 1).
name
A coroutine name.
Notable names:
ApplicationImpl@xxxxxxxx container
- application coroutine.ProjectImpl@xxxxxxxx container
- project coroutine.com.intellij.*.AClass
- a coroutine bound to some specific class instance, e.g., an extension or a service. Unnamed coroutines are hard to identify, so it is recommended to addCoroutineName(someName)
into a coroutine context.(a x b)
- an intersection of coroutinesa
andb
, e.g.,(ApplicationImpl@56422718 x com.example.myplugin)
is an intersection of the application and a plugin scope. See also Intersection Scopes.
CoroutineClass{JobState}
A coroutine's toString()
:
CoroutineClass
- a coroutine class. Notable values:StandaloneCoroutine
andLazyStandaloneCoroutine
are created bylaunch
.DeferredCoroutine
andLazyDeferredCoroutine
are created byasync
.BlockingCoroutine
is created byrunBlockingCancellable()
.ProducerCoroutine
is created byproduce
.ChildScope
is created bychildScope
.
JobState
- a coroutineJob
's state. Possible states and transition can be found in theJob
's KDoc.
state: STATE
A coroutine's state.
Possible states:
CREATED
- a coroutine was created but not yet started.SUSPENDED
- a coroutine was executed up until the last frame in the stacktrace. This is where it was last seen running.RUNNING
- a coroutine is currently executed by a thread. Its stacktrace reflects what the coroutine is doing right now (probably blocked waiting for something, otherwise aRUNNING
coroutine is rarely seen unless it’s doing CPU-intensive work).
[context]
A coroutine context. Context elements are separated with ,
.
Notable context elements:
no parent and no name
comes from the startup tracer. It should not be present in application/project coroutines and their children.ComponentManager(ApplicationImpl@xxxxxxxx)
- application or project, which serves as the coroutine parent.BlockingEventLoop
,Dispatchers.Default
,Dispatchers.IO
,LimitedDispatcher
,Dispatchers.EDT
- a coroutine dispatcher. Absence means Dispatchers.Default.ModalityState.xxx
- modality state. Absence meansModalityState.nonModal()
.When EDT is in a modal state, all non-modal coroutines are suspended until the modal state ends, and EDT goes back to non-modal state as well.
Some
RUNNING
coroutines might block in aninvokeAndWait
call, which means thatinvokeAndWait
used non-modal default modality state for one of two reasons:the coroutine contains the correct modality state in its context, but
invokeAndWait
is not aware of ita modal coroutine awaits another unrelated coroutine, which in turn requires non-modal EDT to complete.
Same problems can be found in regular thread dumps and blocking code, but coroutines suspend instead of blocking a thread, so it’s only possible to observe the last seen frame, which is usually enough.