GNU 디버거 GDB 완전 정복 2026: 프로그램 디버깅의 모든 것
- IT
- 2026. 2. 3.
🐛 프로그램이 갑자기 죽어버렸는데 원인을 찾을 수 없다고요? GDB(GNU Debugger)를 마스터하면 어떤 버그든 추적할 수 있어요!
프로그래밍을 하다 보면 가장 답답한 순간이 바로 **"왜 프로그램이 죽었지?"**하는 상황입니다. 세그멘테이션 폴트, 무한 루프, 메모리 누수... 이런 문제들을 해결하기 위해서는 강력한 디버깅 도구가 필요하죠.
- *GDB(GNU Debugger)**는 리눅스와 유닉스 계열 시스템에서 가장 널리 사용되는 디버거로, C, C++, Go, Rust 등 다양한 언어를 지원합니다. 단순히 에러를 찾는 것을 넘어서, 프로그램의 내부 동작을 완전히 들여다볼 수 있는 강력한 도구입니다.
🎯 GDB란 무엇인가? 디버깅의 핵심 도구
GDB의 정의와 역할
- *GDB(GNU Debugger)**는 GNU 프로젝트의 일부로 개발된 명령행 기반 디버거입니다. 프로그램이 실행되는 동안 내부 상태를 관찰하고, 실행을 제어할 수 있게 해주는 필수 개발 도구예요.
GDB가 할 수 있는 일들
- 프로그램 실행 제어: 중단점 설정, 단계별 실행
- 변수 값 검사: 메모리 내용 실시간 확인
- 스택 추적: 함수 호출 경로 분석
- 메모리 분석: 포인터, 배열, 구조체 내용 확인
- 코어 덤프 분석: 프로그램 크래시 원인 파악
다른 디버거와의 차이점
특징 GDB Visual Studio Debugger LLDB

