Effective Debugging/Chapter 2. 범용적인 디버깅 기법
created : 2020-04-07T11:44:40+00:00
modified : 2020-09-26T14:27:16+00:00
Item 9. 성공적인 디버깅을 위한 마음가짐
- 소프트웨어에서 발생한 문제는 항상 찾아서 고칠수 있다고 믿는다.
- 시간을 충분히 판단한다.
- 고도로 집중한다.
- 어려운 문제를 만나면 잠을 자는것도 좋다.
기억할 사항
- 모든 문제는 찾아서 고칠 수 있다고 믿는다.
- 디버깅 작업에 필요한 시간을 충분히 확보한다.
- 작업에 최대한 집중할 수 있도록 환경을 마련한다.
- 힘든 문제를 해결할 때는 효과적인 수면을 취한다.
- 포기하지 않는다.
- 디버깅 환경, 도구, 기법을 익히는 데 꾸준히 노력한다.
Item 10. 효율적으로 문제 상황 재현하기
효율적으로 문제 상황을 재현하는 것이 가지는 장점
- 오류를 만들어 내기 위해 시간을 낭비할 필요 없이 곧바로 원인을 해결하는데 집중할 수 있다.
- 다른 사람들에게 도움을 청하기 좋다.
- 오류를 해결한 뒤에 검증하기 쉽다.
문제를 단순화 해라
- SSCCE라고 부르는 기준에 따라 간결하게 작성한다.
- 코드의 의존 관계가 많다면 상향식으로 접근하여 처음부터 새로 시작하는 것이 바람직하다.
- 문제를 파악하기 힘들 때에는 하향식으로 접근하여 경우의 수를 줄여나가는 것이 좋다.
중요 키워드
- 독립적인 형태
- 반복적으로 실행할 수 있는 환경
- 오류가 발생하는 버전에 대한 복사본을 언제든지 만들 수 있는 기능
기억할 사항
- 문제 상황을 재현할 수 있다면 디버깅 작업이 쉬워진다.
- 문제를 재현할 수 있는 예제를 최대한 간결하고 독립적으로 실행할 수 있는 형태로 만든다.
- 반복적으로 실행할 수 있는 환경을 구축한다.
- 버전 관리 시스템을 활용하여 소프트웨어에 버전을 지정해서 원하는 버전을 언제든지 불러 올 수 있도록 구성한다.
Item 11. 코드 수정 후 결과 확인까지의 시간 최소화하기
기억할 사항
- 수정한 코드의 결과를 확인하는 데 걸리는 시간을 최소화하여 효율을 높인다.
- 빠르게 빌드하고 배치하는 프로세스를 마련한다.
- 오류가 발생하면 최대한 빠르게 멈추게 한다.
Item 12. 복잡한 테스트 시나리오 자동화하기
- 루아를 배워보자ㅠ
기억할 사항
- 복잡한 테스트 케이스를 실행하는 작업은 스크립트 언어를 이용하여 자동화한다.
Item 13. 디버깅 관련 데이터를 한눈에 볼 수 있는 환경 구축하기
- 최대한 넓은 화면 확보
- 프린터로 출력해서 보자
기억할 사항
- 많은 데이터를 한눈에 볼 수 있다면 작업에 좀 더 집중할 수 있고 데이터의 패턴이나 상관관계를 파악하기도 쉽다.
- 화면 공간을 최대한 넓게 확보한다.
- 변경할 일이 거의 없는 데이터는 프린터로 출력해서 본다.
Item 14. 소프트웨어 업데이트 고려하기
- 디버깅에 들어가기 앞서 환경을 최신 버전으로 업데이트한다.
- 업데이트에 너무 큰 기대는 하지 않는다.
- 서드파티 모듈에서 버그가 발생할 수 있다는 점도 염두에 둔다.
Item 15. 서드파티 소스 코드 분석을 통해 문제 해결하기
- 작성하는 소프트웨어에서 사용하는 서드파티 모듈에 대한 소스 코드를 확보한다.
- 서드파티 API에 문제가 발생하거나 알 수 없는 에러 메시지가 출력되면 서드파티 소스 코드를 분석한다.
- 서드파티 라이브러리를 디버깅 버전으로 빌드해서 사용한다.
- 다른 대안이 없을 경우에만 서드파티 코드를 직접 수정한다.
Item 16. 전문 모니터링 및 테스팅 장비 활용하기
- 로직, 버스, 프로토콜 분석기를 활용하면 하드웨어 수준에서 발생하는 문제를 정확히 분석할 수 있다.
- 하드웨어에 관련된 문제를 분석할 때는 적절한 장치를 직접 제작하는 것도 도움된다.
- 네트워크 패킷을 모니터링할 때는 와이어샤크나 이더넷 허브, 매니지드 스위치, 또는 명령줄 기반의 패킷 수집프로그램을 활용한다.
Item 17. 오류의 효과 극대화하기
-
항상 참, 혹은 거짓이 되도록 소스코드를 수정한다.
if (fileds.time > apr_time_now() || 1) { ... } if (0) { ... }
- 환경을 수정해본다.
- 웹 요청을 처리하는 프로그램이라면, Apache JMeter와 같은 부하 테스트(load test)나 스트레스 테스트(stress test) 도구를 이용해본다.
- 싸구려 장비를 이용해서 제약을 줘본다.
- 데이터 유효성 또는 데이터 손상 문제를 분석할 떄는 퍼징(fuzzing)이라는 테스트 기법을 사용해본다.
zzuf
와 같은 도구를 활용하자
기억할 사항
- 의심스런 실행 경로를 인위적으로 따라가게 한다.
- 분석하려는 문제 현상이 눈에 잘 띄도록 그 효과를 극대화한다.
- 소프트웨어의 실행 영역이 정상 범위를 벗어나도록 스트레스를 준다.
- 모든 작업을 버전관리 시스템의 별도의 가지(Branch)에서 수행한다.
Item 18. 원격 디버깅 환경 구축하기
- 하드웨어에 밀접한 문제에 대한 디버깅 작업을 자신이 사용하는 컴퓨터의 화면과 키보드로 작업할 수 있도록 장치 에뮬레이터를 설치한다
- 임베디드 소프트웨어를 디버깅할 때는 자신이 사용하는 개발 머신에서 제공하는 도구를 활용할 수 있게 해주는 쐬기 모듈을 활용한다.
- 고객의 PC에 발생한 문제를 해결할 때는 원격에서 접속할 수 있는 환경을 구축한다.
- 서버에 대한 디버깅 작업을 원격에서 수행할 수 있도록 IP 기반 KVM 스위치를 설치한다.
Item 19. 디버깅 작업 자동화 하기
- 오류의 원인에 대한 모든 경우의 수를 탐색하는 작업을 자동화한다. 컴퓨터에게 시간은 별 것 아니지만 여러분의 시간은 소중하기 떄문이다.
Item 20.디버깅 전과 후에 정리하기
- 디버깅 작업을 수행할 때 쉬운 영역부터 공략하는 것이 좋다.
- 도구를 사용하여 쉽게 찾을 수 있는문제
- 수정 가능한 Assertion 실패처럼 프로그램 실행 과정에서 발생하는 경고 메시지
- 읽기 힘들게 작성된 코드에서 문제가 발생한 경우
- 주석에 XXX, FIXME, TODO와 같은 문구가 표기되어 있거나 should, think, must와 같이 뭔가 책임을 회피하는 듯한 문장이 담긴 미심쩍은 코드
- 그 밖에 무시했던 사소한 버그
기억할 사항
- 본격적인 디버깅에 들어가기 전에 작업 환경에서 오류가 발생하지 않도록 정리한다.
- 작업이 끝나면 임시로 수정한 코드를 제거하고 나중에 필요한 부분은 커밋한다.
Item 21. 비슷한 문제 모두 고치기
- 오류 하나를 수정한 뒤에는 이와 비슷한 유형의 오류도 찾아서 해결하고, 향후에도 발생하지 않도록 적절히 조치한다.