관찰하려는 질문에 맞춰 도구 고르기
중단점은 특정 순간에 실행을 멈추고 레지스터나 메모리, 호출 경로를 확인하기 좋습니다. 로그는 여러 작업이 시간에 따라 어떻게 진행됐는지 남기기에 좋습니다. 둘 중 하나가 항상 더 정확하거나 빠른 것은 아닙니다. 계산 결과가 처음 틀어지는 함수의 경계를 안다면 중단점으로 전후 값을 비교할 수 있고, 오랜 시간 뒤에만 발생하는 오류라면 로그가 조사 범위를 좁히는 데 도움이 됩니다. 먼저 지금 모르는 것이 값인지 순서인지 횟수인지 적어 보세요. 그 질문이 명확하면 코드를 무작정 멈추거나 로그를 계속 추가하는 일을 줄일 수 있습니다.
로그에는 연결할 수 있는 문맥 남기기
실패했다는 메시지만 반복해서 남으면 서로 다른 작업이 섞였을 때 어느 흐름의 실패인지 구분하기 어렵습니다. 공개 가능한 작업 식별자, 처리 단계, 오류 종류와 필요한 크기 정보처럼 앞뒤를 연결할 문맥이 필요합니다. 다만 입력 전체나 인증 정보, 개인 데이터를 그대로 기록하는 방식은 피해야 합니다. 시간 정보도 한 줄이 출력된 순서와 실제 사건의 인과관계가 같다고 보장하지는 않습니다. 여러 스레드나 비동기 작업에서는 출력 버퍼와 스케줄링의 영향을 고려해야 합니다. 로그를 설계할 때는 기록량보다 특정 가설을 확인할 수 있는 정보를 우선합니다.
중단점이 문제를 숨길 수도 있다
시간에 민감한 프로그램은 정지하는 순간 외부 연결이 끊기거나 스레드 실행 순서가 달라질 수 있습니다. 따라서 디버거에서만 문제가 안 난다면 그 결과를 정상이라고 단정하면 안 됩니다. 로그를 남기는 작업 역시 입출력과 동기화에 영향을 줄 수 있으므로 원래 조건과 다른 점을 기록해야 합니다. DBG Desk의 이벤트 로그는 GDB와 대상에서 전달된 출력 및 정지 이벤트를 보여주지만 애플리케이션의 모든 작업을 자동으로 추적하지는 않습니다. 필요한 사건이 로그에 없다면 실행되지 않았다고 곧바로 결론 내리기보다 그 사건을 기록하는 코드가 있는지부터 확인하세요.
흐름을 좁힌 뒤 정지해서 확인하기
현실적인 조합은 로그로 실패가 시작되는 구간을 찾고, 재현 가능한 입력을 확보한 뒤 중단점으로 구체적인 값을 확인하는 방식입니다. 함수 입구에서 입력을 보고 반환 직전에 결과를 비교하면 그 구간이 책임지는 계산이 맞는지 판단할 수 있습니다. 확인한 가설과 반례를 간단히 남기고 필요 없는 로그와 중단점은 정리하세요. 임시 조사 코드를 영구 오류 처리처럼 남겨두면 운영 중 불필요한 출력이 늘어날 수 있습니다. 수정 후에는 원래 오류가 나는 조건에서 결과를 다시 확인하고, 진단 코드가 없어도 해결되는지 점검해야 원인과 관찰 효과를 구분할 수 있습니다.
함수 경계에서 가설 확인하기
요청을 처리한 뒤 합계가 틀어진다면 로그로 같은 요청이 중복 처리됐는지부터 볼 수 있습니다. 처리 횟수가 맞다면 계산 함수의 입구와 반환 직전에서 멈춰 입력과 결과를 비교합니다. 반대로 입력은 같은데 특정 시점에만 결과가 달라지면 공유 상태나 실행 순서를 다음 가설로 삼을 수 있습니다. 이때 값이 다르다는 관찰과 경쟁 상태 때문이라는 해석을 따로 적어 두세요. 아직 확인하지 않은 원인을 로그 문구에 사실처럼 넣으면 이후 조사도 그 가설에 끌려갑니다. 필요한 증거를 하나씩 확보하고 반례가 나오면 다음 관찰 위치를 바꾸는 방식이 효율적입니다.