ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Dart 调试适配器(Debug Adapter Protocol)实战指南:从 `dart debug_adapter` 命令到自定义请求与事件

Dart 调试适配器(Debug Adapter Protocol)实战指南:从 `dart debug_adapter` 命令到自定义请求与事件 编程语言编译器语言运行时标准库开发工具【免费下载链接】sdkThe Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.项目地址https://gitcode.com/gh_mirrors/sdk1/sdk点击查看免费下载本文以 Dart SDK 仓库中的 third_party/pkg/dap/tool/README.md 为核心骨架并结合pkg/dap_adapters、pkg/dartdev等模块的源码实现系统讲解 Dart 的 DAP 调试适配器如何启动、如何通过launchRequest/attachRequest配置调试会话、如何使用表达式格式说明符以及适配器提供的一整套自定义请求与自定义事件。读完本文你将能直接为编辑器或自定义 DAP 客户端编写 launch/attach 配置并理解这些配置项在 SDK 源码中的真实处理逻辑。一、概述Dart 如何接入 Debug Adapter ProtocolDart SDK 内置了基于Debug Adapter ProtocolDAP的调试支持作为直接使用VM Service见 runtime/vm/service/service.md的替代方案从而让新的编辑器集成调试功能时更加简单编辑器只需实现 DAP 客户端无需了解 Dart VM 内部协议细节。调试适配器通过dart debug_adapter命令启动源码见 pkg/dartdev/lib/src/commands/debug_adapter.dart注意命令名同时兼容旧的debug_adapter拼写它面向两类使用者已内置 DAP 客户端的编辑器扩展例如 VS Code 的 Dart Code 扩展自带通用 DAP 客户端配置能力的编辑器用户自行编写 launch/attach 配置。SDK 提供两个适配器命令运行方式特点dart debug_adapter标准适配器用dart运行脚本面向普通 Dart CLI 程序的调试dart debug_adapter --test用dart test运行脚本面向测试调试额外发出dart.testNotification自定义事件重要行为说明DAP 协议规定由客户端先开口client speaks first因此直接在终端里运行dart debug_adapter不会产生任何输出、进程也不会退出——这是完全正常的预期行为它只是静静地等待 DAP 客户端通过 stdin/stdout 建立会话。命令实现中针对这一场景做了兜底将协议解析错误写入 stderr并提示该命令面向工具而非人工使用见 debug_adapter.dart。从命令行源码debug_adapter.dart还可以看到该命令附带以下 flag--ipv6是否让 DAP / VM Service / DDS 绑定 IPv6 地址默认false--test是否使用dart test调试适配器默认false开启后脚本通过dart test运行并发送测试进度/结果事件--dds、--auth-codes历史上用于控制 DDS 与 VM Service 鉴权码的开关当前已被标记为废弃占位DAP 不再自行拉起 DDS仅保留以免老客户端传入时崩溃。关于 FlutterFlutter 应用的调试应由flutter工具内置的调试适配器驱动而不应直接使用dart debug_adapter相关说明见 Flutter 仓库中packages/flutter_tools/lib/src/debug_adapters/的文档本仓库 docs 目录不涉及该内容此处仅作提示勿混淆使用场景。二、Launch/Attach 参数详解launchRequest与attachRequest的载荷参数在适配器实现中被解析为DartCommonLaunchAttachRequestArguments、DartLaunchRequestArguments与DartAttachRequestArguments等类见 pkg/dap_adapters/lib/src/adapters/dart.dart。下面按原文档的分类逐一说明并结合源码标注默认值/约束。2.1 通用参数launch 与 attach 均可用参数类型含义debugExternalPackageLibrariesbool?是否启用对当前工作区之外的包的调试debugSdkLibrariesbool?是否启用对 SDK 库的调试showGettersInDebugViewsbool?是否在 Variables / Evaluation 响应含悬停、Watch 窗口中包含 getterevaluateGettersInDebugViewsbool?是否无需用户操作即预求值 getter隐含showGettersInDebugViewstrueevaluateToStringInDebugViewsbool?是否在表达式求值请求中调用toString()含悬停、Watch 窗口sendLogsToClientbool?是否将全部 VM Service 流量通过自定义dart.log事件代理回客户端有性能开销用于排障vmServicePortint?VM Service 绑定的端口additionalProjectPathsListString?工作区中除cwd外打开的其他项目路径cwdString?生成 Dart 进程的工作目录envMapString, String?传递给所生成进程的环境变量sendCustomProgressEventsbool?是否用自定义dart.progressStart/dart.progressUpdate/dart.progressEnd事件替代标准 DAP 进度事件开启后即使客户端声明了supportsProgressReporting也不会再发送标准事件allowAnsiColorOutputbool?是否允许在 Output 事件中输出 ANSI 颜色码从源码看这些字段统一由DebugAdapterArgumentReader从请求 map 中读取dart.dart其中sendCustomProgressEvents在无值时默认取false而env在 attach 场景中不被支持因为 attach 不生成新进程适配器构造 attach 参数时将其置空。2.2 launchRequest 专属参数参数类型含义noDebugbool?是否以 noDebug 模式运行不调试只运行缺省为调试模式programString要运行的 Dart 程序路径必填argsListString?传给 Dart 程序的参数位于命令行program之后toolArgsListString?传给“启动工具”的参数CLI 脚本为dart之后的参数测试脚本为dart run test:test之后的参数vmAdditionalArgsListString?直接传给 Dart VM 的参数CLI 与测试场景都位于dart之后consoleString?若为terminal或externalTerminal则通过runInTerminal反向请求运行否则由适配器自己生成 Dart 进程customToolString?可选的替代工具用来替换dart该工具必须与被替换的工具/命令完全兼容customToolReplacesArgsint?调用customTool时从参数列表开头删除的参数个数。例如测试运行时设customTool为dart_test、customToolReplacesArgs为2则最终调用dart_test foo_test.dart而非dart run test:test foo_test.dart若该值大于计算出的参数总数则全部参数都会被移除缺省为0这两个customTool*参数是深度定制调试链路的入口适合团队将dart包装为带私有编译参数的封装工具但封装层必须保持与被替换命令在命令行语义上的完全兼容。2.3 attachRequest 专属参数参数类型含义vmServiceInfoFileString?用于读取 VM Service 信息的文件vmServiceUriString?要附加的 VM Service URI约束vmServiceInfoFile与vmServiceUri二者必须且只能提供一个。对应实现见 dart.dart两类字段分别被读入DartAttachRequestArguments且由于 attach 不生成进程env在该场景不可用。三、表达式求值格式说明符Format Specifiers在 Watch 窗口或 Debug Console 中可以在表达式末尾追加特殊后缀来改变变量的显示格式对应实现类EvaluationExpression见 pkg/dap_adapters/lib/src/variables.dart后缀效果,nq字符串不加引号,h整数按十六进制显示,d整数按十进制base 10显示格式说明符的优先级与传播规则说明符覆盖其他任何格式化方式例如variablesRequest/evaluateRequest中可携带的format参数说明符会沿变量树向下传播对Listint表达式追加,h后列表展开得到的元素也会以十六进制渲染多个说明符可逗号分隔组合对某个类实例写myVariable,nq,h其子字段中的String不引号、int以十六进制显示。从源码实现看解析逻辑由正则(.*?)(?:,([\w,]))$提取表达式主体与后缀集合variables.dart再根据集合中是否包含nq/h/d构造对应的VariableFormat。四、自定义请求Custom Requests除标准 DAP 请求外适配器还实现了若干客户端可调用的自定义请求。以下请求的处理代码集中在 pkg/dap_adapters/lib/src/adapters/dart.dart 的自定义请求分发逻辑中。4.1updateDebugOptions在会话运行期间更新部分调试选项这些选项通常在 launch/attach 时提供。请求中出现的键会覆盖此前设置的值只更新部分值时只需在参数中包含这些键{ debugSdkLibraries: true, debugExternalPackageLibraries: false }对应实现为_updateDebugOptions见 dart.dart。与之配套的还有updateSendLogsToClient源码注释说明它可用于“Capture Debugging Logs”这类按需开启日志代理的命令见 dart.dart可在不重启会话的情况下选择性开启日志转发。4.2callService允许客户端调用任意 VM Service 服务例如已注册的 service extension。服务 RPC/方法名放在method字段中params依所调用服务而定{ method: myFooService, params: { // ... } }实现中该方法为必填项缺失会抛出DebugAdapterException随后通过vmService.callServiceExtension(method, args: params)转发并将服务响应回传给客户端dart.dart。客户端通常通过下文的自定义事件dart.serviceRegistered等获知可调用的服务名再据此发起callService。4.3hotReload对每个活动 isolate 调用 VM 的reloadSources服务重新加载所有被修改的源文件{ method: hotReload, params: null }实现中通过isolateManager.reloadSources()完成dart.dart。源码注释特别说明Flutter 的 DAP 会自行处理该命令经由 run daemon 转发因为 Flutter 还需要在重载后重建 widget。五、自定义事件Custom Events适配器可能向客户端发送以下自定义事件。5.1dart.debuggerUris以调试模式运行时发出携带 VM Service 的 URI{ type: event, event: dart.debuggerUris, body: { vmServiceUri: ws://127.0.0.1:123/abdef123 } }该事件在 dart.dart 附近的会话建立逻辑中发出。5.2dart.log当 launch/attach 参数中sendLogsToClient为true时调试日志以及所有进出 VM Service 的流量都会被代理回客户端以便排查问题{ type: event, event: dart.log, body: { message: log message or json string } }注意该选项存在性能影响只应在排障时开启。5.3dart.serviceRegistered当 VM Service 注册某个服务时发出{ type: event, event: dart.serviceRegistered, body: { service: ServiceName, method: methodName } }5.4dart.serviceUnregistered当 VM Service 注销某个服务时发出body 结构同上{ type: event, event: dart.serviceUnregistered, body: { service: ServiceName, method: methodName } }5.5dart.serviceExtensionAdded当 VM Service Extension 被添加时发出{ type: event, event: dart.serviceExtensionAdded, body: { extensionRPC: extensionRPC to call, isolateId: isolateId } }注册与注销事件在 dart.dart 附近集中发送客户端可据此发现新服务再配合callService调用。5.6dart.testNotification仅在使用--test调试适配器时发出。package:test的 JSON 消息会以该事件原样转发给客户端事件分发见 pkg/dap_adapters/lib/src/adapters/mixins.dart{ type: event, event: dart.testNotification, body: { type: testStart, test: { id: 1, name: my test name, // ... } } }body 内层即package:test的 JSON 报告协议testStart、testDone、success等消息。mixin 实现还会根据消息类型在 Output 事件中渲染对应的测试进度/结果文本如成功/跳过/错误符号与堆栈见 mixins.dart。六、仓库结构从命令到协议实现的调用链理解整个 DAP 调试链路建议按以下路径阅读仓库命令入口pkg/dartdev/lib/src/commands/debug_adapter.dart——dart debug_adapter子命令解析--ipv6/--test等 flag创建DapServer并挂在 stdin/stdout 上。适配器实现pkg/dap_adapters/lib/src/adapters/dart.dart——Dart CLI 与 Dart Test 两个适配器的核心负责 launch/attach 参数解析、自定义请求分发、事件发送、变量求值等dart_cli_adapter.dart 与 dart_test_adapter.dart 分别为两类会话的具体封装。底层基础设施pkg/dap_adapters/lib/src/base_debug_adapter.dart适配器基类、server.dart协议服务器、protocol_converter.dartDAP↔VM Service 转换、isolate_manager.dartisolate/线程管理hotReload与_collectAllGarbage等请求依赖它。协议类型生成third_party/pkg/dap——DAP 协议的类型化封装包其tool/codegen.dart依据tool/external_dap_spec/debugAdapterProtocol.json生成请求/响应/事件类型供pkg/dap_adapters使用。七、验证与测试集成测试一览仓库在 pkg/dap_adapters/test/dap/integration/ 下提供了完整的端到端集成测试覆盖本文所述功能的真实行为args_test.dart——launch/attach 参数解析debug_breakpoints_test.dart、debug_stack_test.dart——断点与调用栈debug_eval_test.dart、debug_variables_test.dart——表达式求值与变量视图含格式说明符相关行为debug_logging_test.dart——sendLogsToClient/dart.log行为debug_services_test.dart——服务注册/注销事件与callServicedebug_attach_test.dart——attach 会话vmServiceUri/vmServiceInfoFiledart_test_test.dart——--test适配器与dart.testNotificationno_debug_test.dart——noDebug模式debug_test.dart、protocol_test.dart——会话生命周期与协议交互。这些测试同时扮演“可运行的示例”角色test_server.dart与test_client.dart提供了最小 DAP 服务端/客户端骨架读者可据此搭建自己的调试会话做实验。八、使用注意事项小结不要在终端里直接运行dart debug_adapter期待输出——它专为 DAP 客户端编辑器设计客户端先说话进程会静默等待调试测试请使用dart debug_adapter --test并消费dart.testNotification事件获取package:test的结构化结果追踪 VM Service 内部流量时开启sendLogsToClient并监听dart.log但仅在排障时使用attach 场景下vmServiceInfoFile与vmServiceUri必须二选一若需要非标准工具链通过customToolcustomToolReplacesArgs组合替换dart启动命令并保证兼容性对变量显示格式有特殊需求时善用,nq/,h/,d格式说明符它们比format参数优先级更高且会向子变量传播。赞分享编程语言编译器语言运行时标准库开发工具【免费下载链接】sdkThe Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.项目地址https://gitcode.com/gh_mirrors/sdk1/sdk点击查看免费下载相关推荐Dart SDK 的 Debug Adapter Protocol 适配器package:dap_adapters架构剖析与调试实战Dart SDK 的 Debug Adapter Protocol 适配器package:dap_adapters架构剖析与调试实战 package:da编程语言编译器语言运行时标准库开发工具urql 调试指南Devtools、Debug Events 与自定义调试事件urql 调试指南Devtools、Debug Events 与自定义调试事件 urql 为使用者和自研 Exchange 的开发者提供了完整的调试工具链内前端dio 5.x 完全指南Dart/Flutter 全平台 HTTP 网络请求库的全局配置、拦截器、FormData 与自定义适配器实战dio 5.x 完全指南Dart/Flutter 全平台 HTTP 网络请求库的全局配置、拦截器、FormData 与自定义适配器实战 dio 是 Dart网络后端WebSocket上一篇gh_mirrors/ui2/ui错误处理优雅处理运行时异常下一篇CacheWebView进阶配置详解从基础设置到高级定制完全手册创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表