개요

GDB는 GNU프로젝트의 일환으로 소스코드를 Debugging에 사용되는 Tool이다.

기본 명령어

시작과 종료
  • gdb [프로그램명] : 시작
  • q(quit) or ctrl+d : 종료
브레이크 포인트
  • b func, line, *0x1234 : func 함수의 시작부분에 브레이크, line행에 브레이크, 특정 주소에 브레이크
  • tb : b와 같으나 1회용 브레이크 포인트. 문법은 b와 동일
  • info b : 현재 브레이크 포인트 보기
  • cl : 브레이크 포인트 지우기
  • d : 모든 브레이크 포인트 지우기
  • c(continue) : 다음 브레이크 포인트까지 진행
  • watch [변수명] : 특정변수에 와치 포인트를 설정하고, 특정변수가 바뀔 때마다 브레이크가 걸리면서 이전/현재 값을 출력한다
  • rwatch [변수명] : Watch는 write가 일어날때만 break가 걸리지만, rwatch는 read가 일어날때만 break가 걸린다.
  • awatch [변수명] : watch + rwatch로, read/write가 일어날때 break가 걸린다.
watch혹은 break는 조건문을 받아서, 특정 조건에서 break를 걸수 있다.
watch malloc.c:123 if return_addr == 0x1010 (malloc 123에서 확인가능한 지역변수 return_addr의 값이 0x1010이면 break)
진행 명령어
  • r(run) : 프로그램 수행
  • k(kill) : 프로그램 수행 종료
  • s(step) skip : 현재 행 수행 후 정지, 함수 호출시 함수 안으로 들어감, skip 있을 경우 skip 반큼 수행후 정지
  • n(next) skip : 현재 행 수행 후 정지, 함수 호출시 함수 수행 다음 행으로 감, skip 있을 경우 skip 만큼 수행후 정지
  • u : 현재 루프를 빠져나감
  • finish : 현재 함수를 수행하고 빠져 나감
  • return (return val): 현재 함수를 수행하지 않고 빠져 나감, 혹은 return val이 있으면 return val 리턴
출력
  • info locals : 현재 스택의 로컬변수 모두를 출력
  • info variables : 전역변수 모두 출력 (스압)
  • p [변수명] : 해당변수 value 출력, (포인터변수 입력시 주소값 출력, *포인터변수명 -> 실제 value 출력)
    • p $[레지스터명] : 레지스터값 출력
    • p *[포인터] : struct/class의 배열일 때 배열의 크기를 알림
    • p /[출력형식][변수명] : 출력형식에 맞추어 변수값 출력
    • 출력 형식) t : 2진수, o : 8진수, d : 부호없는 10진수, u : 부호없는 10진수, x : 16진수, c : 최초 1바이트 값을 문자형으로 출력, f : 부동소수점, a : 가장 가까운 심볼의 오프셋 출력
    • p (캐스팅)[변수명] : 변수를 캐스팅하여 출력 ( p (char*)ptr )
    • p [포인터변수or배열]+[숫자] : 특정 주소 + 숫자 위치 출력 ( p (array[1]+4) )
    • p [변수명] = [value] : 특정 변수의 값을 설정
  • info registers : 레지스터 전체 출력
  • display [변수명] : 매번 p 치기 귀찮으니 특정변수 진행 중 계속 출력, p와 사용 방법 동일
  • disalbe display [번호] : 일시적으로 디스플레이 중단
  • enable display [번호] : 중단했던 번호 다시 출력
  • undisplay [번호] : 출력하던 display 변수 제거
스택 상태 검사
  • info f : 스택 프레임 내용 출력
  • info args : 함수 호출시 인자를 출력
  • info locals : 함수의 지역변수를 출력
  • info catch : 함수의 예외 핸들러를 출력
  • bt : 전체 스택 프레임 출력(콜스택)
  • frame [스택번호] : 스택번호의 스택 프레임으로 이동
  • up : 상위 스택 프레임으로 이동
  • up [숫자] : 숫자만큼 상위 스택프레임으로 이동
  • down : 하위 스택 프레임으로 이동
  • down [숫자] : 숫자만큼 하위 스택프레임으로 이동
메모리 상태 검사
  • x/[범위][출력형식][범위의단위] [메모리주소나 함수명]
    • 출력 형식) t : 2진수, o : 8진수, d : 부호없는 10진수, u : 부호없는 10진수, x : 16진수, c : 최초 1바이트 값을 문자형으로 출력, f : 부동소수점, a : 가장 가까운 심볼의 오프셋 출력, s 문자열로 출력, i 어셈블리 형식으로 출력
    • 범위의 단위) b : 1 byte, h : 2 byte, w : 4 byte, g : 8 byte
기타
  • disas [함수명] : 특정함수의 어셈블리 코드 출력
  • disas [주소] [주소] : 주소 사이의 어셈블리 코드 출력
  • call [함수명(인자)] : 특정 함수를 인자값으로 호출
  • jump *[주소] : 주소로 강제적으로 분기
  • jump [행번호] : 특정 행으로 강제 분기
  • jump [함수명] : 특정 함수로 강제 분기
  • info signals : signal 종류 출력
  • info tab키 : info로 확인 가능한 명령어 출력
  • set {타입}[주소] = [값] : 특정 메모리에 값을 지정 ( set {int}0x8048300 = 100 )

유용한 명령어

  • set-follow-mode child: Parent 프로세스가 아니라 Child process를 디버깅한다.
  • set detach-on-fork: fork() 후에 Parnet 혹은 Child를 디버깅 할건지, 아니면 둘다 attaching할건지 결정한다.
  • show <Mode-Name>: 현재 어떤 모드로 실행중인지를 표시한다. 예) show set-follow-mode

참고

  1. https://mitny.github.io/articles/2016-08/gdb-command
  2. https://stackoverflow.com/questions/58851/can-i-set-a-breakpoint-on-memory-access-in-gdb
  3. https://stackoverflow.com/questions/14390256/gdb-break-if-variable-equal-value