kotlin协程代码生成-5.Debug(译)

kotlin协程代码生成翻译文章系列,翻译自 coroutineCodegenUtil.kt

Debug

调试协程并不像调试常规代码那样直观。例如,由于挂起调用可能会暂停,甚至简单的调试事件,如"步进",都需要代码生成器和调试器的支持才能实现。另一个例子是从协程中抛出异常,这可能导致不同的堆栈跟踪,取决于协程是否已经暂停并且然后恢复,或者暂停是否从未发生过。如果协程已经暂停并且然后恢复,堆栈跟踪甚至可能没有用户代码,只有库代码,使得调试变得非常困难。

本节将解释代码生成器如何提供调试器所需的信息。

Step-over

在协程代码生成中,历史上第一个的调试支持是"步进"功能。该调用会返回一个值或COROUTINE_SUSPENDED标记。因此,状态机会检查结果,并继续执行或返回该标记。因此,状态机构建器会生成两个执行路径:直接调用和挂起-恢复。如果调用返回一个值,那么"步进"操作会像平常一样运行。然而,如果我们想要支持挂起-恢复路径,则需要代码生成器和调试器的一些技巧。

首先,代码生成器在返回COROUTINE_SUSPENDED标记之前会放置额外的LINENUMBER指令。这样,当用户按下"步进"按钮时,调试器会在这个LINENUMBER处设置断点,并在执行到达下一行(在直接路径的情况下)或断点时移除它。这个虚构的LINENUMBER的行号是调用者标头的行号。我们选择了这个数字,因为我们需要行号在函数之间不同(可能有多个挂起调用,等待"步进"完成),而且不干扰用户代码。

当协程恢复时,断点会再次触发,因为代码生成器在函数开始处生成另一个LINENUMBER

总而言之,代码生成器在挂起-恢复路径中生成了N+1个虚构的LINENUMBER指令,因此调试器可以在行号上放置断点,并使用一个断点模拟"步进",该断点被触发两次。

Debug Metadata

The continuation-passing-style 解释了当我们恢复一个协程时,它的调用者变成了BaseContinuationImpl.resumeWith。然而,用户希望看到调用挂起协程的协程。幸运的是,可以通过completion链获得关于调用者的信息。使用该链构造的堆栈跟踪称为异步堆栈跟踪。

然而,首先,代码生成器应提供这些信息。为此,每个继续类都有一个@kotlin.coroutines.jvm.internal.DebugMetadata注解,其中包含以下字段:

  1. 源文件、类名和方法名,以及行号,用于生成异步堆栈跟踪元素。
  2. 一个行号数组,将label值映射到挂起点行号。
  3. 从溢出变量到本地变量的映射,调试器用于显示变量的值。

调试器和kotlinx.coroutines都使用调试元数据生成异步堆栈跟踪。

继续类的toString方法使用调试元数据显示协程挂起的位置。

请注意,尾调用优化会删除继续类。因此,异步堆栈跟踪中存在间隙。此外,只存储挂起点的行号;因此,行号并不总是准确的。

Probes

kotlin.coroutines.jvm.internal 包含一些探测函数,由调试器替换以显示当前协程(在广义上)及其状态:挂起或运行。

  1. probeCoroutineCreatecreateCoroutine 函数中被调用。
  2. probeCoroutineResumedBaseContinuationImpl.resumeWith 函数中被调用。
  3. 如果 suspendCoroutineUninterceptedOrReturn 返回 COROUTINE_SUSPENDED,则代码生成器生成 probeCoroutineSuspended 调用。
相关推荐
モンキー・D・小菜鸡儿1 天前
Android 中 StateFlow 的使用
android·kotlin
我又来搬代码了1 天前
【Android】【Compose】Compose知识点复习(一)
android·前端·kotlin·android studio
hnlgzb1 天前
好像kotlin class和kotlin file都可以是activity?
android·开发语言·kotlin
zhangphil1 天前
Kotlin超时withTimeout超时与ensureActive()取消协程任务执行
kotlin
hnlgzb2 天前
安卓app开发,如何快速上手kotlin和compose的开发?
android·开发语言·kotlin
alexhilton2 天前
Jetpack Compose 2025年12月版本新增功能
android·kotlin·android jetpack
lin62534222 天前
Android九宫格,1张图到9张图适配;图片自定义UI
android·ui·kotlin
zhangphil2 天前
Kotlin协程buffer缓冲池,调度任务执行
kotlin
モンキー・D・小菜鸡儿3 天前
Android Jetpack Compose 基础控件介绍
android·kotlin·android jetpack·compose