Systematic Debugging (체계적 디버깅)
개요
임시방편(Temporary Fix)은 시간을 낭비하고 새로운 버그를 낳습니다. 근본 원인(Root Cause)을 찾지 않고 증상만 치료하려 하지 마십시오.
철칙 (The Iron Law):
근본 원인 규명 없이는 수정도 없다 (NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST)
이 스킬의 사용 시점
- 테스트 실패
- 프로덕션 버그
- 예상치 못한 동작
- 성능 문제
- 빌드 실패
특히 다음과 같은 유혹이 들 때 더더욱 사용하세요:
- "시간이 없으니 일단 이렇게 해보자"
- "간단한 문제 같은데?"
- "이미 여러 방법을 시도해봤는데 안 되네"
4단계 절차 (The Four Phases)
1단계: 근본 원인 조사 (Root Cause Investigation)
수정을 시도하기 전에 반드시 완료해야 합니다.
- 에러 메시지 정독: 에러 코드, 스택 트레이스, 파일 경로, 라인 번호를 정확히 파악하세요.
- Trace ID 및 APM 연동: 분산 환경이나 복잡한 환경일 경우 로그나 Datadog 등 APM에서
trace_id또는span_id를 최우선으로 확보하여 연계된 모든 서비스의 흐름을 파악하세요. - 재현(Reproduction): 문제를 일관되게 재현할 수 있는 절차를 확립하세요. 재현되지 않는 버그는 고칠 수 없습니다.
- 변경 사항 추적: 최근에 무엇이 바뀌었나요? (Git diff, 의존성 업데이트, 환경 설정 등)
2단계: 패턴 분석 (Pattern Analysis)
- 정상 작동 케이스 비교: 유사한 로직인데 정상적으로 작동하는 코드가 있나요? 차이점을 한 줄 한 줄 비교하세요.
- 의존성 파악: 이 코드가 실행되기 위해 필요한 전제 조건(데이터, 설정, 상태)은 무엇인가요?
3단계: 가설 수립 및 검증 (Hypothesis and Testing)
- 단일 가설 수립: "X가 Y 때문에 문제의 원인일 것이다"라고 명확히 정의하세요.
- 최소 검증: 가설을 확인하기 위한 가장 작은 실험을 하세요. (로그 추가, 변수 값 확인 등)
- 결과 확인: 실험 결과가 가설을 지지하나요? 아니라면 새로운 가설을 세우세요.
4단계: 구현 (Implementation)
- 실패하는 테스트 작성 (Red): 문제를 가장 간단하게 재현하는 테스트 코드를 작성하세요.
- 최소 수정 (Green): 근본 원인을 해결하는 최소한의 코드를 작성하세요. "이 김에 리팩토링"은 하지 마십시오.
- 검증 (Refactor): 문제가 해결되었는지, 다른 기능에 영향(Side Effect)은 없는지 확인하세요.
위험 신호 (Red Flags) - 즉시 멈추세요
- "일단 이거 해보고 안 되면 저거 해보자" (무작위 대입)
- "왜 되는지/안 되는지 모르겠지만 일단 넘어가자"
- 같은 문제를 해결하기 위해 3번 이상 수정을 시도하고 있다. -> 멈추고 아키텍처를 의심하세요.
잘못된 합리화
| 핑계 | 현실 |
|---|---|
| "너무 급해서 절차를 따를 시간이 없어요" | 체계적 디버깅이 무작위 시도보다 항상 빠릅니다. |
| "간단한 문제라 바로 고칠 수 있어요" | 진짜 원인을 모른다면 간단한 문제가 아닙니다. |
| "테스트는 나중에 짤게요" | 검증되지 않은 수정은 수정이 아닙니다. |