jvmMain.debug.CoroutineDebugging.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlinx-coroutines-core-jvm Show documentation
Show all versions of kotlinx-coroutines-core-jvm Show documentation
Coroutines support libraries for Kotlin
The newest version!
/* This package name is like this so that
1) the artificial stack frames look pretty, and
2) the IDE reliably navigates to this file. */
package _COROUTINE
/**
* A collection of artificial stack trace elements to be included in stack traces by the coroutines machinery.
*
* There are typically two ways in which one can encounter an artificial stack frame:
* 1. By using the debug mode, via the stacktrace recovery mechanism; see
* [stacktrace recovery](https://github.com/Kotlin/kotlinx.coroutines/blob/master/docs/topics/debugging.md#stacktrace-recovery)
* documentation. The usual way to enable the debug mode is with the [kotlinx.coroutines.DEBUG_PROPERTY_NAME] system
* property.
* 2. By looking at the output of DebugProbes; see the
* [kotlinx-coroutines-debug](https://github.com/Kotlin/kotlinx.coroutines/tree/master/kotlinx-coroutines-debug) module.
*/
internal class ArtificialStackFrames {
/**
* Returns an artificial stack trace element denoting the boundary between coroutine creation and its execution.
*
* Appearance of this function in stack traces does not mean that it was called. Instead, it is used as a marker
* that separates the part of the stack trace with the code executed in a coroutine from the stack trace of the code
* that launched the coroutine.
*
* In earlier versions of kotlinx-coroutines, this was displayed as "(Coroutine creation stacktrace)", which caused
* problems for tooling that processes stack traces: https://github.com/Kotlin/kotlinx.coroutines/issues/2291
*
* Note that presence of this marker in a stack trace implies that coroutine creation stack traces were enabled.
*/
fun coroutineCreation(): StackTraceElement = Exception().artificialFrame(_CREATION::class.java.simpleName)
/**
* Returns an artificial stack trace element denoting a coroutine boundary.
*
* Appearance of this function in stack traces does not mean that it was called. Instead, when one coroutine invokes
* another, this is used as a marker in the stack trace to denote where the execution of one coroutine ends and that
* of another begins.
*
* In earlier versions of kotlinx-coroutines, this was displayed as "(Coroutine boundary)", which caused
* problems for tooling that processes stack traces: https://github.com/Kotlin/kotlinx.coroutines/issues/2291
*/
fun coroutineBoundary(): StackTraceElement = Exception().artificialFrame(_BOUNDARY::class.java.simpleName)
}
// These are needed for the IDE navigation to detect that this file does contain the definition.
private class _CREATION
private class _BOUNDARY
internal val ARTIFICIAL_FRAME_PACKAGE_NAME = "_COROUTINE"
/**
* Forms an artificial stack frame with the given class name.
*
* It consists of the following parts:
* 1. The package name, it seems, is needed for the IDE to detect stack trace elements reliably. It is `_COROUTINE` since
* this is a valid identifier.
* 2. Class names represents what type of artificial frame this is.
* 3. The method name is `_`. The methods not being present in class definitions does not seem to affect navigation.
*/
private fun Throwable.artificialFrame(name: String): StackTraceElement =
with(stackTrace[0]) { StackTraceElement(ARTIFICIAL_FRAME_PACKAGE_NAME + "." + name, "_", fileName, lineNumber) }