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 调用。
相关推荐
heeheeai11 小时前
kotlin kmp 副作用函数 effect
kotlin·effect·kmp·副作用函数
纳于大麓12 小时前
Kotlin基础语法一
android·开发语言·kotlin
KotlinKUG贵州16 小时前
Spring开发,从Kotlin开始
spring boot·spring·kotlin
移动开发者1号19 小时前
Android中Activity、Task与Process的关系
android·kotlin
移动开发者1号19 小时前
Activity onCreate解析
android·kotlin
alexhilton1 天前
在Android应用中实战Repository模式
android·kotlin·android jetpack
雨白1 天前
高阶函数与内联优化
kotlin
&岁月不待人&2 天前
实现弹窗随键盘上移居中
java·kotlin
移动开发者1号2 天前
Android Activity状态保存方法
android·kotlin
移动开发者1号2 天前
Volley源码深度分析与设计亮点
android·kotlin