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 调用。
相关推荐
一丝晨光4 小时前
Java、PHP、ASP、JSP、Kotlin、.NET、Go
java·kotlin·go·php·.net·jsp·asp
500了13 小时前
Kotlin基本知识
android·开发语言·kotlin
陈亦康1 天前
Armeria gPRC 高级特性 - 装饰器、无框架请求、阻塞处理器、Nacos集成、负载均衡、rpc异常处理、文档服务......
kotlin·grpc·armeria
奋斗的小鹰2 天前
kotlin 委托
android·开发语言·kotlin
Wency(王斯-CUEB)2 天前
【文献阅读】政府数字治理的改善是否促进了自然资源管理?基于智慧城市试点的准自然实验
android·kotlin·智慧城市
中游鱼2 天前
Visual Studio C# 编写加密火星坐标转换
kotlin·c#·visual studio
500了2 天前
kotlin协程
开发语言·python·kotlin
ChinaDragonDreamer4 天前
Kotlin:1.8.0 的新特性
android·开发语言·kotlin
IH_LZH4 天前
Kotlin:变量声明,null安全,条件语句,函数,类与对象
android·开发语言·kotlin
Forbesdytto5 天前
kotlin中的对象表达式与java中的匿名内部类
java·kotlin·移动端