mcpField
D
debugging-code

debugging-code

github.com/jetbrains其他38539 次安装1 周前更新
代码仓库

关于 debugging-code

Code Debugging 是面向 Rider 中解决方案的调试器优先运行时根因分析技能,涵盖 .NET 和游戏开发项目。当源码和日志不足以确定运行时值或控制流时,可用于收集证据。

主要功能

  1. 01调查运行时状态和控制流
  2. 02设置断点并检查变量值
  3. 03复现测试和应用场景
  4. 04复用调试会话并管理断点
  5. 05要求收集确凿证据后再修复运行时问题

适用场景

  1. 01确定运行中的程序进入了哪个分支
  2. 02检查故障调用路径中的变量值
  3. 03确认执行是否到达指定位置
  4. 04在 Rider 中调试测试失败

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jetbrains/skills --skill debugging-code

安装后在 Claude Code 中输入/debugging-code确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

reference/
tools.md
reference/tools/
execute_run_configuration.md
get_run_configurations.md
xdebug_control_session.md
xdebug_evaluate_expression.md
xdebug_get_debugger_status.md
xdebug_get_frame_values.md
xdebug_get_stack.md
xdebug_get_threads.md
xdebug_get_value_by_path.md
xdebug_list_breakpoints.md
xdebug_remove_breakpoint.md
xdebug_run_to_line.md
xdebug_set_breakpoint.md
xdebug_set_variable.md
xdebug_start_debugger_session.md

详细介绍

代码调试

以调试器为先,对在 Rider 中打开的解决方案进行运行时根因分析,涵盖 C#、C++、F#、VB、Unreal Engine 及其他 GameDev 项目。

通过 execute_tool(command="<tool> --arg value ...") 调用每个工具。不要直接调用底层句柄。仅在即将调用某个特定工具时阅读 reference/tools.md;不要预先加载整个工具树。

目标

当静态阅读代码不足以回答具体的运行时问题,或需要确认静态分析的思路或结果时,使用调试器证据作答——包括确认执行是否通过断点或跟踪点到达 Agent 选定的代码位置。

何时使用此技能

符合以下任一条件时使用此技能:

  • 需要运行时状态或控制流证据(实际值、执行的分支、调用顺序、线程上下文,或执行是否到达选定位置),且无法从源代码或日志中有把握地推断;
  • 否则需要阅读许多文件或手动追踪很长的调用链才能找到相关路径;
  • 用户明确要求使用调试器(断点、单步执行、检查值、调试器会话)。

如果用户手动启用或提及此技能,应将其视为明确要求在所需工具可用时启动并使用调试器;不要将其简化为概念性讨论。

符合以下任一条件时跳过调试器(改用静态分析或日志检查):

  • 源代码或构建输出中可见编译时/语法错误;
  • 无需运行代码即可看出原因(拼写错误、重载错误、明显的空接收器、参数数量错误);
  • 单文件逻辑错误,且所有状态在源代码层面都清晰可见;
  • 失败测试消息或日志已指出出错行和具体值。

消歧

如果代码库领域中包含与调试相关的概念,应明确判断用户是在谈论自己的代码,还是确实要求你启动调试器。不要默认将名为 debug/Debugger 的标识符、功能、标志或日志类别——包括 System.Diagnostics.Debug 或 Debug 构建配置——视为调试器请求。

激活门槛(工具可用性)

仅当当前会话中有可用的调试器 MCP 工具时,才使用此技能。最低必需工具集:

  • xdebug_set_breakpoint
  • xdebug_start_debugger_session
  • xdebug_control_session
  • xdebug_get_stack
  • 至少一个值工具:xdebug_get_frame_values、xdebug_get_value_by_path 或 xdebug_evaluate_expression
  • get_run_configurations

如果无法使用这套最低必需工具:明确说明阻碍,不要强行执行调试器工作流,并改用最佳替代方案。所有工具的说明见 reference/tools.md。

调试前的初步排查

先进行最少量的静态排查(错误文本、堆栈跟踪、附近的源代码)。出现以下任一情况时开始调试器工作:静态分析后仍有多个合理的运行时假设;需要具体的运行时值或精确控制流才能判断;单步跟踪代码比阅读大量跨文件调用路径更省力;或用户明确要求执行调试器操作。

开始新一轮调试前,先评估能否复用当前相关会话。尽早设置第一个断点,并在更改运行时行为前收集具体证据。

强制运行时证据

对于运行时行为问题,在修改代码之前(当调试器证据可用时),至少收集以下内容:

  • 暂停会话中的暂停位置(文件/行号);
  • 通过 xdebug_get_stack 获取顶部调用路径;
  • 当问题涉及可达性时,提供执行是否命中明确选定的断点或跟踪点的证据;
  • 通过 xdebug_get_frame_values、xdebug_get_value_by_path 或 xdebug_evaluate_expression 获取至少一个具体运行时值。

除非已明确说明存在阻碍,否则在收集这些证据之前,不要断言运行时结论。

