GDB로 안전하게 C++ 디버깅: 세그폴트 걱정 없이 단계별 분석
GDB를 사용하면 프로그램이 충돌하는 위치를 단 15~30초 만에 정확히 파악할 수 있습니다. 매번 printf 문을 넣고 재컴파일하는 번거로움 없이, 디버거를 통해 실시간으로 콜 스택과 변수 값을 확인하세요. 디버그 정보를 포함하려면 -g -O0 옵션을 사용해 컴파일하세요:
g++ -g -O0 -o myprogram myprogram.cpp
file myprogram 명령어로 디버그 정보가 포함되었는지 확인합니다. 디버깅을 시작하려면 gdb ./myprogram를 실행한 후 run 명령어를 입력하세요. 세그폴트 발생 시 GDB는 자동으로 멈추며, backtrace (bt) 명령어로 정확한 위치를 표시합니다.
this 포인터가 null인 상태에서 std::string::operator= 호출 시 충돌이 즉시 스택 트레이스에 나타납니다:
#0 0x... in std::string::operator= (this=0x0, ...)
#1 0x... in UserData::setName (...)
#2 0x... in main ()
읽기 쉬운 출력을 위해 다음 설정을 활성화하세요: set print pretty on 및 set print demangle on.
브레이크포인트와 코드 단계 실행
실행 흐름을 제어하기 위해 브레이크포인트를 설정하세요:
break main—main함수 시작 지점break program.cpp:42— 특정 줄에 설정break UserData::setName— 메서드 진입 시 중단info break— 모든 브레이크포인트 목록 보기
오버로딩된 C++ 함수의 경우 서명을 명시해야 합니다: break print(int) 또는 break print(std::string)입니다. 고급 옵션으로 rbreak ^.*::print$를 사용해 정규식으로 모든 print 메서드를 일괄 매칭할 수 있습니다.
코드를 탐색하는 명령어:
| 명령어 | 단축키 | 동작 |
|--------|--------|------|
| next | n | 함수 내부로 들어가지 않고 한 줄 실행 |
| step | s | 한 줄 실행하고 함수 내부로 진입 |
| finish | fin | 함수 종료까지 실행 |
| continue | c | 다음 브레이크포인트까지 계속 실행 |
C++에서는 STL 함수(예: push_back) 내부로 step하지 마세요. 대신 next를 사용해 라이브러리 내부 구현을 피하세요.
변수와 객체 검사
다음 명령어로 데이터를 확인하세요:
print variable_name— 변수 값 보기print *pointer— 포인터 역참조print vec.size()— 메서드 호출display variable_name— 각 단계 후 자동 표시info locals— 지역 변수 보기info args— 함수 인수 표시
GDB는 C++ 타입을 정확히 렌더링합니다:
print myVector
$1 = std::vector of length 5, capacity 8 = {1, 2, 3, 4, 5}
print myString
$2 = "Hello, World!"
만약 <optimized out>라는 메시지가 보이면, -O0 옵션으로 다시 컴파일하세요. -g 플래그 없이는 변수 이름이 표시되지 않습니다.
TUI 모드로 시각적 디버깅
tui enable을 활성화하면 화면이 분할됩니다: 상단은 현재 실행 중인 소스 코드(강조된 줄 포함), 하단은 명령어 입력 영역입니다. 다음과 같은 기능을 사용할 수 있습니다:
layout src— 소스 코드 보기layout asm— 어셈블리 보기layout split— 소스 + 어셈블리 병렬 보기layout regs— 레지스터 창Ctrl + X, 2— 두 개의 창 생성Ctrl + X, o— 창 전환Ctrl + X, a— TUI 모드 종료
TUI는 줄 번호에 의존하지 않고도 코드의 맥락을 직관적으로 제공하여 탐색을 간소화합니다.
흔한 문제와 해결법
| 문제 | 해결 방법 |
|------|----------|
| <optimized out> | -O0로 재컴파일 |
| 변수 이름 없음 | -g 플래그 사용 |
| 지역 변수 미표시 | 함수 내부에서 info locals 실행 |
| 벡터에 쓰레기 값 | 오래된 libstdc++에서는 print vec._M_impl._M_start 사용 |
중급 개발자를 위한 필수 명령어
90%의 디버깅 작업을 완벽히 처리할 수 있도록 이 10개의 명령어를 익히세요:
r— 실행b— 브레이크포인트 설정bt— 백트레이스n— 다음 줄 실행s— 단계 실행fin— 함수 종료까지 실행c— 계속 실행p— 값 출력i locals— 지역 변수 보기q— 종료
핵심 요약
- 콜 스택(
bt) 는 세그폴트의 70%를 몇 초 만에 해결하며,main까지의 전체 경로를 드러냅니다. - TUI 모드는 코드를 시각적으로 표현해 복잡한 프로젝트에서 인지 부담을 줄입니다.
-g -O0는 필수 조건입니다. 없으면 디버깅은 의미가 없습니다.nextvsstep는 STL을 사용하는 C++에서 매우 중요합니다. 라이브러리 내부 깊이 탐색을 피하세요.display와info locals/args는 코드에printf를 삽입하지 않고도 상태를 완전히 파악할 수 있게 해줍니다.
— Editorial Team
아직 댓글이 없습니다.