xref: /aosp_15_r20/external/kotlinx.coroutines/docs/topics/debug-coroutines-with-idea.md (revision 7a7160fed73afa6648ef8aa100d4a336fe921d9a)
1[//]: # (title: Debug coroutines using IntelliJ IDEA – tutorial)
2
3This tutorial demonstrates how to create Kotlin coroutines and debug them using IntelliJ IDEA.
4
5The tutorial assumes you have prior knowledge of the [coroutines](coroutines-guide.md) concept.
6
7## Create coroutines
8
91. Open a Kotlin project in IntelliJ IDEA. If you don't have a project, [create one](jvm-get-started.md#create-a-project).
102. To use the `kotlinx.coroutines` library in a Gradle project, add the following dependency to `build.gradle(.kts)`:
11
12   <tabs group="build-script">
13   <tab title="Kotlin" group-key="kotlin">
14
15   ```kotlin
16   dependencies {
17       implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:%coroutinesVersion%")
18   }
19   ```
20
21   </tab>
22   <tab title="Groovy" group-key="groovy">
23
24   ```groovy
25   dependencies {
26       implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:%coroutinesVersion%'
27   }
28   ```
29
30   </tab>
31   </tabs>
32
33   For other build systems, see instructions in the [`kotlinx.coroutines` README](https://github.com/Kotlin/kotlinx.coroutines#using-in-your-projects).
34
353. Open the `Main.kt` file in `src/main/kotlin`.
36
37    The `src` directory contains Kotlin source files and resources. The `Main.kt` file contains sample code that will print `Hello World!`.
38
394. Change code in the `main()` function:
40
41    * Use the [`runBlocking()`](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/run-blocking.html) block to wrap a coroutine.
42    * Use the [`async()`](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html) function to create coroutines that compute deferred values `a` and `b`.
43    * Use the [`await()`](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/await.html) function to await the computation result.
44    * Use the [`println()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/println.html) function to print computing status and the result of multiplication to the output.
45
46    ```kotlin
47    import kotlinx.coroutines.*
48
49    fun main() = runBlocking<Unit> {
50        val a = async {
51            println("I'm computing part of the answer")
52            6
53        }
54        val b = async {
55            println("I'm computing another part of the answer")
56            7
57        }
58        println("The answer is ${a.await() * b.await()}")
59    }
60    ```
61
625. Build the code by clicking **Build Project**.
63
64    ![Build an application](flow-build-project.png)
65
66## Debug coroutines
67
681. Set breakpoints at the lines with the `println()` function call:
69
70    ![Build a console application](coroutine-breakpoint.png)
71
722. Run the code in debug mode by clicking **Debug** next to the run configuration at the top of the screen.
73
74    ![Build a console application](flow-debug-project.png)
75
76    The **Debug** tool window appears:
77    * The **Frames** tab contains the call stack.
78    * The **Variables** tab contains variables in the current context.
79    * The **Coroutines** tab contains information on running or suspended coroutines. It shows that there are three coroutines.
80    The first one has the **RUNNING** status, and the other two have the **CREATED** status.
81
82    ![Debug the coroutine](coroutine-debug-1.png)
83
843. Resume the debugger session by clicking **Resume Program** in the **Debug** tool window:
85
86    ![Debug the coroutine](coroutine-debug-2.png)
87
88    Now the **Coroutines** tab shows the following:
89    * The first coroutine has the **SUSPENDED** status – it is waiting for the values so it can multiply them.
90    * The second coroutine is calculating the `a` value – it has the **RUNNING** status.
91    * The third coroutine has the **CREATED** status and isn’t calculating the value of `b`.
92
934. Resume the debugger session by clicking **Resume Program** in the **Debug** tool window:
94
95    ![Build a console application](coroutine-debug-3.png)
96
97    Now the **Coroutines** tab shows the following:
98    * The first coroutine has the **SUSPENDED** status – it is waiting for the values so it can multiply them.
99    * The second coroutine has computed its value and disappeared.
100    * The third coroutine is calculating the value of `b` – it has the **RUNNING** status.
101
102Using IntelliJ IDEA debugger, you can dig deeper into each coroutine to debug your code.
103
104### Optimized-out variables
105
106If you use `suspend` functions, in the debugger, you might see the "was optimized out" text next to a variable's name:
107
108![Variable "a" was optimized out](variable-optimised-out.png)
109
110This text means that the variable's lifetime was decreased, and the variable doesn't exist anymore.
111It is difficult to debug code with optimized variables because you don't see their values.
112You can disable this behavior with the `-Xdebug` compiler option.
113
114> __Never use this flag in production__: `-Xdebug` can [cause memory leaks](https://youtrack.jetbrains.com/issue/KT-48678/Coroutine-debugger-disable-was-optimised-out-compiler-feature#focus=Comments-27-6015585.0-0).
115>
116{type="warning"}