复现模式选择

  1. AUTO:Agent 可以直接运行并重新运行场景(运行配置、测试、可执行文件、端点)。使用 xdebug_start_debugger_session 在调试模式下启动;如果只需获取输出或退出代码,则使用 execute_run_configuration 进行非调试运行。
  2. ASSISTED:复现需要用户独有的操作(UI 流程、身份验证、外部依赖、硬件交互)。
  3. HYBRID:先尝试一到两次 AUTO,如果未复现故障,再切换到 ASSISTED。

如果候选目标是测试,默认使用 AUTO。准备好断点之前,绝不要要求用户复现。

测试任务执行

  • 要调试测试,请在测试定义处([Fact] / [Test] / [TestMethod] 方法或用例)传入 --filePath + --line;IDE 会识别测试框架(xUnit、NUnit、MSTest)。对于现有测试运行配置,请使用 --configurationName。若要在不调试的情况下运行测试(例如,在设置断点前确认测试会失败),请使用相同的目标参数调用 execute_run_configuration。
  • 触发后,使用 execute_tool(command="xdebug_get_debugger_status") 检查结果状态,并在相关会话中继续操作。
  • 除非没有可用的测试运行方式来复现问题,或复现需要用户独有的设置,否则不要要求用户手动重新运行。

参数规范

  • 可选参数要么省略/设为 null,要么设为实际值;省略时就直接省略。
  • 不要使用 ""、"/"、"__omit__"、 "." 或虚构路径等占位字符串来表示省略的可选参数。
  • 将 ID 和路径视为不透明的运行时数据:从工具输出中复制,不要自行构造。

会话绑定

  • 准备断点或启动之前,调用 execute_tool(command="xdebug_get_debugger_status")。
  • 如果存在相关的活动会话,请在该会话中继续,不要另开会话。
  • 获取准确的 sessionId,并在所有会话范围内的调用中重复使用。如果会话停止、超时或消失,请先通过 xdebug_get_debugger_status 刷新会话信息,再继续使用。
  • 暂停位置发生变化后,不要重复使用过时的 frameIndex 或 path;请从最新的 xdebug_get_stack 重新读取。

运行配置解析

  • 从 get_run_configurations 获取 configurationName;其 supportsDynamicLaunchOverrides 决定是否支持 --programArguments / --workingDirectory / --envs(参见 reference/tools/get_run_configurations.md)。
  • 不要自行构造 dotnet 调用,也不要在配置不支持覆盖参数时通过 --programArguments 传入测试筛选器;应遵循运行配置,仅在能实质性提升可复现性或可观测性时使用启动覆盖参数。

断点归属与规范

  • 始终先运行 execute_tool(command="xdebug_list_breakpoints"),并以返回的 owner(user / agent)为准。
  • 修改任何内容前,先建立基线快照(breakpointId -> enabled)。
  • 通过 execute_tool(command="xdebug_set_breakpoint --breakpointId <id> --enabled false") 临时禁用当前路径不需要的 owner=user 断点;仅在调试器周期结束时恢复一次。
  • 避免在迭代期间大范围变更断点。xdebug_remove_breakpoint 默认使用 --owner agent;如需全局清理,则依次调用两次:--owner agent,然后 --owner user。

断点定位模式

xdebug_set_breakpoint 有两种互斥的定位模式(位置与 breakpointId)——一次调用中切勿混用;在 breakpointId 模式下,传入完整的目标状态,因为提供的字段会成为最终结果。每次调用后,都要确认返回的 lineText 与目标行相符。模式和完整约定见:reference/tools/xdebug_set_breakpoint.md。

库代码与反编译源代码调试

可以在库代码和框架代码中设置断点。read_file 可读取外部源文件,以及程序集的捆绑反编译输出(如果有,还包括通过 SourceLink / PDB 解析出的原始文件)。获取路径的方法:

  • 堆栈帧:xdebug_get_stack 会返回 file 路径,包括外部程序集中的路径——请原样使用返回的路径;
  • 符号搜索:search_symbol(q="TypeName", include_external=true) 会返回外部 / 库符号路径。

在外部代码中设置断点前,始终使用 read_file(file_path=<path>) 查找准确行号;切勿猜测行号。不要通过插入 Console.WriteLine 来编辑源代码;请改用跟踪点。

选择入口点和第一个断点

首次运行前,明确选择范围最小且可复现的入口点(单个测试、聚焦的运行配置、端点处理程序、命令处理程序),并将第一个断点设在最早能观察到不确定性的可执行行(分支决策、映射边界、状态转换、动态分派、异常构造)。如不确定,最多设置 2 个粗略断点——一个在入口边界,一个在疑似故障边界——运行一次后再缩小范围。

核心工作流

复制此检查清单,并在推进过程中逐项勾选:

