실행 파일과 소스가 같은 빌드인지 확인하기

디버거를 처음 붙였을 때 가장 먼저 확인할 것은 코드의 잘못된 줄이 아니라 지금 연 실행 파일입니다. 편집기에서 보고 있는 소스는 바뀌었는데 디버깅 대상은 어제 빌드한 파일일 수 있습니다. 특히 Debug와 Release 폴더를 따로 쓰거나 같은 이름의 실행 파일을 여러 폴더에 복사해 두면 혼동하기 쉽습니다. 빌드 명령이 성공했는지, 생성된 파일의 절대 경로가 무엇인지, 마지막 수정 시각이 예상과 맞는지부터 확인하세요. DBG Desk에서는 파일 선택 창이나 드래그 앤 드롭으로 파일을 열 수 있습니다. 의존 파일이 있으면 경로로 열기를 사용합니다. 소스와 실행 파일의 관계가 틀리면 이후에 보게 되는 줄 번호와 변수 값도 믿기 어렵습니다.

작은 예제로 연결부터 확인하기

첫 시도부터 복잡한 서비스에 연결하기보다는 프로젝트에 포함된 counter.c 같은 작은 프로그램을 사용하는 편이 원인을 좁히기 좋습니다. GCC에서는 gcc -g -O0 examples/counter.c -o examples/counter.exe처럼 디버그 정보를 넣고 최적화를 끈 빌드를 준비할 수 있습니다. 이 명령의 출력 경로는 명령을 실행한 폴더를 기준으로 합니다. 빌드가 끝나면 파일 열기에서 바이너리를 고르고 main 중단점 추가, 실행 순서로 진행합니다. 파일을 고르면 엔진 연결도 진행합니다. main에서 멈추면 브라우저와 로컬 서버, GDB, 대상 프로그램 사이의 기본 연결이 된 것입니다. 빌드 도구가 없다면 예제 컴파일과 디버거 연결 문제를 구분해 해결해야 합니다.

한 번에 하나씩 관찰하기

정지한 뒤에는 현재 명령어 주소와 호출 스택을 먼저 봅니다. F7은 명령어 하나를 실행하고, F8은 함수 호출을 넘겨 진행합니다. 여기서 말하는 한 단계는 소스 코드 한 줄과 다릅니다. 단순한 덧셈도 값을 읽고 계산하고 저장하는 여러 명령어로 나뉠 수 있습니다. 처음에는 레지스터가 바뀌는 시점과 프로그램 카운터가 이동하는 위치만 확인해도 충분합니다. 창마다 무엇을 뜻하는지 한꺼번에 이해하려고 하기보다 함수 진입, 계산, 반환이라는 작은 흐름을 따라가세요. 계산 결과가 예상과 다르면 직전 명령어가 어떤 값을 입력으로 받았는지 확인합니다.

다시 실행할 조건을 남기기

첫 세션이 끝나면 실행 파일 경로, 빌드 명령, 전달한 인수, 멈춘 함수와 관찰한 결과를 간단히 적습니다. 정상 예제의 결과를 알고 있어야 이후에 연결 오류와 프로그램 오류를 구별할 수 있습니다. counter 예제라면 최종 출력은 total = 35입니다. 인수가 필요한 프로그램은 같은 파일이라도 실행 조건에 따라 전혀 다른 경로를 지나므로 인수까지 함께 남기는 것이 중요합니다. 다음 세션에서는 동일한 조건으로 같은 중단점에 도달하는지부터 확인하세요. 프로세스가 아직 정지한 상태라면 다른 파일을 열기 전에 Detach로 연결을 정리합니다.

세션 기록 예시

첫 기록은 복잡할 필요가 없습니다. 빌드는 gcc -g -O0, 대상은 프로젝트의 counter.exe, 인수는 빈 배열, 첫 정지는 main이라고 적어 보세요. 그다음 accumulate에 중단점을 옮겼다면 어떤 반복에서 어떤 값을 확인했는지도 덧붙입니다. 동일한 파일을 다시 열었는데 이전과 다른 결과가 나오면 먼저 빌드와 인수를 비교할 수 있습니다. 기록에는 비밀번호나 개인 파일의 내용을 넣지 않고도 실행 조건을 설명할 수 있어야 합니다. 이 예제에서 첫 번째 호출의 입력은 0이고 계산 결과는 1이므로, 이 작은 기대값을 확인한 뒤 나머지 반복으로 진행하면 됩니다. 처음부터 모든 명령어를 해석하지 않아도 비교할 기준이 생깁니다.

빌드 명령
gcc -g -O0 examples/counter.c -o examples/counter.exe