DAP是VSCode调试核心协议,通过JSON-RPC实现编辑器与调试适配器通信。文章解析其机制并指导用Node.js实现支持launch和continue的简单适配器,涵盖消息解析、响应发送、事件上报及插件注册流程。

VSCode 的调试功能强大,背后依赖的是 Debug Adapter Protocol(DAP),即调试适配器协议。要开发自定义调试器并集成到 VSCode 中,理解 DAP 是关键。本文剖析该协议机制,并指导如何实现一个简单的自定义调试适配器。
DAP 是一种基于 JSON 的通信协议,运行在 VSCode 编辑器(前端)与 调试适配器(后端)之间。它的设计目标是解耦编辑器和具体语言的调试逻辑,使得任意语言只要提供符合 DAP 规范的调试适配器,就能在 VSCode 中获得完整的调试支持。
通信通常通过标准输入输出(stdin/stdout)进行,使用带有 Content-Length 头的 JSON-RPC 消息格式。例如:
Content-Length: 134\r\n\r\n{"type":"request","command":"launch","arguments":{"program":"app.js"},"seq":1,"command":"launch"}VSCode 发送请求,调试适配器接收并返回响应或发送事件(如断点命中、线程启动等)。
一次调试会话从用户点击“启动调试”开始,VSCode 根据 launch.json 配置启动调试适配器进程,并建立通信通道。
主要流程如下:
以 Node.js 为例,编写一个最简调试适配器,支持 launch 和基本 continue 操作。
步骤 1:创建基础结构
新建文件 debugAdapter.js,监听 stdin 输入:
const readline = require('readline'); let seq = 0; const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.on('line', line => { if (line.startsWith('Content-Length')) { // 解析带长度头的消息 const match = line.match(/Content-Length: (\d+)/); if (match) { const len = parseInt(match[1]); // 下一行是空行,再下一行是 JSON rl.once('line', () => { rl.once('line', jsonLine => { handleMessage(JSON.parse(jsonLine)); }); }); } } });步骤 2:处理 initialize 请求
function handleMessage(msg) { switch (msg.command) { case 'initialize': sendResponse(msg.seq, { supportsConfigurationDoneRequest: true, supportsEvaluateForHovers: true }); break; case 'launch': handleLaunch(msg); break; case 'continue': handleContinue(msg); break; case 'disconnect': process.exit(0); } } function sendResponse(seq, body) { const resp = { type: 'response', seq: ++seq, request_seq: seq, command: msg.command, success: true, body }; sendRaw(JSON.stringify(resp)); } function sendRaw(jsonStr) { process.stdout.write(`Content-Length: ${Buffer.byteLength(jsonStr)}\r\n\r\n${jsonStr}`); }步骤 3:模拟 launch 与事件上报
function handleLaunch(req) { sendEvent('initialized'); // 通知 VSCode 可以设置断点了 sendResponse(req.seq, {}); } function sendEvent(event, body) { const msg = { type: 'event', event, seq: ++seq, body }; sendRaw(JSON.stringify(msg)); }当收到 launch 后,发送 initialized 事件,VSCode 接着会发送 setBreakpoints 请求(需实现),但本例略去。
修改 package.json 插件配置:
"contributes": { "debuggers": [{ "type": "my-debug", "label": "My Debugger", "programs": { "adapter": "./out/debugAdapter.js" }, "configurationAttributes": { "launch": { "required": ["program"], "properties": { "program": { "type": "string", "description": "The program to debug" } } } }, "initialConfigurations": [ { "name": "Launch Program", "type": "my-debug", "request": "launch", "program": "${workspaceFolder}/app.js" } ] }] }安装插件后,即可选择 “my-debug” 类型启动调试。
基本上就这些。真正实用的适配器需要对接实际解释器或运行时(如 V8、GDB、Python 的 pdb),解析源码映射、管理调用栈、变量作用域等。但核心通信模型不变 —— 实现 DAP 协议规定的 request、response、event 交互。
以上就是VSCode调试协议剖析_自定义调试器适配器开发的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号