You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VS Code是否提供调试器API?程序化调试交互需求咨询

解决方案:通过VS Code DAP编程交互实现变量自动转储

核心思路

VS Code的调试系统基于Debug Adapter Protocol (DAP),不管底层用的是cppvsdbg还是其他调试后端,都可以通过DAP接口与调试器编程交互。你可以用Python(通过WebSocket连接DAP)或JS/TS(通过VS Code扩展API)实现以下需求:

  • 无需修改目标C/C++/Fortran代码
  • 利用调试器的符号反射能力自动获取所有变量字段
  • 在调试断点/执行暂停时自动将变量转储到文件

方案一:Python实现(优先推荐)

通过Python的WebSocket客户端连接VS Code的DAP服务,监听调试暂停事件,获取并转储变量。

步骤1:获取DAP连接地址

启动VS Code调试会话后,通过以下方式获取DAP的WebSocket地址:

  1. 打开VS Code设置,启用debug.debugAdapter.log
  2. 查看调试控制台的日志,找到类似WebSocket server listening on ws://localhost:XXXX/debug的行,复制该地址

步骤2:Python代码实现

首先安装依赖:

pip install websockets

示例代码(自动转储暂停时的所有变量):

import asyncio
import websockets
import json
from datetime import datetime

async def debug_variable_dumper():
    # 替换为你从DAP日志中获取的WebSocket地址
    dap_ws_url = "ws://localhost:5003/debug"
    
    async with websockets.connect(dap_ws_url) as ws:
        print("Connected to VS Code DAP server")
        
        # 完成DAP初始化握手
        init_msg = {
            "seq": 1,
            "type": "request",
            "command": "initialize",
            "arguments": {
                "clientID": "python-dap-dumper",
                "clientName": "Python Variable Dumper",
                "adapterID": "cppvsdbg",
                "linesStartAt1": True,
                "columnsStartAt1": True,
                "supportsVariableType": True,
                "supportsRunInTerminalRequest": True
            }
        }
        await ws.send(json.dumps(init_msg))
        await ws.recv()  # 忽略初始化响应
        
        # 持续监听调试事件
        while True:
            raw_msg = await ws.recv()
            msg = json.loads(raw_msg)
            
            # 捕获调试器暂停事件
            if msg.get("type") == "event" and msg.get("event") == "stopped":
                thread_id = msg["body"]["threadId"]
                print(f"Debugger stopped (reason: {msg['body']['reason']})")
                
                # 获取当前栈帧ID
                stack_req = {
                    "seq": 2,
                    "type": "request",
                    "command": "stackTrace",
                    "arguments": {"threadId": thread_id, "levels": 1}
                }
                await ws.send(json.dumps(stack_req))
                stack_res = json.loads(await ws.recv())
                frame_id = stack_res["body"]["stackFrames"][0]["id"]
                
                # 获取当前栈帧的所有变量(局部、全局、静态)
                vars_req = {
                    "seq": 3,
                    "type": "request",
                    "command": "variables",
                    "arguments": {"frameId": frame_id, "filter": "all"}
                }
                await ws.send(json.dumps(vars_req))
                vars_res = json.loads(await ws.recv())
                
                # 转储变量到JSON文件
                timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
                dump_file = f"variable_dump_{timestamp}.json"
                with open(dump_file, "w", encoding="utf-8") as f:
                    json.dump(vars_res["body"]["variables"], f, indent=2)
                print(f"Variables saved to {dump_file}")
                
                # 自动继续调试会话
                continue_req = {
                    "seq": 4,
                    "type": "request",
                    "command": "continue",
                    "arguments": {"threadId": thread_id}
                }
                await ws.send(json.dumps(continue_req))

asyncio.run(debug_variable_dumper())

方案二:JS/TS VS Code扩展(更集成化)

通过VS Code扩展API直接调用调试接口,无需手动处理WebSocket,体验更流畅。

扩展核心代码(extension.ts)

import * as vscode from 'vscode';
import * as fs from 'fs';
import * as path from 'path';

export function activate(context: vscode.ExtensionContext) {
    // 注册启动转储的命令
    const startDumper = vscode.commands.registerCommand('var-dumper.start', async () => {
        const session = vscode.debug.activeDebugSession;
        if (!session) {
            vscode.window.showErrorMessage('No active debug session detected');
            return;
        }

        // 监听调试暂停事件
        const stopListener = session.onDidReceiveDebugSessionCustomEvent('stopped', async (event) => {
            const threadId = event.body.threadId;
            
            // 获取当前栈帧
            const stackRes = await session.customRequest('stackTrace', {
                threadId,
                levels: 1
            });
            const frameId = stackRes.stackFrames[0].id;
            
            // 获取所有变量
            const varsRes = await session.customRequest('variables', {
                frameId,
                filter: 'all'
            });
            
            // 生成转储文件
            const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
            const dumpPath = path.join(
                vscode.workspace.rootPath || process.cwd(),
                `var_dump_${timestamp}.json`
            );
            fs.writeFileSync(dumpPath, JSON.stringify(varsRes.variables, null, 2), 'utf-8');
            vscode.window.showInformationMessage(`Variables dumped to: ${dumpPath}`);
            
            // 自动继续执行
            await session.customRequest('continue', { threadId });
        });

        context.subscriptions.push(stopListener);
        vscode.window.showInformationMessage('Variable dumper activated - will dump on every debug stop');
    });

    context.subscriptions.push(startDumper);
}

export function deactivate() {}

扩展配置(package.json片段)

在contributes字段中添加命令声明:

{
    "contributes": {
        "commands": [
            {
                "command": "var-dumper.start",
                "title": "Start Variable Dumper"
            }
        ]
    }
}

关键特性说明

  • 无需修改目标代码:所有变量读取操作都通过调试器的符号表完成,目标程序无需添加任何跟踪或日志代码。
  • 自动反射字段:cppvsdbg后端会自动解析C/C++/Fortran的类型信息,返回结构体、数组、派生类型的完整字段,无需手动定义结构。
  • Windows环境兼容:cppvsdbg是Windows原生调试后端,两种方案均完美适配。
  • 自定义触发逻辑:可修改代码,实现仅在特定断点、函数调用或条件满足时触发转储(比如在stopped事件中判断msg['body']['reason']或添加变量值条件)。

内容的提问来源于stack exchange,提问作者Mazrog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 03:08:13