IntelliJ IDEA로 코루틴 디버깅하기 – 튜토리얼

IntelliJ IDEA로 코루틴 디버깅하기 – 튜토리얼 (Debug coroutines using IntelliJ IDEA – tutorial)

코루틴은 실행 흐름이 여러 갈래로 나뉘다 보니 디버깅이 까다로운 편이에요. 이 튜토리얼에서는 IntelliJ IDEA에서 Kotlin 코루틴을 만들고 디버깅하는 방법을 실제 코드로 배워 볼게요.

출처: Kotlin 공식 문서

본문

이 튜토리얼은 IntelliJ IDEA를 사용해 Kotlin 코루틴을 만들고 디버깅하는 방법을 보여줘요.

이 튜토리얼은 코루틴 개념에 대한 사전 지식이 있다고 가정해요.

코루틴 만들기

  1. IntelliJ IDEA에서 Kotlin 프로젝트를 열어요. 프로젝트가 없다면 프로젝트를 하나 만들어요.

  2. Gradle 프로젝트에서 kotlinx.coroutines 라이브러리를 사용하려면 build.gradle(.kts)에 다음 의존성을 추가해요.

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

    Groovy DSL(build.gradle)이라면:

    dependencies {
        implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.11.0'
    }
    

    다른 빌드 시스템에 대해서는 kotlinx.coroutines README의 지침을 참고해요.

  3. src/main/kotlin에 있는 Main.kt 파일을 열어요.

    src 디렉터리에는 Kotlin 소스 파일과 리소스가 들어 있어요. Main.kt 파일에는 Hello World!를 출력하는 샘플 코드가 담겨 있어요.

  4. main() 함수에서 코드를 변경해요.

    • runBlocking() 블록을 사용해 코루틴을 감싸요.

    • async() 함수를 사용해 지연된 값을 계산하는 코루틴 ab를 만들어요.

    • await() 함수를 사용해 계산 결과를 기다려요.

    • println() 함수를 사용해 계산 상태와 곱셈 결과를 출력해요.

    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 Project를 클릭해 코드를 빌드해요.

    애플리케이션 빌드

코루틴 디버깅하기

  1. println() 함수 호출이 있는 줄에 중단점(breakpoint)을 설정해요.

    콘솔 애플리케이션 빌드

  2. 화면 상단의 실행 구성 옆에 있는 Debug를 클릭해 디버그 모드로 코드를 실행해요.

    콘솔 애플리케이션 빌드

    Debug 도구 창이 나타나요.

    • Frames 탭에는 호출 스택이 들어 있어요.

    • Variables 탭에는 현재 컨텍스트의 변수가 들어 있어요.

    • Coroutines 탭은 실행 중이거나 중단된 코루틴에 대한 정보를 담아요. 세 개의 코루틴이 있음을 보여줘요. 첫 번째는 RUNNING 상태이고, 나머지 두 개는 CREATED 상태예요.

    코루틴 디버깅

  3. Debug 도구 창에서 Resume Program을 클릭해 디버거 세션을 재개해요.

    코루틴 디버깅

    이제 Coroutines 탭은 다음을 보여줘요.

    • 첫 번째 코루틴은 SUSPENDED 상태예요. 값을 곱할 수 있길 기다리고 있죠.

    • 두 번째 코루틴은 a 값을 계산하고 있어요. RUNNING 상태예요.

    • 세 번째 코루틴은 CREATED 상태이고, b 값을 계산하고 있지 않아요.

  4. Debug 도구 창에서 Resume Program을 클릭해 디버거 세션을 다시 재개해요.

    콘솔 애플리케이션 빌드

    이제 Coroutines 탭은 다음을 보여줘요.

    • 첫 번째 코루틴은 SUSPENDED 상태로 값을 곱할 수 있길 기다리고 있어요.

    • 두 번째 코루틴은 값을 계산하고 사라졌어요.

    • 세 번째 코루틴은 b 값을 계산하고 있어요. RUNNING 상태예요.

IntelliJ IDEA 디버거를 사용하면 각 코루틴을 더 깊이 파고들어 코드를 디버깅할 수 있어요.

최적화되어 사라진 변수 (Optimized-out variables)

suspend 함수를 사용하면 디버거에서 변수 이름 옆에 "was optimized out" 텍스트가 보일 수 있어요.

변수 "a"가 최적화되어 사라짐이 텍스트는 변수의 수명이 줄어들어, 그 변수가 더 이상 존재하지 않음을 의미해요. 최적화된 변수는 값을 볼 수 없기 때문에 디버깅하기 어려워요. -Xdebug 컴파일러 옵션으로 이 동작을 비활성화할 수 있어요.

프로덕션에서는 절대 이 플래그를 사용하지 마세요. -Xdebug메모리 누수를 유발할 수 있어요.