| 플랫폼 | 리눅스/유닉스 중심 | 윈도우 중심 | macOS/LLVM 중심 |
| GUI | 명령행 기반 | GUI 기반 | 명령행 기반 |
| 지원 언어 | C/C++/Go/Rust 등 | 다양한 .NET 언어 | C/C++/Swift 등 |
| 학습 곡선 | 가파름 | 완만함 | 중간 |
🚀 GDB 설치 및 기본 설정
리눅스 배포판별 설치 방법
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install gdb
# CentOS/RHEL/Fedora
sudo yum install gdb
# 또는 최신 버전
sudo dnf install gdb
# Arch Linux
sudo pacman -S gdb
컴파일 시 디버그 정보 포함하기
GDB를 효과적으로 사용하려면 디버그 심볼이 포함된 실행 파일이 필요합니다:
# 디버그 정보 포함해서 컴파일
gcc -g -o program program.c
# 최적화 없이 디버그 정보 포함 (권장)
gcc -g -O0 -o program program.c
# 더 많은 디버그 정보 포함
gcc -g3 -O0 -o program program.c
디버그 플래그 설명
- g: 기본 디버그 정보 포함
- g3: 매크로 정보까지 포함하는 상세한 디버그 정보
- O0: 최적화 비활성화 (디버깅 시 변수 추적 용이)
🔧 GDB 기본 사용법 마스터하기
GDB 시작하는 3가지 방법
1. 프로그램 직접 실행
# 기본 실행
gdb ./program
# 명령행 인수와 함께 실행
gdb --args ./program arg1 arg2 arg3
2. 실행 중인 프로세스에 연결
# 프로세스 ID로 연결
gdb -p 12345
# 프로세스 이름으로 찾아서 연결
gdb -p $(pgrep program_name)
실무 활용 예시:
# 웹서버가 멈춰있을 때 디버깅
ps aux | grep nginx
gdb -p 1234 # nginx 프로세스 ID
3. 코어 덤프 파일 분석
# 코어 덤프 분석
gdb ./program ./core
# 특정 경로의 코어 파일 분석
gdb ./program /var/crash/core.12345
핵심 GDB 명령어 완전 정복
프로그램 실행 제어
# GDB 내에서 프로그램 시작
(gdb) run
(gdb) run arg1 arg2 # 인수와 함께 실행
# 프로그램 종료
(gdb) quit
(gdb) q
# 현재 실행 중단
Ctrl+C
중단점(Breakpoint) 활용하기
# 함수에 중단점 설정
(gdb) break main
(gdb) break my_function
(gdb) b main # 축약형
# 특정 줄에 중단점 설정
(gdb) break program.c:25
(gdb) b program.c:25
# 조건부 중단점
(gdb) break main if argc > 1
(gdb) break program.c:30 if x == 10
# 중단점 목록 확인
(gdb) info breakpoints
(gdb) i b
# 중단점 삭제
(gdb) delete 1 # 번호로 삭제
(gdb) delete # 모든 중단점 삭제
(gdb) clear main # 함수의 중단점 삭제
단계별 실행
# 한 줄씩 실행 (함수 안으로 들어감)
(gdb) step
(gdb) s
# 한 줄씩 실행 (함수 호출은 건너뜀)
(gdb) next
(gdb) n
# 현재 함수에서 나올 때까지 실행
(gdb) finish
# 계속 실행
(gdb) continue
(gdb) c
🔍 변수와 메모리 검사의 달인 되기
변수 값 확인하기
# 변수 값 출력
(gdb) print variable_name
(gdb) p variable_name
# 다양한 형식으로 출력
(gdb) print/x variable_name # 16진수
(gdb) print/d variable_name # 10진수
(gdb) print/t variable_name # 2진수
(gdb) print/c variable_name # 문자
(gdb) print/s string_ptr # 문자열
# 포인터가 가리키는 값
(gdb) print *pointer
(gdb) print pointer[0] # 배열 첫 번째 요소
(gdb) print pointer[0]@10 # 배열 10개 요소
메모리 내용 직접 보기
# 메모리 덤프 (examine)
(gdb) x/10wx 0x12345678 # 10개 워드를 16진수로
(gdb) x/20cb string_address # 20개 바이트를 문자로
(gdb) x/5i $pc # 현재 위치부터 5개 명령어
# 형식 지정자
# - 개수: 출력할 유닛 수
# - 크기: b(바이트), h(하프워드), w(워드), g(거대워드)
# - 형식: x(16진수), d(10진수), u(부호없는 10진수), t(2진수), c(문자), s(문자열), i(명령어)
구조체와 배열 분석
# 구조체 멤버 접근
(gdb) print struct_var.member
(gdb) print struct_ptr->member
# 배열 전체 출력
(gdb) print array
(gdb) print array@length # 특정 길이만 출력
# 구조체 타입 정보 확인
(gdb) ptype struct_name
(gdb) whatis variable_name
📚 스택 추적과 함수 호출 분석
백트레이스(Backtrace) 활용하기
# 현재 스택 추적
(gdb) backtrace
(gdb) bt
# 상세한 스택 추적
(gdb) backtrace full
(gdb) bt full
# 특정 개수만 출력
(gdb) bt 5 # 상위 5개 프레임
(gdb) bt -5 # 하위 5개 프레임
스택 프레임 간 이동
# 스택 프레임 정보
(gdb) info frame
(gdb) i f
# 특정 프레임으로 이동
(gdb) frame 2
(gdb) f 2
# 상위/하위 프레임으로 이동
(gdb) up # 호출한 함수로
(gdb) down # 호출된 함수로
# 각 프레임의 지역 변수 확인
(gdb) info locals
(gdb) i locals
🐛 실전 디버깅 시나리오
시나리오 1: 세그멘테이션 폴트 해결
문제 상황: 프로그램이 갑자기 죽으면서 "Segmentation fault (core dumped)" 메시지 출력
# 1. 코어 덤프 활성화
ulimit -c unlimited
# 2. 프로그램 실행 후 크래시
./program
# Segmentation fault (core dumped)
# 3. GDB로 코어 덤프 분석
gdb ./program ./core
# 4. 크래시 지점 확인
(gdb) bt
(gdb) list
# 5. 변수 상태 확인
(gdb) print pointer
(gdb) x/10wx pointer
일반적인 세그폴트 원인들:
- 널 포인터 역참조
- 초기화되지 않은 포인터 사용
- 배열 경계 초과
- 해제된 메모리 접근
시나리오 2: 무한 루프 디버깅
# 1. 실행 중인 프로그램에 연결
gdb -p $(pgrep my_program)
# 2. 현재 실행 위치 확인
(gdb) bt
(gdb) list
# 3. 루프 변수 확인
(gdb) print loop_counter
(gdb) print condition_variable
# 4. 몇 번의 반복 후 상태 재확인
(gdb) continue
# Ctrl+C로 중단
(gdb) print loop_counter
시나리오 3: 메모리 누수 추적
# Valgrind와 GDB 조합 사용
valgrind --tool=memcheck --leak-check=full --db-attach=yes ./program
# GDB에서 메모리 할당 추적
(gdb) break malloc
(gdb) break free
(gdb) commands 1
>bt
>continue
>end
🚀 고급 GDB 기능 활용하기
감시점(Watchpoint) 설정
# 변수 값이 변경될 때 중단
(gdb) watch variable_name
# 메모리 주소가 변경될 때 중단
(gdb) watch *0x12345678
# 읽기 접근 시 중단
(gdb) rwatch variable_name
# 읽기/쓰기 접근 시 중단
(gdb) awatch variable_name
# 감시점 목록 확인
(gdb) info watchpoints
매크로와 사용자 정의 함수
# .gdbinit 파일에 사용자 정의 명령어 작성
define print_array
set $i = 0
while $i < $argc
print $arg0[$i]
set $i = $i + 1
end
end
# 사용 예
(gdb) print_array my_array 10
멀티스레드 프로그램 디버깅
# 스레드 목록 확인
(gdb) info threads
# 특정 스레드로 전환
(gdb) thread 2
# 모든 스레드의 백트레이스
(gdb) thread apply all bt
# 스레드별 중단점 설정
(gdb) break function_name thread 2
🔬 코어 덤프 분석 마스터 클래스
코어 덤프 생성 설정
# 코어 덤프 크기 제한 해제
ulimit -c unlimited
# 시스템 전체 설정 (/etc/security/limits.conf)
* soft core unlimited
* hard core unlimited
# 코어 덤프 파일 위치 설정
echo '/tmp/core.%e.%p' > /proc/sys/kernel/core_pattern
코어 덤프 분석 단계
# 1. GDB로 코어 덤프 열기
gdb ./program ./core.program.12345
# 2. 크래시 지점 확인
(gdb) bt
(gdb) list
# 3. 크래시 당시 변수 상태
(gdb) info registers
(gdb) print variable
# 4. 메모리 상태 확인
(gdb) x/20wx $rsp # 스택 메모리
(gdb) x/20wx $rip # 명령어 메모리
# 5. 전역 변수 상태
(gdb) print global_var
자동 코어 덤프 분석 스크립트
#!/bin/bash
# analyze_core.sh
PROGRAM=$1
COREFILE=$2
gdb -batch -ex "bt" -ex "info registers" -ex "quit" $PROGRAM $COREFILE
🛠️ GDB 환경 최적화 및 설정
.gdbinit 파일 설정
홈 디렉터리에 .gdbinit 파일을 만들어 GDB를 커스터마이징할 수 있어요:
# ~/.gdbinit
set print pretty on # 구조체 이쁘게 출력
set print array on # 배열 전체 출력
set print array-indexes on # 배열 인덱스 표시
set pagination off # 페이지 넘김 비활성화
set confirm off # 확인 메시지 비활성화
# 히스토리 설정
set history save on
set history size 10000
set history filename ~/.gdb_history
# TUI 모드 기본 설정
layout src # 소스 코드 표시
focus cmd # 명령창에 포커스
# 사용자 정의 명령어
define cls
shell clear
end
TUI(Text User Interface) 모드 활용
# TUI 모드로 GDB 시작
gdb -tui ./program
# GDB 내에서 TUI 모드 전환
(gdb) tui enable
(gdb) tui disable
# 레이아웃 변경
(gdb) layout src # 소스 코드 창
(gdb) layout asm # 어셈블리 창
(gdb) layout split # 소스 + 어셈블리
(gdb) layout regs # 레지스터 창
# 창 간 포커스 이동
Ctrl+X+A # 액티브 창 전환
Ctrl+X+O # 다음 창으로
📱 원격 디버깅과 임베디드 시스템
GDB 서버 사용하기
# 타겟 시스템에서 gdbserver 실행
gdbserver :1234 ./program
# 호스트에서 원격 연결
gdb ./program
(gdb) target remote target_ip:1234
(gdb) continue
크로스 컴파일 환경에서의 디버깅
# ARM용 GDB 사용
arm-linux-gnueabi-gdb ./program
# 원격 타겟에 연결
(gdb) target remote 192.168.1.100:1234
🔧 실무에서 자주 사용하는 GDB 패턴
디버깅 체크리스트
프로그램 크래시 시:
- 코어 덤프 확인 → gdb program core
- 백트레이스 분석 → bt full
- 크래시 지점 변수 확인 → print var
- 메모리 상태 검사 → x/20wx address
- 함수 인수 확인 → info args
성능 문제 디버깅:
- 함수 프로파일링 → 중단점으로 호출 빈도 확인
- 메모리 사용량 추적 → 힙 할당 모니터링
- 무한 루프 탐지 → 실행 중 강제 중단 후 분석
자주 사용하는 명령어 조합
# 함수 진입 시 자동으로 변수 출력
(gdb) break function_name
(gdb) commands
>print important_var
>continue
>end
# 조건부 중단점으로 특정 상황만 캐치
(gdb) break main
(gdb) condition 1 argc > 2
# 스택 오버플로우 감지
(gdb) watch $sp
⚡ GDB 성능 최적화 팁
디버깅 속도 향상
- 심볼 테이블 최적화
# 디버그 정보만 별도 파일로 분리
objcopy --only-keep-debug program program.debug
strip --strip-debug program
objcopy --add-gnu-debuglink=program.debug program
- 선택적 중단점 사용
# 조건부 중단점으로 불필요한 중단 방지
(gdb) break expensive_function if error_condition == 1
- 배치 모드 활용
# 스크립트로 자동 분석
gdb -batch -ex "run" -ex "bt" -ex "quit" ./program
🚨 GDB 사용 시 주의사항과 한계
주의해야 할 상황들
1. 최적화된 바이너리 디버깅
- O2, O3 옵션으로 컴파일된 프로그램은 변수가 최적화되어 추적이 어려움
- 디버깅 시에는 O0 사용 권장
2. 멀티스레드 프로그램
- 스레드 간 경쟁 상태는 디버거 연결로 타이밍이 변경될 수 있음
- Heisenbug(관찰하면 사라지는 버그) 주의
3. 시스템 리소스 사용
- GDB는 상당한 메모리를 사용하므로 메모리 부족 시스템에서 주의
- 실시간 시스템에서는 성능 영향 고려 필요
GDB의 한계점
한계 설명 대안
| GUI 부재 | 명령행 기반으로 직관성 부족 | DDD, Eclipse CDT, VS Code 연동 |
| 학습 곡선 | 복잡한 명령어 체계 | 자주 사용하는 명령어부터 습득 |
| 최적화 코드 | 컴파일러 최적화로 디버깅 어려움 | 디버그 빌드 별도 유지 |
| 실시간 제약 | 실시간 시스템에는 부적합 | 로그 기반 디버깅 병행 |
🔮 디버깅의 미래와 GDB의 발전
현대적 디버깅 트렌드
1. IDE 통합
- VS Code, CLion 등에서 GDB를 백엔드로 사용하는 그래픽 인터페이스
- 원클릭 디버깅과 시각적 변수 탐색
2. 클라우드 디버깅
- 원격 서버에서 실행되는 애플리케이션을 로컬에서 디버깅
- 컨테이너 환경에서의 디버깅 지원 강화
3. AI 기반 버그 탐지
- 자동 버그 패턴 인식
- 스마트한 중단점 추천
GDB의 지속적인 발전
- Python 스크립팅 지원 확대
- DWARF 5 디버그 정보 형식 지원
- 리버스 디버깅 기능 개선
- GPU 디버깅 지원 추가
🔄 마무리: GDB 마스터의 핵심 원칙
GNU 디버거 GDB를 완전히 마스터하기 위한 핵심 포인트:
- 기본기가 전부 → print, break, backtrace 완전 숙달
- 실습이 답 → 실제 버그가 있는 프로그램으로 연습
- 자동화 활용 → .gdbinit과 스크립트로 효율성 증대
- 다른 도구와 연계 → Valgrind, strace 등과 조합 사용
디버깅은 단순히 버그를 찾는 것이 아니라, 프로그램의 동작 원리를 깊이 이해하는 과정입니다. GDB를 통해 여러분의 프로그래밍 실력이 한 단계 더 성장할 수 있을 거예요!
처음에는 복잡해 보이지만, 꾸준히 사용하다 보면 GDB 없이는 개발할 수 없을 만큼 강력한 도구라는 것을 깨닫게 될 겁니다.
💬 여러분의 디버깅 경험은 어떠신가요? GDB로 해결한 인상 깊은 버그가 있다면 댓글로 공유해 주세요!
🔗 관련 글 더 보기: