AgentSkillsCN

systematic-debugging

四阶段调试方法论和根本原因分析。在调查bug、修复测试失败或排查意外行为时使用。强调在根本原因分析之前不要进行修复。

中文原作
SKILL.md
--- frontmatter
name: systematic-debugging
description: 四阶段调试方法论和根本原因分析。在调查bug、修复测试失败或排查意外行为时使用。强调在根本原因分析之前不要进行修复。

系统化调试

核心原则

在进行任何修复前,首先进行根本原因调查。

永远不要应用只是掩盖问题的症状补丁。在尝试修复之前,先了解为什么会失败。

四阶段框架

第1阶段:根本原因调查

在接触任何代码之前:

  1. 彻底阅读错误消息 - 每个词都很重要
  2. 一致地重现问题 - 如果无法重现,就无法验证修复
  3. 检查最近的更改 - 在此开始失败之前改变了什么?
  4. 收集诊断证据 - 日志、堆栈跟踪、状态转储
  5. 追踪数据流 - 遵循调用链以找到坏值的来源

根本原因追踪技术:

code
1. 观察症状 - 错误在哪里显示?
2. 找到直接原因 - 哪个代码直接产生错误?
3. 询问"谁调用了这个?" - 向上映射调用链
4. 继续向上追踪 - 在堆栈中向后遵循无效数据
5. 找到原始触发器 - 问题实际上在哪里开始?

关键原则: 永远不要仅在错误出现的地方修复问题——总是追踪到原始触发器。

第2阶段:模式分析

  1. 定位工作示例 - 找到类似的代码可以正确工作
  2. 完全比较实现 - 不只是浏览
  3. 识别差异 - 工作代码和破坏代码之间有什么不同?
  4. 了解依赖关系 - 这个代码依赖什么?

第3阶段:假设和测试

应用科学方法:

  1. 表述一个清晰的假设 - "错误发生是因为X"
  2. 设计最小测试 - 一次改变一个变量
  3. 预测结果 - 如果假设正确会发生什么?
  4. 运行测试 - 执行并观察
  5. 验证结果 - 它的行为是否与预测一致?
  6. 迭代或继续 - 如果错误则改进假设,如果正确则实施

第4阶段:实施

  1. 创建失败的测试用例 - 捕获bug行为
  2. 实施单一修复 - 解决根本原因,而不是症状
  3. 验证测试通过 - 确认修复有效
  4. 运行完整测试套件 - 确保没有回归
  5. 如果修复失败,停止 - 重新评估假设

关键规则: 如果连续三次或更多修复失败,停止。这表明存在需要讨论的架构问题,而不是更多补丁。

红旗 - 流程违反

如果你发现自己在想,立即停止:

  • "先快速修复,之后再调查"
  • "再尝试一次修复"(在多次失败之后)
  • "这应该行得通"(没有理解原因)
  • "让我试试..."(没有假设)
  • "在我的机器上可以工作"(没有调查差异)

更深层问题的警告信号

连续修复在不同区域揭示新问题表明存在架构问题:

  • 停止打补丁
  • 记录您发现的内容
  • 在继续前与团队讨论
  • 考虑设计是否需要重新思考

常见调试场景

测试失败

code
1. 阅读完整的错误消息和堆栈跟踪
2. 识别哪个断言失败和原因
3. 检查测试设置 - 测试环境正确吗?
4. 检查测试数据 - 模拟/fixture正确吗?
5. 追踪到意外值的来源

运行时错误

code
1. 捕获完整的堆栈跟踪
2. 识别抛出的行
3. 检查什么值是undefined/null
4. 向后追踪以找到坏值的来源
5. 在源头添加验证

"它之前能工作"

code
1. 使用git bisect找到破坏提交
2. 将更改与先前的工作版本进行比较
3. 识别什么假设改变了
4. 在假设违反的来源处修复

间歇性失败

code
1. 查找竞态条件
2. 检查共享可变状态
3. 检查异步操作顺序
4. 查找时序依赖
5. 添加确定性等待或正确的同步

调试检查清单

在声称bug已修复前:

  • 根本原因已识别并记录
  • 假设已形成并测试
  • 修复解决根本原因,而不是症状
  • 创建了重现bug的失败测试
  • 现在测试通过修复
  • 完整测试套件通过
  • 未使用"快速修复"合理化
  • 修复是最小化和集中的

成功指标

系统化调试实现约95%的首次修复率,而临时方法约40%。

您做对的迹象:

  • 修复不会产生新bug
  • 您可以解释为什么会发生bug
  • 类似的bug不会再次出现
  • 修复后代码更好,而不仅仅是"可以工作"

与其他技能的集成

  • testing-patterns: 在修复前创建重现bug的测试