Systematic Debugging
遇到任何 bug、测试失败或异常行为时使用,在提出修复方案之前执行
Install
npx skills add jnMetaCode/superpowers-zh --skill systematic-debugging -g -a claude-code -y- Repository
- jnMetaCode/superpowers-zh8.4k
- Category
- Engineering
- Updated
- 9d ago
- License
- MIT
- Context cost
- Lightabout 1,116 tokens
- Runs scripts
- Yes, review before use
What it does
遇到任何 bug、测试失败或异常行为时使用,在提出修复方案之前执行
系统化调试
概述
核心原则: 在尝试修复之前,务必先找到根本原因。只修症状就是失败。
敷衍走流程等于违背调试的精神。
铁律
不做根因调查,不许提修复方案
如果你还没完成第一阶段,就不能提出修复方案。
何时使用
用于任何技术问题:
- 测试失败
- 生产环境 bug
- 异常行为
- 性能问题
- 构建失败
- 集成问题
尤其在以下情况必须使用:
- 时间紧迫(紧急情况最容易让人猜测式修复)
- 觉得"一个小修改"就能搞定
- 已经尝试了多种修复
- 上一次修复没有生效
- 你没有完全理解问题
以下情况也不要跳过:
- 问题看起来很简单(简单的 bug 也有根本原因)
- 你很赶时间(越急越容易返工)
- 领导要求立刻修好(系统化调试比反复尝试更快)
四个阶段
你必须完成每个阶段后才能进入下一个。
第一阶段:根因调查
在尝试任何修复之前:
-
仔细阅读错误信息
- 不要跳过错误或警告
- 它们往往直接包含解决方案
- 完整阅读堆栈跟踪
- 记下行号、文件路径、错误码
-
稳定复现
- 你能可靠地触发它吗?
- 具体的复现步骤是什么?
- 每次都能复现吗?
- 如果无法复现 → 收集更多数据,不要猜测
-
检查近期变更
- 什么变更可能导致了这个问题?
- git diff、最近的提交
- 新依赖、配置变更
- 环境差异
-
在多组件系统中收集证据
当系统有多个组件时(CI → 构建 → 签名,API → 服务 → 数据库):
在提出修复方案之前,先添加诊断埋点:
对每个组件边界: - 记录进入组件的数据 - 记录离开组件的数据 - 验证环境/配置的传递 - 检查每一层的状态 执行一次以收集证据,确定断裂点在哪里 然后分析证据,定位故障组件 然后针对该组件深入调查示例(多层系统):
# 第 1 层:工作流 echo "=== Secrets available in workflow: ===" echo "IDENTITY: $([ -n "${IDENTITY:-}" ] && echo SET || echo UNSET)" # 第 2 层:构建脚本 echo "=== Env vars in build script: ===" printenv IDENTITY >/dev/null 2>&1 && echo "IDENTITY in environment" || echo "IDENTITY not in environment" # 第 3 层:签名脚本 echo "=== Keychain state: ===" security list-keychains security find-identity -v # 第 4 层:实际签名 codesign --sign "$IDENTITY" --verbose=4 "$APP"由此可以看出: 哪一层出了问题(secrets → workflow ✓, workflow → build ✗)
-
跟踪数据流
当错误发生在调用栈深处时:
参见本目录下的
root-cause-tracing.md,了解完整的反向追踪技术。简要版本:
- 错误值从哪里产生的?
- 谁用错误值调用了这里?
- 持续向上追踪直到找到源头
- 在源头修复,而不是在症状处修复
第二阶段:模式分析
先找到模式,再修复:
-
找到可正常工作的示例
- 在同一代码库中找到类似的正常代码
- 有什么正常的代码与出问题的代码相似?
-
与参考实现对比
- 如果是实现某个模式,完整阅读参考实现
- 不要略读, , 逐行阅读
- 在应用之前彻底理解该模式
-
识别差异
- 正常代码和出问题的代码之间有什么不同?
- 列出每一个差异,无论多小
- 不要假设"那不可能有影响"
-
理解依赖关系
- 这个功能需要哪些其他组件?
- 需要哪些设置、配置、环境?
- 它有哪些隐含假设?
