systematic-debugging

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Systematic Debugging

系统调试(Systematic Debugging)

엄격한 디버깅 워크플로우다. 버그, 테스트 실패, 예기치 않은 동작을 다룰 때 사용한다.
핵심 목적은 세 가지다.
  1. 증상이 아니라 원인을 고친다.
  2. 추측 기반 수정을 막는다.
  3. 실패를 테스트로 고정한 뒤 수정한다.
这是一套严格的调试工作流,用于处理Bug、测试失败、异常行为等场景。
核心目标有三个:
  1. 修复根因而非表面症状
  2. 避免基于猜测的修改
  3. 先通过测试锁定失败场景再进行修复

Hard Gates

硬性准则

다음 규칙은 예외 없이 따른다.
  1. 재현 또는 관측 가능 상태를 만들기 전에는 수정하지 않는다.
  2. 원인 가설을 명시하기 전에는 수정하지 않는다.
  3. 실패 테스트 또는 동등한 재현 장치를 만들기 전에는 수정하지 않는다.
  4. 한 번에 하나의 가설만 검증한다.
  5. 수정 시 "while I'm here" 리팩터링을 금지한다.
  6. 수정 시도가 3번 실패하면 추가 패치 전에 구조적 문제를 의심한다.
이 과정을 어기는 것은 디버깅 실패로 본다.
以下规则无例外必须遵守:
  1. 未构建可复现或可观测状态前不进行修复
  2. 未明确根因假设前不进行修复
  3. 未编写失败测试用例或等价复现工具前不进行修复
  4. 每次仅验证一个假设
  5. 修复时禁止「顺便」做无关重构
  6. 连续3次修复失败后,在追加补丁前先排查是否存在结构性问题
违反以上流程即视为调试失败。

When To Use

适用场景

다음 상황이면 이 스킬을 사용한다.
  • 테스트가 실패할 때
  • 운영 또는 로컬에서 버그가 발생할 때
  • 예상과 다른 응답, 상태, 렌더링, 쿼리 결과가 나올 때
  • 성능 저하, 타임아웃, 레이스 컨디션, 간헐 실패를 조사할 때
  • 이미 한 번 이상 고쳤는데 다시 깨졌을 때
다음 핑계는 허용하지 않는다.
  • "간단해 보여서 바로 고치면 된다"
  • "시간이 없으니 일단 패치하고 보자"
  • "이거 같으니까 그냥 바꿔보자"
出现以下情况时可使用本工作流:
  • 测试失败时
  • 线上或本地环境出现Bug时
  • 出现不符合预期的响应、状态、渲染、查询结果时
  • 排查性能下降、超时、竞态条件、偶发失败问题时
  • 问题已经修复过一次又再次复现时
不允许以下借口:
  • "看起来很简单,直接改就行"
  • "没时间了,先打个补丁再说"
  • "感觉是这个问题,直接改改试试"

Required Output Contract

必要输出约定

이 스킬을 사용할 때는 내부적으로 아래 항목을 반드시 고정한다.
  1. Problem statement: 무엇이 잘못되었는지 한 문장으로 정의
  2. Reproduction path: 어떻게 실패를 재현하거나 관측할지
  3. Evidence: 실제 관측 결과
  4. Root-cause hypothesis: 왜 이 문제가 발생한다고 보는지
  5. Failing guard: 실패 테스트, 재현 스크립트, 로그 검증 중 하나
  6. Fix: 원인에 대한 단일 수정
  7. Verification: 수정 후 재현 경로와 관련 테스트 결과
이 7개 중 빠진 항목이 있으면 아직 끝난 일이 아니다.
使用本工作流时必须明确以下7项内容:
  1. 问题描述:用一句话定义具体问题
  2. 复现路径:说明如何复现或观测到失败现象
  3. 证据:实际观测到的结果
  4. 根因假设:你认为问题出现的原因
  5. 失败防护:失败测试用例、复现脚本、日志校验三者之一
  6. 修复方案:针对根因的单一修改
  7. 验证结果:修复后复现路径的执行结果和相关测试结果
