Debugger/GDB

[GDB] 사용법, 명령어 정리

우와해커 2019. 12. 28. 12:06

컴파일러 디버깅 옵션

gcc -g -W -Wall -o [실행파일] [C파일]

 

소스 수준의 디버깅을 위한 정보를 실행파일에 포함시킨다.


디버깅 관련 리눅스 기본 명령어

  • file <파일이름> : 파일 정보    -> not stripped 출력 시 symbol을 볼 수 있다.

  • strings <파일이름> : 문자열 정보

  • nm -D <파일이름> : 동적으로 남아 있는 정보    -> 프로그램이 사용하는 함수 출력(정적 라이브러리만 해당)

  • objdump -d <파일이름> : 덤프따기

  • gdb <파일이름> : 디버깅


GDB 명령어 (gdb 실행 후 사용하는 명령어들)

1. 기본 설정

  • layout asm : 어셈블리 정보창 출력

  • layout reg : 레지스터 정보창 출력

  • set disassembly-flavor intel : 인텔 아키텍쳐로 설정

 

2. 프로그램 실행

  • r <명령인자> : 실행(run)

  • c : 중단된 프로그램 실행 재개(continue)

  • kill : 프로그램 실행 종료

  • s <숫자> : 몇 단계 씩 수행(step)

  • ni, si : 한단계 진행

  • finish : 현재 함수의 리턴까지 실행

  • return <return 값> : 함수를 실행하지 않고 리턴

  • q : 디버깅 종료


3. 중단점(breakpoint)

  • b <함수이름/라인넘버/*메모리주소> : breakpoint 설정

-> b *main+43 : main문자열(함수이름참조)이 참조하는 주소 + 43

-> break 80484a8

  • i b : 설정된 breakpoint 표시(= info breakpoint 또는 info b)

  • delete <breakpoint 번호> : 설정된 bp 삭제

  • enable <breakpoint 번호> : bp 활성

  • disable <breakpoint 번호> : bp 비활성

  • clear <함수이름> : 함수 내의 모든 bp 삭제


4. 메모리 확인

  • display [/표시형식] <변수이름> : 변수의 값이 유효한 코드 부분에서 값을 계속해서 출력 (표시형식: d, x, t)

  • undisplay : display 모드를 종료

  • print [/표시형식] <변수이름/*메모리주소/레지스터이름> : 현재 또는 지정된 위치의 프로그램 소스 코드 출력

  • x/[개수][표시형식][단위크기] <주소/함수이름> : 지정된 위치의 메모리 데이터를 지정된 형식으로 출력

-> 표시형식: d, o, x, t, f, s, i 등

-> 단위 크기: b, h, w, g

 

예시) x/x <주소> : 해당 주소의 내용물을 바이트 단위로 출력

-> x/10x : opcode 10개 출력

-> x/10i : 명령어 10개 출력

-> x/10s : 문자열 10개 출력

-> x/10wx : word단위로 10개 출력

-> x/s, x/i, ... etc

 

예시) mov $eax, [0xbfffefc4] : 대괄호포인터를 의미

-> 대괄호 없이 0xbfffefc4일 경우 그 주소의 내용이다.

-> 포인터는 그 주소에 저장된 포인터주소가 참조하는 주소의 내용물을 저장하는 것.

-> '*'기호 사용 : x/s *0xbfffefc4 처럼 한단계 더 보아야함

 

예시) 레지스터도 포인터처럼 사용해서 내용물을 볼 수 있다.

-> x/s $eax : eax에 저장된 내용(주소일수도있음)

-> x/s *$eax : eax에 저장된 포인터가 가리키는 내용



5. 프로그램 코드 확인

  • list <함수이름/라인넘버/변수이름> : 현재 또는 지정된 위치의 프로그램 소스 코드 출력

  • disas <함수이름/메모리주소> : 함수 디스어셈 내용(기계어 코드)

 

6. 변수값 변경 감지

  • watch <변수이름> : 변수에 데이터가 쓰여질 때 실행 멈춤(breakpoint역할)

  • rwatch <변수이름> : 변수 읽을 때 실행 멈춤

  • awatch <변수이름> : 변수 관련 모든 경우에 실행 멈춤

 

7. 기타 명령어

  • backtrace, where : 현재 실행 위치의 주소와 스택 상태 출력

  • i locals : 모든 지역 변수 목록과 현재 값 출력(= info locals)

  • i program : 프로그램 실행 정보 출력(= info program)

  • i reg : 현재 레지스터 정보 출력(= info reg)

  • set <수정할주소의 포인터> = <내용> : 메모리 데이터 변경

예시) 잘못된 경우 : 레지스터 주소에 문자열 주소를 넣을 때

set $esp = 0x08048585 : esp가 바뀜

 

예시) 옳은 경우 : 레지스터가 참조하는 주소에 문자열 주소를 넣을 때

set *0xbfffefa0 = 0x08048585

레지스터는 포인터참조(*)를 사용할 수 없다.

즉, 레지스터의 주소를 적을 것!