调试适配器协议的新家园
2018 年 8 月 7 日 André Weinand,@weinand
七月里程碑的目标之一是将调试适配器协议——它一直“隐藏”在一个有些“晦涩”的 GitHub 项目中——迁移到一个更醒目的网站(参见功能请求 #19636)。
这篇博客将介绍协议、调试适配器协议的一些背景信息,以及此次迁移的动机。
为什么需要通过协议解耦?
摘自另一篇博客
“Visual Studio Code 是一款面向所有开发人员的编辑器,无论您使用何种编程语言。”
这项承诺基于(至少)两大支柱:
- 一个可扩展的工具平台和生态系统,每个人都可以轻松贡献。
- 使任何编程语言都能轻松获得出色工具支持的技术。
开发工具支持编程语言意味着:
- 基于对语言的深入理解(又称“语言智能”)的丰富编辑支持。
- 集成到编辑工具中的语言调试支持。
后者可能会让一些人感到惊讶,但我们一直坚信调试是源代码编写地——编辑器——不可或缺的一部分。调试是开发“内部循环”的重要组成部分。
但是,为新的语言向 IDE 或编辑器添加调试器是一项艰巨的工作,因为标准调试功能的列表不小:
- 源、函数、条件、行内断点和日志点。
- 在悬停或源代码中行内显示变量值。
- 多进程和多线程支持。
- 遍历复杂数据结构。
- 监视表达式。
- 用于带自动完成功能的交互式评估的调试控制台(REPL)。
为一种新语言实现这些功能不仅需要巨大的努力,而且令人沮丧的是,这项工作必须为每个开发工具重复进行,因为每个工具都使用不同的 API 来实现其用户界面。
这导致了大量重复的功能(和实现),如下图中的蓝色方框所示:
当我们开始开发 Visual Studio Code 时,我们一直设想尽可能地将“前端”UI 与语言特定的“后端”实现解耦。我们希望在语言智能和调试支持方面都这样做。
今天我们相信我们已经实现了这个宏伟的目标:
我们创建了两个抽象协议,允许将“前端”中的编辑和调试用户界面与“后端”组件提供的语言特定智能和调试功能解耦。
“对语言的深入理解”通过语言服务器协议(LSP)得以体现,而“调试支持”则通过调试适配器协议(DAP)得以体现。
调试适配器协议
调试适配器协议背后的理念是为开发工具的调试组件如何与具体的调试器或运行时进行通信标准化一个抽象协议。
由于假设现有调试器或运行时会很快采用此协议是不现实的,因此我们设计了一个中间组件来承担将现有调试器或运行时 API 适配到调试适配器协议的角色。这个中间组件就成为了调试适配器,这解释了协议的名称:调试适配器协议。
这是一个开发工具如何使用 DAP 与流行的“gdb”调试器的调试适配器进行通信的示例:
我们假设用户已经启动了一个调试会话,但目前停留在程序的入口点,并希望设置(并随后命中)一个断点。
- 用户通过点击断点槽位在一个特定的源文件中设置一个或多个断点。开发工具向调试适配器发送一个`setBreakpoints`请求,调试适配器将断点注册到 gdb 调试器。
- 用户接着按下继续按钮以恢复执行。工具向调试适配器发送一个`continue`请求,调试适配器将其转换为相应的 gdb 命令。
- 一段时间后,断点被命中,调试适配器收到 gdb 的一些通知,并将其转换为 DAP `stopped`事件,然后发送给开发工具。
- 为了响应此 `stopped` 事件,开发工具更新其 UI 并显示堆栈跟踪视图。这会触发 `stacktrace` 请求,该请求返回为单个堆栈帧显示的所有信息。
- 如果用户选择一个堆栈帧,开发工具会使用 `variables` 请求来获取该帧的变量。
由于历史原因,DAP 使用了一种基于 JSON 的有线格式,灵感来自(现已废弃的)V8 调试协议。请注意,这种格式与 LSP 中使用的 JSON-RPC 类似但不兼容。
在简短的 DAP 通信示例之后,让我们回顾一下 DAP 方法的特点:
该图展示了 DAP 方法的两个重要优点:
- 调试适配器可以在不同的开发工具之间共享,这有助于分摊其开发成本。
- 调试适配器协议不与 VS Code 绑定,可以作为其他开发工具中通用调试器 UI 的基础。
这些特性与 2016 年在其独立网站上发布的语言服务器协议的特性相似。
DAP 的新家园
现在我们已经效仿调试适配器协议,将 DAP 规范从旧位置迁移到新网站https://msdocs.cn/debug-adapter-protocol,以及相应的仓库https://github.com/microsoft/debug-adapter-protocol。
此举应强调调试适配器协议并非特定于 Visual Studio Code。例如,Visual Studio 现在也支持此协议。
在新位置,我们提供:
- 协议的概述和介绍。
- 可机器处理的JSON 模式形式的协议规范。
- 从协议规范自动生成的详细文档。
- 实现该协议的调试适配器。
- 承载该协议的开发工具。
- 支持该协议的SDK。
- 错误、功能请求和拉取请求可以在新仓库的问题部分创建。
旧位置将继续托管 DAP 的三个 npm 模块的源代码:
下一步?
由于调试适配器协议已经存在了一段时间,所以这次迁移到新网站并不是真正的首次亮相,而只是搬到了新家...
我们诚挚邀请所有现有和未来的 DAP 用户访问我们的新家,并继续在那里协作。例如,您可以通过在 GitHub 上针对以下 Markdown 文件提交拉取请求来帮助更新支持工具和实现的列表:调试适配器、工具和SDK。
代表 VS Code 团队:祝您编码愉快!
André Weinand - Twitter 上的 @weinand