Debugger Run Progress:
- [ ] Scope the failure: exact error text, expected vs actual, 2-5 candidate anchors in the runtime path
- [ ] `xdebug_get_debugger_status` → reuse an active relevant session OR plan a new one
- [ ] Pick reproduction mode (AUTO / ASSISTED / HYBRID)
- [ ] Snapshot the breakpoint baseline; disable irrelevant user breakpoints
- [ ] Set initial breakpoints; verify `lineText` for each
- [ ] `xdebug_start_debugger_session ...` OR continue inside the existing session
- [ ] After a fresh start or RESUME: `xdebug_control_session --action WAIT_FOR_PAUSE`
- [ ] At each pause: `xdebug_get_stack` + values / eval (`xdebug_get_frame_values`, `xdebug_get_value_by_path`, `xdebug_evaluate_expression`)
- [ ] Decide next movement (`STEP_OVER` / `STEP_INTO` when evidence is nearby, OR a new breakpoint then `RESUME`)
- [ ] For tracepoints: `xdebug_control_session --action DRAIN_EVENTS`
- [ ] Stop on the first proven incorrect state transition or a stated blocker
- [ ] Wrap-up (cleanup + report)

每一步都要遵循以下规范:

  • 没有明确指出预期的下一次暂停位置时,绝不执行 RESUME;每次执行 RESUME 后,始终执行 WAIT_FOR_PAUSE。
  • 等待超时:执行 PAUSE,重新检查已启用的断点和预期路径;连续超时 2 次后,停止重试该等待,并扩大断点覆盖范围。
  • 没有具体运行时值作为依据时,绝不断言根本原因;在原因得到证实前,不要修改运行时行为。
  • 不要止步于下游症状——沿调用帧向上追溯 / 回退到产生该状态的位置;如果需要的位置已经经过,则使用更早的断点重新启动。
  • 当某个帧指向外部 / 反编译代码时,使用 read_file 读取该代码,并在那里设置更深层的断点;不要跳过。

事件和跟踪点

  • breakpointErrorsTail / tracepointOutputsTail(xdebug_control_session;参见其参考文档)仅由基于 JVM 的调试器填充。Rider 的调试器并非基于 JVM,因此不要依赖这些字段:先在暂停的帧中使用 xdebug_evaluate_expression 对 --condition 进行预检,并从程序的运行 / 控制台输出中确认跟踪点日志。
  • 如需在不暂停程序的情况下记录跟踪点日志,请使用 execute_tool(command="xdebug_set_breakpoint --filePath <path> --line <n> --isLogMessage true --suspendPolicy NONE")(或 --isLogStack true)。

表达式规范

xdebug_evaluate_expression 和 xdebug_set_variable 接受当前帧所用语言(C#、C++、F# 或 VB)的原始表达式——确切输入规则请参阅相应的参考文件。除此约定外:

  • 对于 --condition 和 --expression 中的全局/静态符号,优先使用完全限定名称,以避免调试器表达式上下文缺少导入而导致 Unresolved reference。
  • 路由器使用 ParametersListUtil 解析外层的 execute_tool(command=...) 行。表达式包含双引号时,用单引号包裹外层命令字符串;包含单引号时,用双引号包裹外层字符串;避免混用两种引号而不进行转义。
  • 如果程序已暂停,先使用 xdebug_evaluate_expression 对有风险的 --condition 表达式进行预检,再依赖该表达式。

向上检查调用帧并回退

程序在某个帧中停止时,检查更上层的帧,以重建数据来源:确定是谁传入了当前值,以及状态最早在哪个调用帧中变得不正确。如果所需位置已经经过:使用更早的断点(AUTO)重新运行,或设置更早的断点并让用户再次复现(ASSISTED)。如果已经错过所需证据,不要从过晚的位置继续。如果某个帧指向外部代码/反编译代码,使用 read_file 阅读,并在需要时在那里设置断点,以便更深入地追踪数据来源。

证据检查清单

得出结论前,记录:确切的失败消息/正文;异常类型和/或状态码;状态首次偏离预期的位置;具体的错误键/值(以及相关数量);错误数据的来源/出处;以及流水线为何会放过这些数据。

收尾

调试完成后:

  1. 清理:执行 execute_tool(command="xdebug_remove_breakpoint --owner agent"),将已禁用的用户断点恢复到初始状态;如果不再需要该会话,则执行 execute_tool(command="xdebug_control_session --action STOP")。
  2. 报告:
    • 用一句话说明根因;
    • 用 3-6 个要点说明因果链;
    • 提供包含确切观测值的运行时证据;
    • 提供代码引用(绝对路径加行号);
    • 如果未进行调试而采用了替代方案,说明确切原因以及仍缺少哪些证据。
  3. 根据用户目标决定下一步:如果用户只要求诊断,则以报告和建议的后续步骤结束;如果任务意味着需要修改代码,则根据已证实的根因实施修复。

工具参考

有关 13 个 xdebug_* MCP 工具以及 get_run_configurations/execute_run_configuration 的签名和逐参数说明,请参阅 reference/tools.md。

评论

支持 Markdown