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 调用。
相关推荐
Kapaseker2 小时前
Compose SelectionState API — 主动控制文本选择
android·kotlin
小强闯江湖18 小时前
不只是让 AI 写代码:ViewCompose 把 Android UI 做成了可编译、可渲染的闭环
android·人工智能·kotlin
bytebitx2 天前
MacOS 编译腾讯 Mars XLog 及使用(已16KB对齐)
kotlin·mac·apk
alexhilton3 天前
让架构边界变成可执行的测试
android·kotlin·android jetpack
数据治理自习室3 天前
AI 应用评测体系(GraphRAG)
android·大数据·人工智能·kotlin
名剑走天下4 天前
Android 面试题大全
android·kotlin
chjif4 天前
Android 设备管控开发实战:自定义 Launcher 如何只显示指定 App?
android·kotlin
非凡ghost4 天前
用 Kotlin 和 Jetpack Compose 重写的安卓视频播放器,原生体验有多流畅?
android·java·kotlin·音视频·软件需求
名剑走天下5 天前
android 面试题
kotlin
蜡台5 天前
Jetpack Compose 稳定性、重组优化(Stable / @NonRestartableComposable)
android·kotlin·compose·jepack