debugging-strategies by wshobson/agents
npx skills add https://github.com/wshobson/agents --skill debugging-strategies通过成熟的策略、强大的工具和系统化的方法,将调试从令人沮丧的猜测转变为系统化的问题解决过程。
1. 观察:实际行为是什么? 2. 假设:可能是什么原因导致的? 3. 实验:测试你的假设 4. 分析:结果是否证明/证伪了你的理论? 5. 重复:直到找到根本原因为止
不要假设:
应该做:
大声解释你的代码和问题(对橡皮鸭、同事或自己)。通常能揭示问题所在。
## 复现检查清单
1. **你能复现它吗?**
- 总是?有时?随机?
- 需要特定条件吗?
- 其他人能复现吗?
2. **创建最小复现案例**
- 简化到最小的例子
- 移除无关代码
- 隔离问题
3. **记录步骤**
- 写下确切的步骤
- 记录环境详情
- 捕获错误信息
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
## 信息收集
1. **错误信息**
- 完整的堆栈跟踪
- 错误代码
- 控制台/日志输出
2. **环境**
- 操作系统版本
- 语言/运行时版本
- 依赖版本
- 环境变量
3. **近期变更**
- Git 历史
- 部署时间线
- 配置变更
4. **影响范围**
- 影响所有用户还是特定用户?
- 所有浏览器还是特定浏览器?
- 仅生产环境还是开发环境也有?
## 假设形成
基于收集的信息,提问:
1. **什么改变了?**
- 最近的代码变更
- 依赖更新
- 基础设施变更
2. **有什么不同?**
- 正常环境 vs 故障环境
- 正常用户 vs 故障用户
- 之前 vs 之后
3. **哪里可能出错?**
- 输入验证
- 业务逻辑
- 数据层
- 外部服务
## 测试策略
1. **二分查找法**
- 注释掉一半代码
- 缩小问题范围
- 重复直到找到问题
2. **添加日志**
- 策略性地使用 console.log/print
- 跟踪变量值
- 追踪执行流程
3. **隔离组件**
- 单独测试每个部分
- 模拟依赖
- 移除复杂性
4. **对比正常与故障**
- 对比配置
- 对比环境
- 对比数据
// Chrome DevTools 调试器
function processOrder(order: Order) {
debugger; // 执行在此处暂停
const total = calculateTotal(order);
console.log("Total:", total);
// 条件断点
if (order.items.length > 10) {
debugger; // 仅在条件为真时中断
}
return total;
}
// 控制台调试技巧
console.log("Value:", value); // 基础
console.table(arrayOfObjects); // 表格格式
console.time("operation");
/* code */ console.timeEnd("operation"); // 计时
console.trace(); // 堆栈跟踪
console.assert(value > 0, "Value must be positive"); // 断言
// 性能分析
performance.mark("start-operation");
// ... operation code
performance.mark("end-operation");
performance.measure("operation", "start-operation", "end-operation");
console.log(performance.getEntriesByType("measure"));
VS Code 调试器配置:
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug Program",
"program": "${workspaceFolder}/src/index.ts",
"preLaunchTask": "tsc: build - tsconfig.json",
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
"skipFiles": ["<node_internals>/**"]
},
{
"type": "node",
"request": "launch",
"name": "Debug Tests",
"program": "${workspaceFolder}/node_modules/jest/bin/jest",
"args": ["--runInBand", "--no-cache"],
"console": "integratedTerminal"
}
]
}
# 内置调试器 (pdb)
import pdb
def calculate_total(items):
total = 0
pdb.set_trace() # 调试器在此处启动
for item in items:
total += item.price * item.quantity
return total
# 断点 (Python 3.7+)
def process_order(order):
breakpoint() # 比 pdb.set_trace() 更方便
# ... code
# 事后调试
try:
risky_operation()
except Exception:
import pdb
pdb.post_mortem() # 在异常点调试
# IPython 调试 (ipdb)
from ipdb import set_trace
set_trace() # 比 pdb 更好的界面
# 用于调试的日志记录
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
def fetch_user(user_id):
logger.debug(f'Fetching user: {user_id}')
user = db.query(User).get(user_id)
logger.debug(f'Found user: {user}')
return user
# 性能分析
import cProfile
import pstats
cProfile.run('slow_function()', 'profile_stats')
stats = pstats.Stats('profile_stats')
stats.sort_stats('cumulative')
stats.print_stats(10) # 最慢的 10 个
// Delve 调试器
// Install: go install github.com/go-delve/delve/cmd/dlv@latest
// Run: dlv debug main.go
import (
"fmt"
"runtime"
"runtime/debug"
)
// 打印堆栈跟踪
func debugStack() {
debug.PrintStack()
}
// 带调试的恐慌恢复
func processRequest() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Panic:", r)
debug.PrintStack()
}
}()
// ... 可能引发恐慌的代码
}
// 内存分析
import _ "net/http/pprof"
// 访问 http://localhost:6060/debug/pprof/
// CPU 分析
import (
"os"
"runtime/pprof"
)
f, _ := os.Create("cpu.prof")
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
// ... 要分析的代码
# 使用 Git bisect 查找回归
git bisect start
git bisect bad # 当前提交是坏的
git bisect good v1.0.0 # v1.0.0 是好的
# Git 检出中间提交
# 测试它,然后:
git bisect good # 如果它工作正常
git bisect bad # 如果它坏了
# 继续直到找到 Bug
git bisect reset # 完成后
对比正常与故障:
## 有什么不同?
| 方面 | 正常 | 故障 |
| ------------ | ----------- | -------------- |
| 环境 | 开发环境 | 生产环境 |
| Node 版本 | 18.16.0 | 18.15.0 |
| 数据 | 空数据库 | 100 万条记录 |
| 用户 | 管理员 | 普通用户 |
| 浏览器 | Chrome | Safari |
| 时间 | 白天 | 午夜后 |
假设:基于时间的问题?检查时区处理。
// 函数调用跟踪
function trace(
target: any,
propertyKey: string,
descriptor: PropertyDescriptor,
) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Calling ${propertyKey} with args:`, args);
const result = originalMethod.apply(this, args);
console.log(`${propertyKey} returned:`, result);
return result;
};
return descriptor;
}
class OrderService {
@trace
calculateTotal(items: Item[]): number {
return items.reduce((sum, item) => sum + item.price, 0);
}
}
// Chrome DevTools 内存分析器
// 1. 拍摄堆快照
// 2. 执行操作
// 3. 拍摄另一个快照
// 4. 比较快照
// Node.js 内存调试
if (process.memoryUsage().heapUsed > 500 * 1024 * 1024) {
console.warn("High memory usage:", process.memoryUsage());
// 生成堆转储
require("v8").writeHeapSnapshot();
}
// 在测试中查找内存泄漏
let beforeMemory: number;
beforeEach(() => {
beforeMemory = process.memoryUsage().heapUsed;
});
afterEach(() => {
const afterMemory = process.memoryUsage().heapUsed;
const diff = afterMemory - beforeMemory;
if (diff > 10 * 1024 * 1024) {
// 10MB 阈值
console.warn(`Possible memory leak: ${diff / 1024 / 1024}MB`);
}
});
## 处理不稳定的 Bug 的策略
1. **添加大量日志**
- 记录时间信息
- 记录所有状态转换
- 记录外部交互
2. **查找竞态条件**
- 对共享状态的并发访问
- 异步操作完成顺序错乱
- 缺少同步
3. **检查时间依赖性**
- setTimeout/setInterval
- Promise 解决顺序
- 动画帧时序
4. **压力测试**
- 运行多次
- 改变时间
- 模拟负载
## 性能调试
1. **先分析**
- 不要盲目优化
- 测量前后变化
- 找到瓶颈
2. **常见原因**
- N+1 查询
- 不必要的重新渲染
- 大数据处理
- 同步 I/O
3. **工具**
- 浏览器 DevTools 性能选项卡
- Lighthouse
- Python: cProfile, line_profiler
- Node: clinic.js, 0x
## 生产环境调试
1. **收集证据**
- 错误跟踪 (Sentry, Bugsnag)
- 应用程序日志
- 用户报告
- 指标/监控
2. **本地复现**
- 使用生产数据(匿名化)
- 匹配环境
- 遵循确切步骤
3. **安全调查**
- 不要更改生产环境
- 使用功能标志
- 添加监控/日志
- 在预发布环境测试修复
## 卡住时,检查:
- [ ] 拼写错误(变量名拼写错误)
- [ ] 大小写敏感(fileName vs filename)
- [ ] Null/undefined 值
- [ ] 数组索引差一错误
- [ ] 异步时序(竞态条件)
- [ ] 作用域问题(闭包,变量提升)
- [ ] 类型不匹配
- [ ] 缺少依赖项
- [ ] 环境变量
- [ ] 文件路径(绝对 vs 相对)
- [ ] 缓存问题(清除缓存)
- [ ] 陈旧数据(刷新数据库)
每周安装量
4.5K
代码仓库
GitHub 星标
32.2K
首次出现
Jan 20, 2026
安全审计
安装于
claude-code3.4K
opencode3.3K
gemini-cli3.2K
codex3.1K
cursor3.0K
github-copilot2.8K
Transform debugging from frustrating guesswork into systematic problem-solving with proven strategies, powerful tools, and methodical approaches.
1. Observe : What's the actual behavior? 2. Hypothesize : What could be causing it? 3. Experiment : Test your hypothesis 4. Analyze : Did it prove/disprove your theory? 5. Repeat : Until you find the root cause
Don't Assume:
Do:
Explain your code and problem out loud (to a rubber duck, colleague, or yourself). Often reveals the issue.
## Reproduction Checklist
1. **Can you reproduce it?**
- Always? Sometimes? Randomly?
- Specific conditions needed?
- Can others reproduce it?
2. **Create minimal reproduction**
- Simplify to smallest example
- Remove unrelated code
- Isolate the problem
3. **Document steps**
- Write down exact steps
- Note environment details
- Capture error messages
## Information Collection
1. **Error Messages**
- Full stack trace
- Error codes
- Console/log output
2. **Environment**
- OS version
- Language/runtime version
- Dependencies versions
- Environment variables
3. **Recent Changes**
- Git history
- Deployment timeline
- Configuration changes
4. **Scope**
- Affects all users or specific ones?
- All browsers or specific ones?
- Production only or also dev?
## Hypothesis Formation
Based on gathered info, ask:
1. **What changed?**
- Recent code changes
- Dependency updates
- Infrastructure changes
2. **What's different?**
- Working vs broken environment
- Working vs broken user
- Before vs after
3. **Where could this fail?**
- Input validation
- Business logic
- Data layer
- External services
## Testing Strategies
1. **Binary Search**
- Comment out half the code
- Narrow down problematic section
- Repeat until found
2. **Add Logging**
- Strategic console.log/print
- Track variable values
- Trace execution flow
3. **Isolate Components**
- Test each piece separately
- Mock dependencies
- Remove complexity
4. **Compare Working vs Broken**
- Diff configurations
- Diff environments
- Diff data
// Chrome DevTools Debugger
function processOrder(order: Order) {
debugger; // Execution pauses here
const total = calculateTotal(order);
console.log("Total:", total);
// Conditional breakpoint
if (order.items.length > 10) {
debugger; // Only breaks if condition true
}
return total;
}
// Console debugging techniques
console.log("Value:", value); // Basic
console.table(arrayOfObjects); // Table format
console.time("operation");
/* code */ console.timeEnd("operation"); // Timing
console.trace(); // Stack trace
console.assert(value > 0, "Value must be positive"); // Assertion
// Performance profiling
performance.mark("start-operation");
// ... operation code
performance.mark("end-operation");
performance.measure("operation", "start-operation", "end-operation");
console.log(performance.getEntriesByType("measure"));
VS Code Debugger Configuration:
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug Program",
"program": "${workspaceFolder}/src/index.ts",
"preLaunchTask": "tsc: build - tsconfig.json",
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
"skipFiles": ["<node_internals>/**"]
},
{
"type": "node",
"request": "launch",
"name": "Debug Tests",
"program": "${workspaceFolder}/node_modules/jest/bin/jest",
"args": ["--runInBand", "--no-cache"],
"console": "integratedTerminal"
}
]
}
# Built-in debugger (pdb)
import pdb
def calculate_total(items):
total = 0
pdb.set_trace() # Debugger starts here
for item in items:
total += item.price * item.quantity
return total
# Breakpoint (Python 3.7+)
def process_order(order):
breakpoint() # More convenient than pdb.set_trace()
# ... code
# Post-mortem debugging
try:
risky_operation()
except Exception:
import pdb
pdb.post_mortem() # Debug at exception point
# IPython debugging (ipdb)
from ipdb import set_trace
set_trace() # Better interface than pdb
# Logging for debugging
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
def fetch_user(user_id):
logger.debug(f'Fetching user: {user_id}')
user = db.query(User).get(user_id)
logger.debug(f'Found user: {user}')
return user
# Profile performance
import cProfile
import pstats
cProfile.run('slow_function()', 'profile_stats')
stats = pstats.Stats('profile_stats')
stats.sort_stats('cumulative')
stats.print_stats(10) # Top 10 slowest
// Delve debugger
// Install: go install github.com/go-delve/delve/cmd/dlv@latest
// Run: dlv debug main.go
import (
"fmt"
"runtime"
"runtime/debug"
)
// Print stack trace
func debugStack() {
debug.PrintStack()
}
// Panic recovery with debugging
func processRequest() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Panic:", r)
debug.PrintStack()
}
}()
// ... code that might panic
}
// Memory profiling
import _ "net/http/pprof"
// Visit http://localhost:6060/debug/pprof/
// CPU profiling
import (
"os"
"runtime/pprof"
)
f, _ := os.Create("cpu.prof")
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
// ... code to profile
# Git bisect for finding regression
git bisect start
git bisect bad # Current commit is bad
git bisect good v1.0.0 # v1.0.0 was good
# Git checks out middle commit
# Test it, then:
git bisect good # if it works
git bisect bad # if it's broken
# Continue until bug found
git bisect reset # when done
Compare working vs broken:
## What's Different?
| Aspect | Working | Broken |
| ------------ | ----------- | -------------- |
| Environment | Development | Production |
| Node version | 18.16.0 | 18.15.0 |
| Data | Empty DB | 1M records |
| User | Admin | Regular user |
| Browser | Chrome | Safari |
| Time | During day | After midnight |
Hypothesis: Time-based issue? Check timezone handling.
// Function call tracing
function trace(
target: any,
propertyKey: string,
descriptor: PropertyDescriptor,
) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Calling ${propertyKey} with args:`, args);
const result = originalMethod.apply(this, args);
console.log(`${propertyKey} returned:`, result);
return result;
};
return descriptor;
}
class OrderService {
@trace
calculateTotal(items: Item[]): number {
return items.reduce((sum, item) => sum + item.price, 0);
}
}
// Chrome DevTools Memory Profiler
// 1. Take heap snapshot
// 2. Perform action
// 3. Take another snapshot
// 4. Compare snapshots
// Node.js memory debugging
if (process.memoryUsage().heapUsed > 500 * 1024 * 1024) {
console.warn("High memory usage:", process.memoryUsage());
// Generate heap dump
require("v8").writeHeapSnapshot();
}
// Find memory leaks in tests
let beforeMemory: number;
beforeEach(() => {
beforeMemory = process.memoryUsage().heapUsed;
});
afterEach(() => {
const afterMemory = process.memoryUsage().heapUsed;
const diff = afterMemory - beforeMemory;
if (diff > 10 * 1024 * 1024) {
// 10MB threshold
console.warn(`Possible memory leak: ${diff / 1024 / 1024}MB`);
}
});
## Strategies for Flaky Bugs
1. **Add extensive logging**
- Log timing information
- Log all state transitions
- Log external interactions
2. **Look for race conditions**
- Concurrent access to shared state
- Async operations completing out of order
- Missing synchronization
3. **Check timing dependencies**
- setTimeout/setInterval
- Promise resolution order
- Animation frame timing
4. **Stress test**
- Run many times
- Vary timing
- Simulate load
## Performance Debugging
1. **Profile first**
- Don't optimize blindly
- Measure before and after
- Find bottlenecks
2. **Common culprits**
- N+1 queries
- Unnecessary re-renders
- Large data processing
- Synchronous I/O
3. **Tools**
- Browser DevTools Performance tab
- Lighthouse
- Python: cProfile, line_profiler
- Node: clinic.js, 0x
## Production Debugging
1. **Gather evidence**
- Error tracking (Sentry, Bugsnag)
- Application logs
- User reports
- Metrics/monitoring
2. **Reproduce locally**
- Use production data (anonymized)
- Match environment
- Follow exact steps
3. **Safe investigation**
- Don't change production
- Use feature flags
- Add monitoring/logging
- Test fixes in staging
## When Stuck, Check:
- [ ] Spelling errors (typos in variable names)
- [ ] Case sensitivity (fileName vs filename)
- [ ] Null/undefined values
- [ ] Array index off-by-one
- [ ] Async timing (race conditions)
- [ ] Scope issues (closure, hoisting)
- [ ] Type mismatches
- [ ] Missing dependencies
- [ ] Environment variables
- [ ] File paths (absolute vs relative)
- [ ] Cache issues (clear cache)
- [ ] Stale data (refresh database)
Weekly Installs
4.5K
Repository
GitHub Stars
32.2K
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
claude-code3.4K
opencode3.3K
gemini-cli3.2K
codex3.1K
cursor3.0K
github-copilot2.8K
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
102,200 周安装
AI智能体长期记忆系统 - 精英级架构,融合6种方法,永不丢失上下文
1,200 周安装
AI新闻播客制作技能:实时新闻转对话式播客脚本与音频生成
1,200 周安装
Word文档处理器:DOCX创建、编辑、分析与修订痕迹处理全指南 | 自动化办公解决方案
1,200 周安装
React Router 框架模式指南:全栈开发、文件路由、数据加载与渲染策略
1,200 周安装
Nano Banana AI 图像生成工具:使用 Gemini 3 Pro 生成与编辑高分辨率图像
1,200 周安装
SVG Logo Designer - AI 驱动的专业矢量标识设计工具,生成可缩放品牌标识
1,200 周安装