버그가 나는 복잡한 코드에서 상관없는 부분을 걷어 내고, 버그가 여전히 일어나는 가장 작은 형태(Minimal Reproducible Example, MRE)를 만드는 것이다. 줄이는 과정 자체가 디버깅이다. 무언가를 지웠더니 버그가 사라졌다면 그 부분이 단서다.
줄이는 방법
- 함수 호출을 하드코딩한 값으로 바꿔도 버그가 나는지 본다
- 의심 가지 않는 큰 덩어리를 주석 처리해 범위를 반씩 줄인다
- 잘 동작하는 예제(문서의 예시 등)에서 출발해 조금씩 내 코드처럼 바꾸다 깨지는 지점을 찾는다
- 한 번에 하나만 바꾼다. 여러 개를 한꺼번에 바꿨다면 되돌리고(
git stash) 하나씩 다시 한다
무작위성 없애기
열 번에 한 번 나는 버그는 디버깅하기 어렵다. 매번 같은 결과가 나오게 만든다.
- 난수 생성기(Random Number Generator)에 시드(Seed)를 고정한다
- 현재 시간을 가짜로 고정한다(faketime, 테스트용 시계 주입)
- HTTP(HyperText Transfer Protocol) 요청을 녹화해 재생한다(Ruby의 VCR 같은 도구, 프런트엔드라면 MSW로 API 모킹)
- 실행 전체를 녹화하고 재생하는 디버거(rr 등)를 쓴다
실패하는 테스트로 고정하기
재현이 되면 그것을 테스트로 만든다.
- 버그가 일어나는 정확한 지점에 집중하게 만든다
- 고쳤는지 테스트 통과로 바로 안다
- 같은 버그가 돌아오지 않게 지켜 준다 → 자가 테스트 코드, 테스트 주도 개발 (TDD)
남에게 물을 때
이슈를 올리거나 질문할 때 최소 재현을 붙이면 답을 받을 확률이 크게 오른다. 만드는 도중에 스스로 답을 찾는 경우도 많다 → 러버덕 디버깅
디버깅의 전체 흐름에서는 세 번째 단계에 해당한다 → 디버깅 문제 정의 5단계
출처: The Pocket Guide to Debugging Julia Evans · 참고: How to create a Minimal, Reproducible Example Stack Overflow