홈으로 돌아가기

GDB C++ 디버깅: segfault를 분 단위로 찾기

C++ 개발자를 위한 GDB 가이드: segfault 찾기, 중단점 설정, 변수 보기 및 TUI 모드에 초점. 실제 크래시 예제와 재컴파일 없이 코드 탐색 기반.

C++에서의 GDB: segfault부터 빠른 디버깅까지
Advertisement 728x90

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= 호출 시 충돌이 즉시 스택 트레이스에 나타납니다:

Google AdInline article slot
#0 0x... in std::string::operator= (this=0x0, ...)
#1 0x... in UserData::setName (...)
#2 0x... in main ()

읽기 쉬운 출력을 위해 다음 설정을 활성화하세요: set print pretty onset print demangle on.

브레이크포인트와 코드 단계 실행

실행 흐름을 제어하기 위해 브레이크포인트를 설정하세요:

  • break mainmain 함수 시작 지점
  • break program.cpp:42 — 특정 줄에 설정
  • break UserData::setName — 메서드 진입 시 중단
  • info break — 모든 브레이크포인트 목록 보기

오버로딩된 C++ 함수의 경우 서명을 명시해야 합니다: break print(int) 또는 break print(std::string)입니다. 고급 옵션으로 rbreak ^.*::print$를 사용해 정규식으로 모든 print 메서드를 일괄 매칭할 수 있습니다.

Google AdInline article slot

코드를 탐색하는 명령어:

| 명령어 | 단축키 | 동작 |

|--------|--------|------|

Google AdInline article slot

| 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 는 필수 조건입니다. 없으면 디버깅은 의미가 없습니다.
  • next vs step 는 STL을 사용하는 C++에서 매우 중요합니다. 라이브러리 내부 깊이 탐색을 피하세요.
  • displayinfo locals/args 는 코드에 printf를 삽입하지 않고도 상태를 완전히 파악할 수 있게 해줍니다.

— Editorial Team

Advertisement 728x90

다음 읽기