GDB·LLDB 기본 명령 — break·step·next·print 동작 비교
#매일 쓰는 명령 10가지
Ch 1에서 첫 세션을 봤습니다. 이 장은 그 안에서 본 명령들을 정확히 다룹니다.
| 명령 | 약어 | 의미 |
|---|---|---|
run | r | 프로그램 실행 |
continue | c | 정지 상태에서 계속 |
break | b | 중단점 설정 |
next | n | 다음 줄로 (함수 안 안 들어감) |
step | s | 다음 줄로 (함수 안으로 진입) |
finish | fin | 현재 함수 끝까지 실행 |
print | p | 변수·식 값 출력 |
info | — | 정보 조회 |
list | l | 소스 코드 표시 |
quit | q | 디버거 종료 |
이 10개를 외우면 *디버거 사용 90%*가 끝납니다.
#run / continue — 시작과 진행
(gdb) run # 인자 없이 실행(gdb) run input.txt --verbose(gdb) r # 약어
(gdb) continue # Breakpoint나 signal로 멈춘 자리에서 다시 실행(gdb) crun은 처음부터, continue는 멈춘 자리부터. continue N으로 N번 무시하고 진행 가능.
LLDB:
(lldb) run input.txt --verbose(lldb) continue#break — 멈출 자리 설정
가장 많이 쓰는 명령. 다양한 형태가 있습니다.
#함수 이름
(gdb) break main # main 함수 시작에서 멈춤(gdb) b main # 약어(gdb) b MyClass::method # C++ 메서드(gdb) b 'MyClass<int>::foo' # 템플릿 함수LLDB:
(lldb) breakpoint set --name main(lldb) b main # alias#파일과 줄 번호
(gdb) break main.c:42 # main.c의 42번째 줄(gdb) b parser.c:128LLDB:
(lldb) breakpoint set --file main.c --line 42(lldb) b main.c:42#조건부
(gdb) break main.c:42 if x > 10(gdb) b factorial if n == 0(gdb) b parser.c:50 if strcmp(buf, "ERROR") == 0x > 10이 참일 때만 멈춤. 깊은 루프 안의 특정 상황만 잡을 때 필수. 문자열 비교도 가능.
#일회성 (Temporary)
(gdb) tbreak main # 한 번 멈추면 자동 삭제LLDB:
(lldb) breakpoint set --one-shot --name main#모든 함수에 자동
(gdb) rbreak factorial.* # 정규식 매칭 모든 함수에 break큰 코드베이스 탐색용.
#Breakpoint 관리
(gdb) info breakpoints # 목록(gdb) i b # 약어(gdb) delete 1 # 1번 삭제(gdb) clear main.c:42 # 특정 자리 삭제(gdb) disable 1 # 비활성화 (안 삭제)(gdb) enable 1LLDB:
(lldb) breakpoint list(lldb) breakpoint delete 1(lldb) breakpoint disable 1(lldb) breakpoint enable 1#step vs next vs finish — 진행 명령
가장 헷갈리는 셋. 정확한 차이를 알아 둡니다.
int add(int a, int b) { return a + b; // ← 4}
int main() { int x = 1; // ← 1 int y = 2; // ← 2 int z = add(x, y); // ← 3 return z; // ← 5}위치 3에서:
| 명령 | 3 → ? |
|---|---|
next | 5 (add() 안 안 들어감, 다음 줄) |
step | 4 (add() 안으로 진입) |
위치 4에서:
| 명령 | 4 → ? |
|---|---|
next | 5 (return 후 main으로) |
finish | 5 (현재 함수 끝까지) |
요약:
next— 한 줄. 함수 호출은 통째로 실행.step— 한 줄. 함수 호출은 안으로 진입.finish— 현재 함수가 반환할 때까지 실행.
finish는 너무 깊이 들어갔을 때 빠져나오는 단축키. step을 잘못 눌러 깊은 라이브러리 안으로 들어갔을 때 finish로 탈출.
#명령어 단위 진행
(gdb) stepi # 어셈블리 한 명령씩 진입(gdb) si(gdb) nexti # 어셈블리 한 명령 (call은 통째)(gdb) niC/C++ 줄이 아니라 기계어 한 줄씩. 최적화된 코드나 디스어셈블리를 따라가야 할 때.
#until — 같은 위치 반복 무시
(gdb) until 50 # 50번 줄까지 같은 자리에 안 멈춤루프 안의 break가 매번 멈추는 게 싫을 때. 50번 줄까지 통과해 진행.
#print — 변수·식 평가
#기본
(gdb) print x$1 = 42
(gdb) p x # 약어(gdb) print x + y$2 = 100C/C++ 식 전부가 평가 가능. 함수 호출도 됩니다 (side effect 주의).
(gdb) print strlen(str)$3 = 13#$N 변수
$1, $2처럼 결과가 자동 번호됩니다. 이후 참조 가능.
(gdb) print my_struct$1 = {field1 = 10, field2 = 20}(gdb) print $1.field1 # 이전 결과 재사용$2 = 10#포맷 지정자
(gdb) p/x x # 16진수(gdb) p/d x # 10진수 (기본)(gdb) p/o x # 8진수(gdb) p/t x # 2진수(gdb) p/c x # 문자(gdb) p/s str # 문자열(gdb) p/f x # 정수 메모리를 float으로LLDB:
(lldb) print x(lldb) p/x x # 16진수(lldb) print --format hex x#배열·메모리
(gdb) print *arr@10 # arr의 10개 원소 (배열로 출력)(gdb) p *(int*)0x7fff1234@5 # 주소에서 5개 int#포인터 따라가기
(gdb) p *ptr # 포인터가 가리키는 곳(gdb) p ptr->field # 구조체 멤버(gdb) p *node->next # 체이닝#set var — 변수 수정
(gdb) set variable x = 100(gdb) set var x = 100 # 약어print x = 100도 동일 효과. 가설 검증에서 필수.
if (x > 0) { // 이 분기를 강제로 들어가고 싶음}(gdb) set var x = 1로 조건 자체를 바꿔 다른 분기 검증.
#display — 자동 출력
(gdb) display x1: x = 5
(gdb) next61: x = 6 # 자동으로 출력매 step마다 자동으로 x값을 보여 줌. 변수 변화를 연속 추적.
(gdb) info display # 등록된 목록(gdb) undisplay 1 # 삭제#info — 정보 조회
info는 서브 명령이 많습니다.
(gdb) info breakpoints # 또는 i b(gdb) info args # 현재 함수의 인자(gdb) info locals # 현재 함수의 지역 변수(gdb) info registers # 모든 레지스터(gdb) info threads # 모든 스레드(gdb) info frame # 현재 프레임 정보(gdb) info functions # 모든 함수(gdb) info variables # 전역 변수(gdb) info sharedlibrary # 로드된 동적 라이브러리LLDB:
(lldb) breakpoint list # = info breakpoints(lldb) frame variable # = info locals + info args(lldb) register read # = info registers(lldb) thread list # = info threads(lldb) image list # = info sharedlibrary가장 자주 쓰는 info locals — 함수 안에서 모든 지역 변수를 한 번에 봅니다. print를 일일이 안 해도 됨.
#list — 소스 코드 보기
(gdb) list # 현재 자리 ± 5줄(gdb) l
(gdb) list 1,20 # 1~20번 줄(gdb) list main # main 함수(gdb) list main.c:42 # 특정 자리(gdb) list # 다시 누르면 다음 10줄LLDB:
(lldb) source list(lldb) l --line 42 --count 20list는 깜빡할 때마다 한 번씩 누르면 됩니다. 현재 위치의 컨텍스트를 즉시 보여 줌.
#jump / return — 흐름 제어
#jump — 실행 위치 강제 변경
(gdb) jump 42 # 42번 줄로 점프위험. 변수 상태가 안 맞으면 죽음. 디버깅 가설 검증에 가끔 사용.
#return — 함수 조기 종료
(gdb) return 0 # 0을 반환하고 함수 즉시 종료함수의 나머지를 실행하지 않고 반환. fault injection이나 분기 검증에 유용.
#quit — 종료
(gdb) quitA debugging session is active....Quit anyway? (y or n) yq로 약어. 디버깅 중인 프로세스가 있으면 확인.
-q 옵션으로 시작하면 시작 메시지 안 나옴 — 깔끔한 출력.
#모르는 명령일 때 — help
(gdb) help(gdb) help break # 'break' 명령 상세(gdb) help info breakpointsLLDB:
(lldb) help(lldb) help breakpoint set(lldb) apropos crash # crash 관련 명령 검색apropos로 키워드 검색.
#.gdbinit / ~/.lldbinit — 초기 설정
매번 같은 설정을 안 치도록 시작 스크립트에 저장.
#.gdbinit
# 출력 페이지네이션 끄기 (긴 출력 자동 스크롤)set pagination off
# 자식 프로세스 따라가기 (멀티프로세스용)set follow-fork-mode child
# 어셈블리 신택스set disassembly-flavor intel
# 자동 명령define hookpost-run info threadsend프로젝트별 .gdbinit는 해당 디렉터리에 두면 자동 로드 (auto-load safe-path 설정 필요).
#~/.lldbinit
settings set target.x86-disassembly-flavor intelsettings set stop-disassembly-display alwayscommand alias bfl breakpoint set --file %1 --line %2Ch 11: 실무 팁에서 자세히.
#작은 cheatsheet
| 동작 | 명령 |
|---|---|
| 시작 | gdb prog / lldb prog |
| 실행 | run |
| 멈출 자리 | break <위치> |
| 한 줄 (함수 안 안 들어감) | next |
| 한 줄 (함수 안으로) | step |
| 함수 끝까지 | finish |
| 계속 | continue |
| 변수 보기 | print <식> |
| 지역 변수 모두 | info locals |
| 호출 사슬 | backtrace |
| 소스 보기 | list |
| 변수 수정 | set var x = 100 |
| 자동 출력 | display <식> |
| 종료 | quit |
#정리
- 매일 쓰는 10명령:
run/continue/break/next/step/finish/print/info/list/quit. break는 위치·조건·일회성 등 다양한 변형.stepvsnext차이는 함수 호출 시 안으로 들어가느냐.finish로 빠져나옴.print는 C/C++ 식 평가기. 함수 호출까지 가능.info,list,display로 상태 추적..gdbinit로 시작 설정 자동화.
#다음 장 예고
Ch 3: 상태 들여다보기에서는 변수 깊이 보기 — 메모리, 레지스터, STL 컨테이너, 포인터 트리.
#참고 자료
GDB and LLDB · 2 of 12
- 1GDB vs LLDB 분석 — 두 디버거의 설치·차이·선택 기준
- 2GDB·LLDB 기본 명령 — break·step·next·print 동작 비교
- 3디버거로 상태 들여다보기 — 변수·메모리·레지스터·STL 추적
- 4GDB·LLDB Backtrace와 프레임 이동 — Call Stack 분석
- 5Breakpoint와 Watchpoint 분석 — Conditional·Hardware·Catchpoint
- 6멀티스레드·멀티프로세스 디버깅 — Non-Stop·Scheduler-Locking·Fork
- 7Core Dump 분석 기법 — gcore·coredumpctl·디버거 활용
- 8GDB 원격 디버깅 — gdbserver·OpenOCD·J-Link 통합
- 9GDB·LLDB Python 스크립팅 — Pretty-Printer·Custom Command
- 10GDB·LLDB TUI와 프런트엔드 — gdb-dashboard·gef·pwndbg·VS Code
- 11GDB·LLDB 실전 팁 — STL·최적화 코드·시간 역행 디버깅
- 12DWARF 디버그 정보 — 디버거가 변수와 라인을 찾는 방식
관련 글
DWARF 디버그 정보 — 디버거가 변수와 라인을 찾는 방식
DWARF 표준, DIE / abbrev / line / location, expression VM, CFI, split-DWARF.
GDB·LLDB Python 스크립팅 — Pretty-Printer·Custom Command
GDB / LLDB Python API. pretty-printer 작성, 커스텀 명령, 자동화, MI.
Breakpoint와 Watchpoint 분석 — Conditional·Hardware·Catchpoint
조건부 break, watchpoint(변수 변경 추적), catchpoint, hardware vs software.