以上7项缺少任意一项都不算调试完成。

Workflow

工作流程

반드시 아래 순서로 진행한다.
必须严格按照以下顺序执行:

Phase 1. Define The Problem

阶段1:定义问题

먼저 문제를 축약한다.
  • 실제 기대 동작은 무엇인가
  • 실제 관측 동작은 무엇인가
  • 영향 범위는 어디까지인가
  • 항상 재현되는가, 간헐적인가
출력 형식:
text
Problem: <expected> but got <actual> under <condition>
증상과 추측을 섞지 않는다.
text
Good: Product detail API returns 500 when brand is null.
Bad: Serializer is broken because brand mapping seems wrong.
首先提炼核心问题:
  • 预期的正确行为是什么
  • 实际观测到的行为是什么
  • 影响范围有多大
  • 是必现问题还是偶发问题
输出格式:
text
Problem: <expected> but got <actual> under <condition>
不要混合症状和猜测:
text
正确示例: Product detail API returns 500 when brand is null.
错误示例: Serializer is broken because brand mapping seems wrong.

Phase 2. Reproduce Or Instrument

阶段2:复现或加埋点

수정 전에 실패를 다시 볼 수 있어야 한다.
우선순위:
  1. 기존 테스트로 재현
  2. 최소 통합 테스트로 재현
  3. 단위 테스트로 재현
  4. 재현 스크립트 또는 명령으로 관측
  5. 로그/계측 추가 후 관측
규칙:
  • 재현 경로는 가능한 한 가장 작게 만든다.
  • UI에서만 보이는 버그라도 더 아래 계층에서 재현 가능하면 그쪽을 선호한다.
  • 간헐 실패면 로그, 입력, 시간, 동시성 조건을 추가해 관측성을 높인다.
  • 재현되지 않으면 수정으로 넘어가지 말고 관측 수단을 늘린다.
재현 불가 상태에서 해야 할 일:
  1. 입력값 기록
  2. 환경 차이 확인
  3. 최근 변경점 확인
  4. 경계 지점별 로그 추가
  5. 동일 증상을 만드는 더 작은 조건 탐색
修复前必须能够复现失败现象。
复现优先级:
  1. 通过现有测试用例复现
  2. 通过最小集成测试复现
  3. 通过单元测试复现
  4. 通过复现脚本或命令观测
  5. 添加日志/埋点后观测
规则:
  • 复现路径尽可能简化
  • 即使是仅在UI上出现的Bug,如果能在下层架构复现则优先选择下层复现
  • 针对偶发失败,通过补充日志、输入、时间、并发条件提升可观测性
  • 无法复现则不要进入修复环节,优先补充观测手段
无法复现时的处理方案:
  1. 记录输入值
  2. 排查环境差异
  3. 确认近期变更点
  4. 在边界节点添加日志
  5. 探索能触发相同症状的最小条件

Phase 3. Gather Evidence

阶段3:收集证据

관측 가능한 사실만 모은다.
항상 확인할 것:
  • 에러 메시지와 스택트레이스 전문
  • 실패 입력값
  • 최근 변경 파일 또는 커밋
  • 환경/설정 차이
  • 호출 경로와 데이터 흐름
멀티 컴포넌트 문제에서는 경계마다 확인한다.
예시:
  • controller -> application -> service -> repository
  • client -> API -> external service
  • scheduler -> batch service -> database
각 경계에서 확인할 것:
  • 무엇이 들어왔는가
  • 무엇이 나갔는가
  • 어떤 값이 변형되었는가
  • 어떤 조건에서만 깨지는가
문제 위치를 특정하기 전에는 고치지 않는다.
仅收集可观测的客观事实:
必须确认项:
  • 完整的错误信息和栈追踪
  • 触发失败的输入值
  • 近期变更的文件或提交
  • 环境/配置差异
  • 调用路径和数据流
多组件协作的问题需要在每个边界节点确认:
示例边界:
  • controller -> application -> service -> repository
  • client -> API -> external service
  • scheduler -> batch service -> database
