Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Systematic 6-phase debugging protocol. Structured approach to bugs with quick checks, isolated testing, 20-minute rule, and bug report template.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✗→✓ | ▲ Improved | 79% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 140% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 56% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 61% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 26% | 0% |
> 中文 — bugfix-protocol 官方中文版本。
结构化的 Bug 处理方法 — 从症状分析到验证。 防止盲目的试错,确保修复方案可持续。
| 阶段 | 名称 | 目标 | 最长时间 | |------|------|------|----------| | 1 | 快速检查 | 排除明显原因 | 2 分钟 | | 2 | 诊断 | 定位根本原因 | 10 分钟 | | 3 | 隔离测试 | 使 Bug 可复现 | 5 分钟 | | 4 | 修复 | 最小化修正 | 10 分钟 | | 5 | 验证 | 验证修复 + 检查副作用 | 5 分钟 | | 6 | 文档编写 | 保存知识经验 | 2 分钟 |
20分钟规则: 如果 20 分钟后仍无进展,请改变方法或寻求帮助。
在深入分析之前 — 检查最常见的原因:
__pycache__,重新启动bash# 清除缓存 find . -name "__pycache__" -type d -exec rm -rf {} + 2>&1 find . -name "*.pyc" -delete 2>&1 # 检查导入 python -c "import modulename" # 检查语法 python -m py_compile file.py
git diff, git log --oneline -10根据项目的不同,专用的诊断脚本可能会大有帮助:
| 工具 | 用途 | |------|------| | import_diagnose.py | 分析导入问题 | | method_analyzer.py | 检查方法签名 | | env_checker.py | 验证环境变量/路径 |
> 注意: 创建项目专属的诊断工具或使用现有的工具。 > 重要的是系统性的方法,而不是具体的工具。
python# 1. Print 调试 (简单但高效) print(f"DEBUG: variable={variable!r}, type={type(variable)}") # 2. 断点 (交互式) breakpoint() # Python 3.7+ # 3. 详细堆栈追踪 import traceback traceback.print_exc() # 4. 使用日志替代 print import logging logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) logger.debug(f"State: {state!r}")
目标:用最少的代码复现 Bug。
python# test_bug.py — 最小复现测试 """ Bug: [简短描述] Expected: [预期发生的结果] Actual: [实际发生的结果] """ # 最小化设置 # ... 仅保留核心必要代码 # Bug 触发器 # ... 触发 Bug 的精确代码 # 预期结果 # assert result == expected, f"Got {result}"
git bisect start, git bisect bad, git bisect good <commit>python# 错误做法:仅处理表面症状 try: result = broken_function() except: # 吞掉所有异常 result = default_value # 正确做法:修复根本原因 def broken_function(): if input_data is None: # 真正原因:缺少 None 检查 return default_value return process(input_data)
| 类别 | 典型修复方案 | |------|--------------| | None/Null | 卫语句:if x is None: return default | | 索引错误 | 边界检查:if i < len(lst) | | 类型错误 | 显式转换:str(x), int(x) | | 导入错误 | 修复路径,安装包 | | 编码问题 | 显式指定 UTF-8:encoding='utf-8' | | 竞态条件 | 锁/互斥锁,或调整顺序 | | 状态 Bug | 检查初始化,添加重置机制 |
bash# 单元测试 python -m pytest tests/ -v # 仅受影响的测试 python -m pytest tests/test_module.py -v -k "test_name" # 类型检查 python -m mypy file.py # Lint 检查 python -m flake8 file.py
markdown## Bug Report: [简短标题] **Date:** YYYY-MM-DD **Severity:** critical / high / medium / low **Component:** [模块/文件] ### Symptom [用户看到的现象 / 错误信息] ### Root Cause [技术层面的根本原因] ### Fix [修改了什么 + 为什么这样修改] ### Affected Files - `file1.py` — [修改说明] - `file2.py` — [修改说明] ### Prevention [将来如何防止此类 Bug 再次发生?]
fix: [修复的简短描述]
Cause: [一句话说明根本原因]
Fix: [修改了什么]
Test: [如何验证的]> 本节适用于使用 PyQt6/PySide6 的桌面 GUI 项目。
| 陷阱 | 问题 | 解决方案 | |------|------|----------| | Signal-Slot 断开 | 信号已连接但处理函数未运行 | 在处理函数中加 print,检查签名 | | 线程安全 | 从工作线程更新 GUI | 使用 QMetaObject.invokeMethod 或信号 | | 布局层叠 | 控件不可见/位置错乱 | widget.show(),检查布局层级 | | 事件循环阻塞 | GUI 界面冻结 | 将耗时操作移至 QThread | | 垃圾回收 | 控件突然消失 | 将引用保存为 self.widget |
python# 打印控件层级树 def dump_widget_tree(widget, indent=0): print(" " * indent + f"{widget.__class__.__name__}: {widget.objectName()}") for child in widget.findChildren(QWidget): if child.parent() == widget: dump_widget_tree(child, indent + 2) # 信号调试 from PyQt6.QtCore import QObject original_connect = QObject.connect def debug_connect(self, *args, **kwargs): print(f"CONNECT: {self.__class__.__name__} -> {args}") return original_connect(self, *args, **kwargs)
发现 BUG?
|
v
[阶段 1: 快速检查] ────── 明显原因? -> 修复
|
v
[阶段 2: 诊断] ────────── 原因明确? -> 阶段 4
|
v
[阶段 3: 隔离测试] ────── 可复现? -> 阶段 4
| |
| 不可复现?
| |
| 添加日志,
| 等待再次发生
v
[阶段 4: 修复] ─────────── 最小化 + 已理解
|
v
[阶段 5: 验证] ────────── 测试通过? -> 阶段 6
| |
| 测试失败? -> 返回阶段 4
v
[阶段 6: 文档编写] ────── Bug 报告 + commit如果你在 20 分钟后陷入困境:
git stash,完全重新开始Other measured skills in the registry, with their headline benchmark lift.