mcpField
D
debugging-methodology

debugging-methodology

github.com/laurigates开发5981 次安装1 天前更新
代码仓库

关于 debugging-methodology

debugging-methodology 是一套系统化定位和修复软件缺陷的技能,适用于调查运行时错误、资源耗尽和性能回归。它强调复现问题、验证故障点证据,并以测量而非既有判断确定根因。

主要功能

  1. 01按步骤复现、定位并验证缺陷
  2. 02记录假设并逐步缩小范围
  3. 03在故障点测量实际资源状态
  4. 04识别默认标识符与哨兵值
  5. 05提供系统级调试工具参考

适用场景

  1. 01调查内存泄漏或竞态条件
  2. 02区分资源耗尽、碎片化与分配器问题
  3. 03核实错误信息中实体是否真实存在

安装

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

$npx skills add https://github.com/laurigates/claude-plugins --skill debugging-methodology

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

附带文件REFERENCE.md

详细介绍

调试方法

系统性地查找并修复 Bug。

何时使用此技能

在以下情况使用此技能……在以下情况改用其他工具……
诊断正在发生的 Bug、内存泄漏、竞态或性能回退Bug 被吞掉的错误隐藏 → code-hidden-failures --track errors
分析复现、隔离和根因Bug 被空结果时的静默成功隐藏 → code-hidden-failures --track degradation
为系统级调查选择 strace/eBPF/perf根因已知后检查周边代码质量 → code-review
记录假设并通过二分法定位故障修复后重构有 Bug 的模块 → code-refactor

核心原则

  1. 奥卡姆剃刀 - 从最简单的解释开始
  2. 二分查找 - 系统性地隔离问题区域
  3. 保留证据 - 修改前先了解状态
  4. 记录假设 - 跟踪尝试过但无效的方法

调试工作流

1. Understand → What is expected vs actual behavior?
2. Reproduce → Can you trigger the bug reliably?
3. Locate → Where in the code does it happen?
4. Diagnose → Why does it happen? (root cause)
5. Fix → Minimal change to resolve
6. Verify → Confirm fix works, no regressions

常见 Bug 模式

症状可能原因首先检查
TypeError/null缺少空值检查输入验证
差一错误循环边界、数组索引边界条件
竞态条件异步时序Await/Promise 处理
导入错误路径/模块解析文件路径、导出
类型不匹配传入了错误类型函数签名
间歇性测试失败时序、共享状态测试隔离

在故障点诊断 — 哨兵值与资源读取

内容摘自 ~/.claude/rules/diagnose-at-the-failure-point.md,该文件的存根保留了两行门槛条件。工具或库报告故障时,两个表面特征经常会误导诊断:错误中点名的实体,以及你一开始就接受的问题表述。在故障发生的确切位置,将两者与实际情况核对,成本都很低。

1. 错误中点名的实体可能是哨兵值/默认值,而不是真实对象

错误中点名的对象具有较小 / 零 / 默认标识符时—— Memory page 0 doesn't exist、id 0、空字符串名称、index -1、 0.0.0.0、空 UUID——通常报告的是未初始化或哨兵默认值, 而非行为异常的真实实体。在推测该实体之前,先确认其标识符来自一次真正成功的操作(已完成的分配 / 查找 / 注册),而非回退路径。

典型案例(2026-07,cubecl CUDA):couldn't find resource for that handle: Memory page 0 doesn't exist 曾被一份交接说明、上游跟踪记录以及我 多次解读为内存池的回收竞态导致“page 0”损坏。实际情况是 MemoryLocation::uninit() = {pool:0,page:0}: 一次分配失败使其句柄未绑定,保留为零默认值;之后每次 查找未绑定句柄时都会报告“page 0”。没有发生任何内存池回收。 证据很明确:不同“缺失”句柄的数量与分配失败次数完全相等。

关键线索通常是与上游某个数值相匹配的计数或比例 (缺失实体数量 == 失败次数)——在认定该实体真实存在之前,先查找这一线索。

2. 对于任何耗尽症状,请读取故障发生时的实际资源状态

OOM / out of memory / can't allocate / ENOSPC / too many open files / pool exhausted 都是对应三种不同修复方式的症状——真正耗尽、碎片化或管理器/分配器错误。只需在故障发生时进行一次测量,就能区分它们:

症状故障发生时读取只有在以下情况下才算真正耗尽
CUDA/GPU OOMcuMemGetInfo(空闲、总量)空闲量 ≪ 请求量
ENOSPC目标文件系统上的 df空闲量 ≈ 0
EMFILE / 文件过多文件描述符数量与 ulimit -n 对比数量 ≈ 限制
分配器/内存池“已满”内存池的 in_use、reserved 与设备总量in_use ≈ 设备总量

在发生故障的调用位置加上检测并打印这些信息;不要根据几秒前采样的结果推断(峰值可能出现在两次采样之间)。在同一个案例中,失败的 malloc 调用处的 cuMemGetInfo 显示25.2 GB 中有 0.58 GB 可用——这确实是内存耗尽,并非碎片化,也不是内存池错误。这一条读数就结束了对分配器的排查:工作集确实超出了显卡容量。其他所有理论(回收竞态、游标保护、回收前同步、分辨率“调节手段”)都已被测量结果而非争论推翻。

**故障发生时的证据 > 你收到的描述 > 看似合理的机制。**措辞笃定的问题报告、维护者给出的根因,以及错误信息本身的表述,都只是需要验证的输入,而非结论。当理论与测量结果不一致时,以测量结果为准——重新诊断,而不是给理论打补丁。错误信息用可疑的整圆数/零值/默认值指名某个实体、“资源耗尽”故障的修复方案取决于耗尽原因,或继承的交接信息、上游跟踪记录已断言根因时,都很容易踩这个坑。跳过这项成本低廉的读取,相当于放弃花五秒执行 cuMemGetInfo/df/计数,却要花多轮排查一个从未发生过的机制。相关内容:agent-patterns-plugin:probe-input-integrity(由你编造的 ID)、git-plugin:git-issue-scoping 和 git-plugin:git-upstream-fix-check(不要轻信继承而来的描述)、agent-patterns-plugin:tool-result-traps(格式正确、却悄然与现实不符的输出)。

调试问题

遇到阻碍时,请问自己:

  1. 最近有哪些变化可能导致这个问题?
  2. 这个问题在所有环境中都会发生,还是只在某一个环境中发生?
  3. Bug 出在我的代码中,还是某个依赖中?
  4. 我有哪些假设可能是错的?
  5. 我能否编写一个最小复现?

有效的调试实践

  • 有针对性地修改:提出假设,每次只改一处
  • 使用合适的调试器:尽可能使用断点逐步执行代码
  • 查找根因:追溯问题的源头,从源头修复
  • 先复现:尝试修复之前,先创建一个最小复现
  • 验证修复:确认修复解决了问题且测试通过

系统级工具(内存分析、性能分析、strace/eBPF 跟踪、网络调试)和特定语言的调试器命令,请参阅 REFERENCE.md。

评论

支持 Markdown