每个边界需要确认:
  • 输入值是什么
  • 输出值是什么
  • 哪些值发生了变更
  • 仅在什么条件下会出现问题
未定位问题位置前不要进行修复。

Phase 4. Isolate Root Cause

阶段4:隔离根因

원인 후보를 하나만 세운다.
형식:
text
Hypothesis: <root cause> because <evidence>
좋은 가설의 조건:
  • 단일 원인을 가리킨다
  • 관측 증거와 연결된다
  • 작은 실험으로 반증 가능하다
나쁜 가설의 예:
  • "어딘가 비동기 문제가 있는 것 같다"
  • "직렬화 쪽 전체가 불안정한 듯하다"
원인을 소스까지 거슬러 올라간다. 오류가 깊은 스택에서 보이면 증상이 아니라 입력의 출처를 추적한다.
每次仅提出一个根因候选:
格式:
text
Hypothesis: <root cause> because <evidence>
好的假设的条件:
  • 指向单一原因
  • 和观测到的证据关联
  • 可以通过小型实验证伪
坏的假设示例:
  • "感觉哪里有异步问题"
  • "序列化模块整体好像不太稳定"
要溯源到根因的源头代码,如果错误出现在深层调用栈,不要只关注表面症状,要追踪输入的来源。

Phase 5. Lock The Failure

阶段5:锁定失败场景

수정 전에 실패를 고정한다.
우선순위:
  1. 자동화된 failing test
  2. 기존 테스트에 회귀 케이스 추가
  3. 최소 재현 스크립트
  4. 로그/어설션 기반 임시 검증 장치
규칙:
  • 가능하면 자동화 테스트를 만든다.
  • 수정 전에는 실패해야 한다.
  • 수정 후에는 같은 경로에서 통과해야 한다.
  • 테스트 이름은 무엇이 깨졌는지 드러내야 한다.
자동화 테스트를 쓸 수 있으면
test-driven-development
스킬을 함께 사용한다.
修复前先锁定失败场景:
优先级:
  1. 自动化失败测试用例
  2. 在现有测试中添加回归用例
  3. 最小复现脚本
  4. 基于日志/断言的临时校验工具
规则:
  • 尽可能编写自动化测试
  • 修复前测试用例必须执行失败
  • 修复后同一路径测试用例必须执行成功
  • 测试名称要清晰体现失败的场景
如果可以编写自动化测试,可搭配
test-driven-development
工作流使用。

Phase 6. Implement A Single Fix

阶段6:执行单一修复

수정은 하나의 가설만 다룬다.
허용:
  • 원인에 직접 대응하는 최소 코드 변경
  • 검증에 필요한 최소한의 보조 수정
금지:
  • 관련 있어 보이는 여러 수정 묶기
  • 리팩터링 겸 수정
  • 포맷/정리/이름 변경 끼워넣기
  • 근거 없는 null-guard 추가
  • 예외 삼키기
실패하면 즉시 다시 Phase 1 또는 Phase 3으로 돌아간다. 이전 가설이 틀렸다는 뜻이다.
一次修复仅处理一个假设:
允许的操作:
  • 直接针对根因的最小代码修改
  • 验证所需的最少辅助修改
禁止的操作:
  • 合并多个看起来相关的修改
  • 修复同时做重构
  • 夹带格式调整/代码清理/命名修改
  • 无依据地添加null防护
  • 吞掉异常
如果修复失败,立刻回到阶段1或阶段3,说明之前的假设是错误的。

Phase 7. Verify And Close

阶段7:验证并闭环

아래를 모두 만족해야 종료한다.
  1. 원래 재현 경로가 더 이상 실패하지 않는다.
  2. 새 failing guard가 통과한다.
  3. 관련 테스트가 깨지지 않는다.
  4. 수정이 증상이 아니라 원인을 막는다는 설명이 가능하다.
