Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/debugging.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
The documentation has been moved to the [topics/debugging.md](topics/debugging.md).
The documentation has been moved to the [https://kotlinlang.org/docs/coroutines-debugging.html](https://kotlinlang.org/docs/coroutines-debugging.html) page.
Binary file removed docs/images/after.png
Binary file not shown.
Binary file removed docs/images/before.png
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/run-debug-configuration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/with-stack-trace-recovery.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/without-stack-trace-recovery.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 6 additions & 3 deletions docs/kc.tree
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
<toc-element topic="exception-handling.md"/>
<toc-element topic="shared-mutable-state-and-concurrency.md"/>
<toc-element topic="select-expression.md"/>
<toc-element topic="debug-coroutines-with-idea.md"/>
<toc-element topic="debug-flow-with-idea.md"/>
</snippet>
<toc-element toc-title="Coroutine debugging">
<toc-element topic="coroutines-debugging.md"/>
<toc-element topic="debug-coroutines-with-idea.md"/>
<toc-element topic="debug-flow-with-idea.md"/>
</toc-element>
</snippet>
</instance-profile>
4 changes: 4 additions & 0 deletions docs/topics/coroutines-and-channels.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

[//]: # (title: Coroutines and channels − tutorial)

> We plan to revise this tutorial. For an up-to-date guide to getting started with coroutines, see [Coroutines basics](coroutines-basics.md).
>
{style="note"}

In this tutorial, you'll learn how to use coroutines in IntelliJ IDEA to perform network requests without blocking the
underlying thread or callbacks.

Expand Down
2 changes: 1 addition & 1 deletion docs/topics/coroutines-basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ You may notice that the output order and thread names may change each time you r
> You can display coroutine names next to thread names in the output of your code for additional information.
> To do so, pass the `-Dkotlinx.coroutines.debug` VM option in your build tool or IDE run configuration.
>
> See [Debugging coroutines](https://github.com/Kotlin/kotlinx.coroutines/blob/master/docs/topics/debugging.md) for more information.
> See [Debugging coroutines](coroutines-debugging.md) for more information.
>
{style="tip"}

Expand Down
561 changes: 561 additions & 0 deletions docs/topics/coroutines-debugging.md

Large diffs are not rendered by default.

110 changes: 2 additions & 108 deletions docs/topics/debugging.md
Original file line number Diff line number Diff line change
@@ -1,109 +1,3 @@
**Table of contents**
Comment thread
daniCsorbaJB marked this conversation as resolved.
The documentation has been moved to the [https://kotlinlang.org/docs/coroutines-debugging.html](https://kotlinlang.org/docs/coroutines-debugging.html) page.

<!--- TOC -->

* [Debugging coroutines](#debugging-coroutines)
* [Debug mode](#debug-mode)
* [Stacktrace recovery](#stacktrace-recovery)
* [Stacktrace recovery machinery](#stacktrace-recovery-machinery)
* [Debug agent](#debug-agent)
* [Android optimization](#android-optimization)

<!--- END -->

## Debugging coroutines

Debugging asynchronous programs is challenging, because multiple concurrent coroutines are typically working at the same time.
To help with that, `kotlinx.coroutines` comes with additional features for debugging: debug mode, stacktrace recovery
and debug agent.
These debugging capabilities are available only on JVM platforms.

## Debug mode

The first debugging feature of `kotlinx.coroutines` is debug mode.
It can be enabled either by setting system property [DEBUG_PROPERTY_NAME] or by running Java with enabled assertions (`-ea` flag).
The latter is helpful to have debug mode enabled by default in unit tests.

Debug mode attaches a unique [name][CoroutineName] to every launched coroutine.
Coroutine name can be seen in a regular Java debugger,
in a string representation of the coroutine or in the thread name executing named coroutine.
Overhead of this feature is negligible and it can be safely turned on by default to simplify logging and diagnostic.

## Stacktrace recovery

Stacktrace recovery is another useful feature of debug mode. It is enabled by default in the debug mode,
but can be separately disabled by setting `kotlinx.coroutines.stacktrace.recovery` system property to `false`.

Stacktrace recovery tries to stitch asynchronous exception stacktrace with a stacktrace of the receiver by copying it, providing
not only information where an exception was thrown, but also where it was asynchronously rethrown or caught.

It is easy to demonstrate with actual stacktraces of the same program that awaits asynchronous operation in `main` function
(runnable code is [here](../../kotlinx-coroutines-debug/test/RecoveryExample.kt)):

| Without recovery | With recovery |
| - | - |
| ![before](../images/before.png "before") | ![after](../images/after.png "after") |

The only downside of this approach is losing referential transparency of the exception.

> Note that suppressed exceptions are not copied and are left intact in the cause
> in order to prevent cycles in the exceptions chain, obscure`[CIRCULAR REFERENCE]` messages
> and even [crashes](https://jira.qos.ch/browse/LOGBACK-1027) in some frameworks

### Stacktrace recovery machinery

This section explains the inner mechanism of stacktrace recovery and can be skipped.

When an exception is rethrown between coroutines (e.g. through `withContext` or `Deferred.await` boundary), stacktrace recovery
machinery tries to create a copy of the original exception (with the original exception as the cause), then rewrite stacktrace
of the copy with coroutine-related stack frames (using [Throwable.setStackTrace](https://docs.oracle.com/javase/9/docs/api/java/lang/Throwable.html#setStackTrace-java.lang.StackTraceElement:A-))
and then throws the resulting exception instead of the original one.

Exception copy logic is straightforward:
1) If the exception class implements [CopyableThrowable], [CopyableThrowable.createCopy] is used.
`null` can be returned from `createCopy` to opt-out specific exception from being recovered.
2) If the exception class has class-specific fields not inherited from Throwable, the exception is not copied.
3) Otherwise, one of the public exception's constructor is invoked reflectively with an optional `initCause` call.
4) If the reflective copy has a changed message (exception constructor passed a modified `message` parameter to the superclass),
the exception is not copied in order to preserve a human-readable message. [CopyableThrowable] does not have such a limitation
and allows the copy to have a `message` different from that of the original.

## Debug agent

[kotlinx-coroutines-debug](../../kotlinx-coroutines-debug) module provides one of the most powerful debug capabilities in `kotlinx.coroutines`.

This is a separate module with a JVM agent that keeps track of all alive coroutines, introspects and dumps them similar to thread dump command,
additionally enhancing stacktraces with information where coroutine was created.

The full tutorial of how to use debug agent can be found in the corresponding [readme](../../kotlinx-coroutines-debug/README.md).

<!---
Make an exception googlable
java.lang.NoClassDefFoundError: Failed resolution of: Ljava/lang/management/ManagementFactory;
at kotlinx.coroutines.repackaged.net.bytebuddy.agent.ByteBuddyAgent$ProcessProvider$ForCurrentVm$ForLegacyVm.resolve(ByteBuddyAgent.java:1055)
at kotlinx.coroutines.repackaged.net.bytebuddy.agent.ByteBuddyAgent$ProcessProvider$ForCurrentVm.resolve(ByteBuddyAgent.java:1038)
at kotlinx.coroutines.repackaged.net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:374)
at kotlinx.coroutines.repackaged.net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:342)
at kotlinx.coroutines.repackaged.net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:328)
at kotlinx.coroutines.debug.internal.DebugProbesImpl.install(DebugProbesImpl.kt:39)
at kotlinx.coroutines.debug.DebugProbes.install(DebugProbes.kt:49)
-->

## Android optimization

In optimized (release) builds with R8 version 1.6.0 or later both
[Debugging mode](debugging.md#debug-mode) and
[Stacktrace recovery](debugging.md#stacktrace-recovery)
are permanently turned off.
For more details see ["Optimization" section for Android](../../ui/kotlinx-coroutines-android/README.md#optimization).

<!--- MODULE kotlinx-coroutines-core -->
<!--- INDEX kotlinx.coroutines -->

[DEBUG_PROPERTY_NAME]: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-d-e-b-u-g_-p-r-o-p-e-r-t-y_-n-a-m-e.html
[CoroutineName]: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-name/index.html
[CopyableThrowable]: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-copyable-throwable/index.html
[CopyableThrowable.createCopy]: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-copyable-throwable/create-copy.html

<!--- MODULE kotlinx-coroutines-debug -->
<!--- END -->
To edit the documentation, open the [topics/coroutines-debugging.md](topics/coroutines-debugging.md) page.