关于 debug-ops
debug-ops 是面向开发者的系统化调试方法 skill,从复现问题到预防回归提供六步流程,并整理多种语言的调试工具和常见故障场景。
主要功能
- 01从复现到预防的六步调试流程
- 02缩小故障范围与定位根因
- 03多语言调试器参考
- 04日志与请求追踪方法
- 05常见故障场景指南
适用场景
- 01稳定复现并定位软件缺陷
- 02排查性能退化或并发问题
- 03验证修复并添加回归测试
- 04追踪跨服务请求与日志
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ 0xdarkmatter/ claude-mods --skill debug-ops安装后在 Claude Code 中输入/debug-ops确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/.gitkeepreferences/common-scenarios.mdsystematic-methods.mdtool-specific.mdscripts/.gitkeep详细介绍
调试操作
系统化的调试方法,涵盖特定语言的工具和常见场景操作指南。
Bug 分类决策树
Bug Report / Symptom
│
├─ Crash
│ ├─ Segfault / Access Violation
│ │ └─ Check: null pointer, buffer overflow, use-after-free, stack overflow
│ ├─ Panic / Fatal Error
│ │ └─ Check: assertion failure, unrecoverable state, out-of-memory
│ └─ Unhandled Exception
│ └─ Check: missing error handler, unexpected input type, network failure
│
├─ Hang
│ ├─ Deadlock
│ │ └─ Check: lock ordering, mutex contention, channel blocking
│ ├─ Infinite Loop
│ │ └─ Check: loop termination condition, counter overflow, recursive call
│ └─ Blocked I/O
│ └─ Check: network timeout, DNS resolution, disk full, file lock
│
├─ Wrong Output
│ ├─ Logic Error
│ │ └─ Check: operator precedence, boundary conditions, boolean logic
│ ├─ Data Corruption
│ │ └─ Check: concurrent mutation, encoding mismatch, truncation
│ └─ Off-by-One
│ └─ Check: loop bounds, array indexing, fence-post errors
│
├─ Performance
│ ├─ Slow Queries
│ │ └─ Check: missing index, N+1 queries, full table scan, lock wait
│ ├─ Memory Bloat
│ │ └─ Check: cache without eviction, leaked references, large allocations
│ └─ CPU Spikes
│ └─ Check: hot loops, regex backtracking, excessive GC, busy-wait
│
└─ Intermittent
├─ Race Condition
│ └─ Check: shared mutable state, read-modify-write, check-then-act
├─ Timing-Dependent
│ └─ Check: timeout values, clock skew, event ordering assumptions
└─ Environment-Specific
└─ Check: OS differences, locale, timezone, file system case sensitivity
系统化调试工作流
从症状到预防的六步流程:
第 1 步:复现
确认 Bug 存在,并创建可靠的复现步骤。无法复现的 Bug,就无法有把握地修复。记录确切的输入、环境和操作顺序。
第 2 步:隔离
将故障范围缩小到尽可能小的范围。使用二分法(git bisect、注释掉一半代码)、桩、功能标志和环境隔离,排除无关代码的影响。
第 3 步:识别
找出根本原因,而不仅仅是直接诱因。使用 5 Whys 技术、跟踪执行过程并检查关键节点的状态。区分症状与潜在缺陷。
第 4 步:修复
应用能解决根本原因的最小正确改动。避免地毯式调试(一次修改多项内容)。要理解修复为何有效,而不只是知道它有效。
第 5 步:验证
确认修复解决了原始问题,且没有引入回归。重新运行原始复现用例。运行完整测试套件。测试与修复相关的边缘情况。
第 6 步:预防
添加回归测试。酌情更新文档或操作手册。考虑其他地方是否也可能存在同类 Bug。与团队分享发现。
复现检查清单
[ ] Minimal reproduction steps documented (numbered, unambiguous)
[ ] Environment captured (OS, runtime version, dependencies, config)
[ ] Exact inputs recorded (request payload, CLI args, file contents)
[ ] Timing sensitivity assessed (does it fail only under load? after delay?)
[ ] Single-threaded reproduction attempted (eliminates concurrency noise)
[ ] Reproduction automated as script or test case
[ ] Confirmed reproduction is deterministic (fails N/N attempts)
[ ] Identified whether reproduction requires specific data/state
隔离技术速查表
| 技术 | 方法 | 最适用场景 |
|---|---|---|
| 二分法(git) | git bisect start BAD GOOD,然后运行 git bisect run ./test.sh | 找出引入 Bug 的提交 |
| 二分法(代码) | 注释掉一半代码,测试并重复操作 | 在不熟悉的代码中缩小故障位置 |
| 桩/模拟对象 | 将依赖项替换为已知可靠的伪实现 | 隔离外部服务的影响 |
| 功能标志 | 逐一关闭功能 | 找出导致问题的功能 |
| 环境隔离 | Docker 容器、新建 VM、全新安装 | 排除环境污染 |
| 网络拦截 | mitmproxy、Charles Proxy、模拟服务端 | 隔离客户端与服务端问题 |
| 输入缩减 | 移除输入字段/数据,直到 Bug 消失 | 找出最小触发条件 |
| 依赖项固定 | 锁定所有依赖项,每次只更新一个 | 找出导致故障的依赖项更新 |
根本原因分析模板
5 Whys 示例
Problem: API returns 500 error on user login
1. Why? → The database query throws a timeout exception
2. Why? → The users table scan takes >30 seconds
3. Why? → There is no index on the email column
4. Why? → The migration that adds the index was never run in production
5. Why? → The deployment script skips migrations when the --fast flag is used
Root cause: Deployment script's --fast flag bypasses migrations
Fix: Remove --fast flag behavior that skips migrations, add migration check to health endpoint
Prevention: CI check that verifies all migrations are applied after deployment
故障树基础
[System Failure]
/ \
[Hardware] [Software]
/ \ / \
[Disk] [Memory] [Config] [Code Bug]
| |
[Missing [Race in
env var] worker pool]
从顶部(观察到的故障)向下追溯到叶节点(根本原因)。每个分支都是 AND/OR 门——AND 表示所有子项都必须成立,OR 表示任一子项成立即可。
特定语言调试速查表
| 语言 | 工具 | 启动命令 | 主要命令 |
|---|---|---|---|
| Node.js | Chrome DevTools | node --inspect-brk app.js | 打开 chrome://inspect,在 Sources 中设置断点 |
| Node.js | ndb | npx ndb app.js | 增强版 DevTools,支持黑盒化 |
| Python | pdb | python -m pdb script.py | n 单步执行,s 步入,c 继续,p expr 打印,bt 回溯 |
| Python | debugpy | python -m debugpy --listen 5678 --wait-for-client script.py | VS Code“Attach”启动配置 |
| Python | breakpoint() | 在代码中插入 breakpoint() | 在该行进入 pdb(Python 3.7+) |
| Go | Delve | dlv debug ./cmd/server | b main.go:42 设置断点,c 继续,n 单步执行,p var 打印 |
| Go | Delve (test) | dlv test ./pkg/... | 直接调试测试函数 |
| Go | Delve (attach) | dlv attach PID | 调试正在运行的进程 |
| Rust | rust-gdb | rust-gdb target/debug/myapp | b main,r,n,p variable,bt |
| Rust | rust-lldb | rust-lldb target/debug/myapp | b s main,r,n,p variable,bt |
| Rust | CodeLLDB | VS Code 扩展 | GUI 断点、变量检查 |
| 浏览器 | DevTools | F12 或 Ctrl+Shift+I | Elements、Console、Network、Sources、Performance、Memory |
快速调试代码片段
// Node.js: drop into debugger at this point
debugger;
// Node.js: conditional breakpoint
if (user.id === 'problem-user') debugger;
# Python: drop into debugger at this point
breakpoint()
# Python: conditional breakpoint
if user_id == 'problem-user':
breakpoint()
// Go: print goroutine stacks (send SIGQUIT or SIGABRT)
// kill -QUIT <pid>
// Or in code:
import "runtime/debug"
debug.PrintStack()
// Rust: enable full backtraces
// RUST_BACKTRACE=1 cargo run
// RUST_BACKTRACE=full cargo run
基于日志的调试模式
策略性日志记录
在决策点记录日志,而不只是记录错误路径:
[ENTRY] function_name(args_summary) -- entering the function
[STATE] key_variable=value -- state at critical decision point
[BRANCH] taking path X because Y -- which branch and why
[EXIT] function_name -> result_summary -- leaving the function
[ERROR] operation failed: detail -- error with context
关联 ID
跨服务跟踪单个请求:
# Generate at entry point, propagate through all calls
X-Request-ID: 550e8400-e29b-41d4-a716-446655440000
# Search across all service logs
rg "550e8400-e29b-41d4-a716-446655440000" /var/log/services/
时间线重建
# Merge and sort logs from multiple sources by timestamp
sort -t' ' -k1,2 service-a.log service-b.log service-c.log > timeline.log
# Find gaps in activity (potential hang/block)
awk '{print $1, $2}' timeline.log | uniq -c | sort -rn | head -20
结构化日志查询
# jq queries on JSON logs
# Find all errors for a specific user
jq 'select(.level == "error" and .user_id == "u123")' app.log
# Get timing distribution for slow requests
jq 'select(.duration_ms > 1000) | .duration_ms' app.log | sort -n
# Count errors by type
jq -r 'select(.level == "error") | .error_type' app.log | sort | uniq -c | sort -rn
常见陷阱
| 陷阱 | 影响 | 修复方法 |
|---|---|---|
| 修复表象,而非根本原因 | Bug 会以不同形式再次出现 | 使用 5 Whys 深入排查 |
| 缺乏安全保障便在生产环境调试 | 有数据丢失或服务中断时间延长的风险 | 使用只读查询、功能标志和金丝雀部署 |
| 海森堡 Bug(观察时消失) | 添加日志或断点会改变时序 | 使用非侵入式工具:strace、采样分析器、rr |
| 假设偏见(“不可能是 X”) | 因为相信某个因素而跳过真正原因 | 明确验证每项假设,即使是“显而易见”的假设 |
| 缺少复现案例 | 无法验证修复,也无法防止回归 | 预先投入时间,确保可靠复现 |
| 过度依赖打印或日志调试 | 迭代缓慢、污染代码,还会漏掉并发 Bug | 使用合适的调试器、分析器或跟踪工具 |
| 未检查近期变更 | 答案往往就在最近几次提交中 | git log --oneline -20、git diff HEAD~5 |
| 忽略警告消息 | 警告往往预示着后续错误 | 调试时将警告视为错误 |
| 调试了错误的版本或分支 | 浪费时间排查已修复的问题或不同代码 | 验证 git branch、git log -1 和运行时版本 |
| 未阅读完整堆栈跟踪 | 根本原因往往在中间,而非顶部 | 从下往上阅读:先在跟踪信息中找到自己的代码 |
| 一次更改多项内容 | 无法判断是哪项更改修复或引发了问题 | 每个测试周期只做一项更改 |
| 未记录“之前”的状态 | 无法与正常工作时的基线进行对比 | 调试前快照保存配置、依赖项和数据 |
参考文件
| 文件 | 内容 | 行数 |
|---|---|---|
references/systematic-methods.md | 科学方法、二分查找、差分调试、差异调试、时光倒流调试、团队调试 | ~600 |
references/tool-specific.md | 浏览器 DevTools、Node.js、Python、Go、Rust、数据库、网络和 Docker 调试工具 | ~650 |
references/common-scenarios.md | 内存泄漏、死锁、竞态条件、性能回归、API 调试、部署问题 | ~550 |
另请参阅
- testing-ops —— 编写测试,防止 Bug 再次发生
- security-ops —— 安全专项调试(身份验证失败、注入、CSRF)
- monitoring-ops —— 生产环境可观测性、告警和仪表盘
- code-stats —— 衡量代码复杂度并找出容易出错的部分
- docker-ops —— 容器调试(退出代码、distroless、构建);kubernetes-ops —— Pod 调试
- git-ops —— Git 二分查找工作流和历史调查
评论
支持 Markdown