간헐 버그라면 한 번 통과로 끝내지 않는다. 반복 실행 또는 조건 변화 하 검증이 필요하다.
满足以下所有条件才可结束调试:
  1. 原复现路径不再触发失败
  2. 新增的失败防护工具执行通过
  3. 相关测试用例没有被破坏
  4. 可以说明修复是针对根因而非仅解决表面症状
如果是偶发Bug,不要仅通过一次成功就判定修复完成,需要重复执行或变更条件多次验证。

Stop Conditions

停止条件

다음 상황이면 멈추고 프레임을 다시 잡는다.
出现以下情况时需要停下来重新梳理思路:

1. Reproduction Failed

1. 无法复现

여러 번 시도해도 재현이 안 되면:
  • 관측 수단이 부족한지 본다.
  • 환경 차이가 있는지 본다.
  • 문제 정의가 잘못되었는지 본다.
재현이 안 되는데 코드를 바꾸는 것은 금지다.
多次尝试都无法复现问题时:
  • 检查是否观测手段不足
  • 检查是否存在环境差异
  • 检查问题定义是否有误
无法复现的情况下禁止修改代码。

2. Three Failed Fixes

2. 连续三次修复失败

세 번 연속으로 수정이 빗나가면 이렇게 판단한다.
  • 현재 이해가 틀렸거나
  • 문제가 공유 상태, 경계 설계, 책임 분리 같은 구조 문제일 가능성이 크다
이 시점부터는 "네 번째 땜질"이 아니라 구조 논의가 필요하다.
连续三次修复都没有解决问题时,基本可以判定:
  • 当前对问题的理解有误,或者
  • 问题大概率是共享状态、边界设计、职责拆分等结构性问题导致
此时不应该尝试第四次补丁修复,而需要先讨论结构性问题。

3. No Failing Guard

3. 没有失败防护

실패 테스트나 동등한 재현 장치를 만들 수 없으면, 완료로 선언하지 않는다. 최소한 재현 명령과 관측 결과를 남긴다.
无法编写失败测试用例或等价复现工具时,不要宣称问题已解决,至少要留存复现命令和观测结果。

Red Flags

危险信号

아래 생각이 들면 즉시 멈추고 앞 단계로 돌아간다.
  • "이 줄만 바꿔보면 될 것 같다"
  • "로그는 나중에 보고 일단 수정해보자"
  • "테스트는 나중에 추가하지 뭐"
  • "한 번에 이것도 저것도 같이 고치자"
  • "에러는 사라졌으니 원인은 몰라도 됐다"
出现以下想法时要立刻停下回到前序阶段:
  • "我只要改这一行应该就好了"
  • "日志后面再看,先改试试"
  • "测试后面再加就行"
  • "一次把这几个问题一起改了"
  • "错误消失了就行,不用管根因"

Minimal Checklist

最简检查清单

실행 중에는 아래 체크리스트를 기준으로 스스로 검증한다.
  • 문제를 한 문장으로 정의했다
  • 실패를 재현하거나 관측 가능하게 만들었다
  • 증거를 수집했다
  • 단일 원인 가설을 만들었다
  • 수정 전 실패 guard를 만들었다
  • 단일 수정만 적용했다
  • 같은 경로로 수정 후 검증했다
执行过程中对照以下清单自我校验:
  • 已经用一句话定义清楚问题
  • 已经可以复现或观测到失败现象
  • 已经收集完相关证据
  • 已经提出单一根因假设
  • 修复前已经做好失败防护
  • 仅执行了单一修复操作
  • 修复后通过同一路径完成验证

Completion Standard

完成标准

이 스킬의 완료 기준은 "코드가 바뀌었다"가 아니다.
완료 기준:
  • 문제 정의가 명확하다
  • 실패가 수정 전에 고정되었다
  • 수정이 원인과 연결된다
  • 검증 결과가 남아 있다
이 네 가지가 없으면 디버깅은 끝난 것이 아니다.
本工作流的完成标准不是「代码已经修改」。
完成标准:
  • 问题定义清晰明确
  • 失败场景在修复前已经被锁定
  • 修复方案和根因直接关联
  • 留存了验证结果
缺少以上任意四点都不算调试完成。