其他
调试 bug/故障时,用四步调试纪律先复现、再定位…
当用户报告 bug、说某处损坏/抛错/失败,要求调试/诊断/调查,或粘贴 stack trace / 错误日志,或触发 /debug-mantra 时,按四步纪律调试并在首次回复背诵口诀。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 48/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 55/100 ×0.15
适用场景
调试 bug/故障时,用四步调试纪律先复通用
解决思路
- 在任何调试会话的首次回复中,先逐字背诵口诀块,然后才开始工作;口诀为:1)首先是可复现性:问题能否被可靠复现?2)了解失败路径:先调试器;再源码追踪+旋钮枚举;最后代码内插桩。3)质疑你的假设:什么能证伪它?4)每次运行都是面包屑:交叉引用所有面包屑。
- 每个调试会话只背诵一次口诀,首次回复中完成;会话中途不要重复背诵。
- 背诵必须逐字进行,绝不转述、缩短或跳过任何行。
- 如果用户说“skip the mantra”,跳过背诵,但仍静默应用四步。
- 按顺序应用四步:在 #1 满足(存在可靠复现)前,不要提出修复。
- 在 #2 缩小失败路径前,不要开始测试假设。
- 在 #3 尝试证伪假设前,不要认定某个假设。
- 在 #4 用所有先前面包屑确认假设前,不要宣布假设正确。
- 如果发现自己没有可靠复现就提出修复,停止并返回步骤 1。
- 把口诀作为你贯穿整个会话的约束,而不是反馈给用户的建议。
- 步骤 1:在任何其他事情之前,构建可运行的复现。
- 可靠复现:将精确步骤、输入和环境捕获为可运行工件:失败测试(failing test)、curl 脚本、CLI 调用、回放 harness(replay harness)。
- 不稳定复现:bug 尚不可调试;先提高触发率:循环触发、并行化、增加压力、缩小时间窗口、注入 sleep。50% flake 可调试,1% 不可调试。
- 完全没有复现:停止;明确说明;向用户请求环境访问、捕获的工件(HAR、log dump、core),或请求插桩权限;不要继续假设。
- 步骤 1 目标:获得快速(1–5 秒)、确定性的通过/失败信号;固定时间、设置 RNG 种子、冻结网络、隔离文件系统。
- 步骤 2:在可复现后,找到代码在哪里出问题以及什么阻止它出问题;差分实验缩小搜索范围。
- 步骤 2 按顺序尝试,只有前一策略失败才升级:先附加调试器。
- 如果环境支持,附加调试器并单步到失败点;一个断点胜过十个日志;在转动任何旋钮之前先做这个。
- 如果无调试器(或调试器到不了 bug),进行源码追踪 + 旋钮枚举:端到端追踪代码路径,并列出所有可能影响结果的旋钮。
- 旋钮包括:配置标志、环境变量、功能开关。
- 旋钮包括:分支条件、输入形状。
- 旋钮包括:时序、并发、构建选项。
- 每个旋钮是差分实验中可翻转的候选轴;一次只翻转一个。
- 如果外部旋钮无法移动失败,进行代码内插桩:在可疑失败点加 printf / 日志语句,转储相关内部状态。
- 给每个探针打上唯一前缀(例如 [DBG-a4f2]),以便清理只需一次 grep。
- 让追踪显示现实在哪里偏离你的模型。
- 步骤 3:当候选根因出现时,在测试前先审视它。
- 检查它是否真正端到端解释症状;完整走一遍。
- 确定最简单的证明是什么?最干净的证伪是什么?
- 先运行证伪;如果假设存活,它是真的;如果死亡,避免追逐幻影。
- 生成 3–5 个排序假设,而不是一个;单一假设思维会锚定在第一个看似合理的想法上。
- 步骤 4:维护会话中每个实验的运行账本(ledger);每条记录包括:改变了什么、发生了什么、排除了什么或确认了什么。
- 当新假设出现时,走查账本:它是否对每个先前观察成立,而不仅仅是最新观察?
- 如果任何过去运行与之矛盾,假设错误或不完整——细化或丢弃。
- 不确定时,设计单个实验,其结果能使其确定;接下来运行那个,而不是在相邻运行上空转。
- 每次运行后更新账本;它是你跨会话的记忆。
适用边界 · 注意事项
- 不适用于非调试任务,例如普通功能实现、代码审查、概念解释或与 bug 无关的问答。
- 当完全没有复现且无法获得环境访问、捕获工件或插桩权限时,不要继续提出假设或修复;应停止并明确说明,请求所需信息。
- 如果用户明确说“skip the mantra”,不要背诵口诀;但仍需静默应用四步,因此不能把它当作完全跳过调试纪律。