명령어가 있다는 것과 이름을 안다는 것은 다르다
디스어셈블리에는 명령어가 나오는데 호출 스택의 함수명이 물음표로 보이는 경우가 있습니다. 실행 파일의 기계어는 읽을 수 있지만 그 주소를 소스의 함수와 연결할 정보가 부족한 상황일 수 있습니다. 디버그 정보는 함수명, 변수, 타입, 줄 번호 같은 관계를 설명하는 자료입니다. 실행에 필요한 코드와 목적이 다르므로 프로그램이 정상적으로 실행되더라도 풍부한 디버깅 정보가 없을 수 있습니다. 먼저 모든 함수 이름이 없는지, 특정 외부 모듈만 없는지 구분하세요. 이름이 없는 프레임이 있다는 이유만으로 프로그램의 스택이 손상됐다고 판단하면 안 됩니다.
빌드한 파일과 심볼의 짝 맞추기
디버그 정보를 준비할 때는 같은 이름의 파일인지보다 같은 빌드에서 나온 파일인지가 중요합니다. 소스를 조금 바꿔 다시 빌드하면 함수의 주소와 배치가 달라질 수 있습니다. 이전 실행 파일의 심볼이나 다른 구성의 자료를 가져오면 그럴듯한 이름과 줄이 보여도 실제와 맞지 않을 수 있습니다. 프로젝트의 실행 파일 경로, 컴파일 옵션, 빌드 시각과 식별 정보를 함께 확인하세요. GCC를 사용하는 예제는 -g로 정보를 생성하고 배포 과정에서 제거되지 않았는지 확인합니다. 별도 파일로 관리하는 경우에는 디버거가 그 위치를 찾을 수 있는지도 별도로 확인해야 합니다.
디버거마다 지원 형식이 다르다
Windows에서 흔한 PDB 파일이 있다고 해서 모든 GDB 환경이 그 정보를 같은 수준으로 사용할 수 있는 것은 아닙니다. 실행 파일 형식, 디버그 정보 형식, 사용한 도구 조합을 맞춰 봐야 합니다. DBG Desk는 현재 GDB의 응답을 표시하는 구조이며 PDB 변환이나 별도 심볼 서버 관리 기능을 제공하지 않습니다. MinGW-w64로 만든 작은 예제가 잘 보이는데 다른 빌드의 프로그램에서 이름이 빠진다면 연결 자체보다 심볼 호환성을 먼저 조사할 수 있습니다. MSVC 중심 프로그램에서는 해당 형식에 맞는 디버거가 더 적합할 수 있다는 점도 도구 선택에 포함해야 합니다.
심볼이 없어도 남는 관찰 자료
심볼이 없어도 현재 명령어, 레지스터, 접근한 메모리와 일부 호출 경로를 관찰할 수 있습니다. 다만 소스 변수 이름이나 정확한 줄 번호를 기대해서는 안 됩니다. 주소 중단점을 쓸 때는 현재 실행에서 확인한 주소인지 점검하고 실행을 다시 시작했을 때의 변화도 고려하세요. 이름을 추측해서 결론을 내리기보다 함수 진입과 반환, 메모리를 읽고 쓰는 위치처럼 확인 가능한 사실부터 기록합니다. 자신의 프로그램이라면 심볼이 있는 빌드로 같은 입력을 재현하는 것이 가장 빠른 해결책일 수 있습니다. 빌드를 바꾸면 재현이 사라지는지도 함께 확인해야 합니다.
파일 경로를 나란히 확인하기
편집기의 프로젝트 폴더와 디버거에 연 파일 폴더를 나란히 적어 보면 오래된 복사본을 조사하는 상황을 발견하기 쉽습니다. 예를 들어 build 폴더에서 새 파일을 만들었는데 desktop 폴더의 이전 파일을 열었다면 새 심볼이 있어도 현재 프로세스와 맞지 않습니다. 경로를 바로잡은 뒤 함수명 중단점이 잡히고 줄 번호가 예상과 맞는지 확인하세요. 외부 라이브러리만 이름이 빠진다면 자신의 실행 파일을 계속 다시 빌드하기보다 그 모듈의 정보를 별도로 조사합니다. 무엇이 빠졌는지 범위를 나눠 기록하면 필요한 자료를 요청할 때도 실행 파일 전체가 문제라는 모호한 설명을 피할 수 있습니다.