Kotlin Help

Debug coroutines using IntelliJ IDEA ā€“ tutorial

This tutorial demonstrates how to create Kotlin coroutines and debug them using IntelliJ IDEA.

The tutorial assumes you have prior knowledge of the coroutines concept.

Create coroutines

  1. Open a Kotlin project in IntelliJ IDEA. If you don't have a project, create one.

  2. To use the kotlinx.coroutines library in a Gradle project, add the following dependency to build.gradle(.kts):

    dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") }
    dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1' }

    For other build systems, see instructions in the kotlinx.coroutines README.

  3. Open the Main.kt file in src/main/kotlin.

    The src directory contains Kotlin source files and resources. The Main.kt file contains sample code that will print Hello World!.

  4. Change code in the main() function:

    • Use the runBlocking() block to wrap a coroutine.

    • Use the async() function to create coroutines that compute deferred values a and b.

    • Use the await() function to await the computation result.

    • Use the println() function to print computing status and the result of multiplication to the output.

    import kotlinx.coroutines.* fun main() = runBlocking<Unit> { val a = async { println("I'm computing part of the answer") 6 } val b = async { println("I'm computing another part of the answer") 7 } println("The answer is ${a.await() * b.await()}") }
  5. Build the code by clicking Build Project.

    Build an application

Debug coroutines

  1. Set breakpoints at the lines with the println() function call:

    Build a console application
  2. Run the code in debug mode by clicking Debug next to the run configuration at the top of the screen.

    Build a console application

    The Debug tool window appears:

    • The Frames tab contains the call stack.

    • The Variables tab contains variables in the current context.

    • The Coroutines tab contains information on running or suspended coroutines. It shows that there are three coroutines. The first one has the RUNNING status, and the other two have the CREATED status.

    Debug the coroutine
  3. Resume the debugger session by clicking Resume Program in the Debug tool window:

    Debug the coroutine

    Now the Coroutines tab shows the following:

    • The first coroutine has the SUSPENDED status – it is waiting for the values so it can multiply them.

    • The second coroutine is calculating the a value – it has the RUNNING status.

    • The third coroutine has the CREATED status and isn’t calculating the value of b.

  4. Resume the debugger session by clicking Resume Program in the Debug tool window:

    Build a console application

    Now the Coroutines tab shows the following:

    • The first coroutine has the SUSPENDED status – it is waiting for the values so it can multiply them.

    • The second coroutine has computed its value and disappeared.

    • The third coroutine is calculating the value of b – it has the RUNNING status.

Using IntelliJ IDEA debugger, you can dig deeper into each coroutine to debug your code.

Optimized-out variables

If you use suspend functions, in the debugger, you might see the "was optimized out" text next to a variable's name:

Variable "a" was optimized out

This text means that the variable's lifetime was decreased, and the variable doesn't exist anymore. It is difficult to debug code with optimized variables because you don't see their values. You can disable this behavior with the -Xdebug compiler option.

Last modified: 16 February 2022