문제가 난 실행 파일과 같은 빌드인지 확인합니다
file ./program
readelf -h ./program
readelf -n ./program
readelf -S ./programELF Machine과 Class, Build ID, 디버그 섹션을 확인합니다. 소스가 같아 보여도 컴파일 옵션·링크·최적화가 달라지면 주소가 달라집니다. 현장 바이너리와 대응하는 unstripped 사본 또는 별도 디버그 파일을 보관해야 합니다. Build ID도 비교 단서이며 프로젝트가 어떤 방식으로 생성했는지 확인합니다.
파일 offset과 실행 주소를 섞지 않습니다
addr2line -e ./program -f -C -i 0x4011260x401126은 설명용 주소입니다. 자기 바이너리에서 확인한 주소로 바꿉니다. -e는 해석할 ELF, -f는 함수명, -C는 C++ 이름 해석, -i는 인라인 호출 정보 표시입니다. ??가 나오면 디버그 정보가 없거나 주소·파일이 맞지 않는지 확인합니다.
- 실행 중 주소어느 실행 파일·공유 라이브러리의 매핑인지 찾습니다.
- 로드 배치 확인PIE/공유 라이브러리는 ELF segment와 load bias를 맞춥니다.
- 디버그 정보 조회해당 빌드에서 함수와 소스 줄을 찾습니다.
상자는 변환 순서입니다. /proc/PID/maps의 첫 주소를 무조건 빼면 된다는 뜻은 아닙니다.
PIE와 공유 라이브러리는 ASLR로 적재 위치가 달라질 수 있습니다. 각 매핑의 파일 offset과 ELF PT_LOAD를 고려해야 합니다. 커널의 KASLR과 모듈의 재배치도 사용자 프로그램과 같은 주소를 쓰는 문제가 아닙니다. 가능하면 GDB에 정확한 실행 파일과 core를 함께 제공합니다.
추적 도구가 보여 주지 않는 것도 있습니다
cscope와 tags는 정적 소스 색인입니다. 함수 포인터, 전처리 조건, 런타임 등록으로 결정되는 실제 호출을 모두 알려 주지는 않습니다. 실행 경로는 로그·디버거·ftrace 등 대상에 맞는 관찰로 확인합니다.
libc 안에서 fault가 발생했다는 로그는 libc 자체가 원인이라는 뜻이 아닙니다. 호출자가 잘못된 포인터나 길이를 전달했거나 더 앞에서 메모리를 손상했을 수 있습니다. __builtin_return_address는 함수명이 아니라 반환 주소를 다루며 최적화와 아키텍처 제약이 있습니다.
디버깅을 위해 시스템 전체 ASLR을 영구히 끄기보다 GDB의 해당 inferior 설정을 확인합니다. strip 전에는 대응하는 디버그 파일을 보관합니다. 재배치에 필요한 심벌이 있는 오브젝트를 무조건 strip해도 안전하다고 가정하지 않습니다.