gdb 사용에 관한 기본적인 내용은 다음 포스트를 참고하세요.
http://kthan.tistory.com/6

명령어의 일부를 빨간색으로 표시한건 단축키를 의미합니다. 



1. 브레이크포인트 설정 명령어

1.1 break : 특정 위치에 브레이크 포인트 설정


예) break func : func 함수의 시작위치에 설정
     break 123   : 123번째 줄에 설정
     break main.c:func  : main.c 파일의 func 함수의 시작 위치에 설정
     break 123 if i == 1  : i값이 1 일때 123번째 줄에 설정


1.2 rbreak :정규표현식(regular expression)을 사용해 여러 심볼에 브레이크포인트 설정


예) rbreak ^func : fun로 시작하는 모든 심볼에 설정
     rbreak func : func를 포함하는 모든 심볼에 설정


1.3 clear :특정 브레이크포인트 지우기 

     예) clear func : func 함수에 설정한 브레이크포인트 지움
          clear 123  : 123번째 줄에 설정한 브레이크포인트 지움


1.4 info breakpoints: 설정한 브레이크포인트 정보 조회


1.5 enable/disable breakpoints :특정 브레이크 포인트 활성화/비활성화 


예) disable breakpoints : 모든  브레이크포인트 비활성화

     disable breakpoints 1,2,5 : 1,2,5번 브레이크 포인트 비활성화 (info b로 조회한 브레이크포인트 숫자)

     enable breakpoints : 모든  브레이크포인트 활성화

     enable breakpoints 1,2,5 : 1,2,5번 브레이크 포인트 활성화 


1.6 delete :설정한 모든 브레이크포인트를 지움



2. 값 출력 

2.1. info 명령어

info <출력할 타입>: 특정 타입의 info 정보를 출력.
(gdb에서 info를 입력하고 Tab키를 누르면 조회 가능한 모든 값들을 볼 수 있음. )


예) info locals : 지역 변수와 값 출력 
     info variables : 전역 변수와 값 출력
     info registers : 레지스터의 값 출력
     info frame: 스택 프레임 정보 출력
     info thread: 스레드별 정보 출력 


2.2. print 명령어

print/[출력 형식] (형 변환)[변수] : 특정 변수 값을 원하는 포맷으로 출력 

  • 출력 형식:
    t: 2진수
    o: 8진수
    d: int형 10진수
    u: unsigned int형 10진수
    x: 16진수
    c: 1 바이트를 char형
    f: float형 

예) print/x lval : lval를 16진수로 출력 
     print (char *) str : str변수를 "char *" 타입으로 변환 후 출력           


  • 다양한 값 지정 

예) print array@12   : 크기가 12인 array라는 배열을 출력           
    print func::value  : func라는 함수에 있는 value라는 변수 출력 


2.3. list 명령어
list  : 소스 리스트 출력  

예) list    : 현재 실행중인 위치 주변의 소스 출력 
     list func : func 함수의 주변의 소스 출력  
     list 199 : 199 라인 주변의 소스 출력  
     list main.c:main  :  main.c 함수의 main함수 주변의 소스 출력  
     list main.c:199    : main.c 함수의 199 라인 주변의 소스 출력   

  • 보여지는 라인 수 설정 
  예) (gdb) set listsize 20 : list 명령어로 보여지는 라인수를 20줄로 변경



2.4 display 명령어

display <lvalue> : s(step)명령 수행시 매번 lvalue값을 출력
enable/disable display <display번호> : 설정한 번호의 display를 활성화/비활성화



3. 진행 관련 명령어

watch <lvalue> : lvalue에 값이 써질때 마다 브레이크
rwatch <lvalue> : lvalue에서 값을 읽을 때 마다 브레이크

thread [n] : n번째 스레드로 이동(info thread 명령어로 스레드별 정보 조회 가능)

frame [n] : n번째 스택 프레임으로 이동
up [n] : n번째 상위 스택으로 이동
down [n] : n번째 하위 스택으로 이동

※ 'bt' 명령어로 조회되는 결과에서 앞쪽에 있는 숫자가 스택 번호임 


Posted by KT한
,
목적:
gdb를 활용해서 바이너리 파일을 실행하는게 번거로울때
segment fault가 발생하면 자동으로 core file이 생성되도록 설정


절차:

1. ulimit -a 로 조회

core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 31160
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited


2. ulimit -c 로 core file size를 설정
얼마나 큰 파일이 생성될지 모르기 때문에 unlimited 으로 설정

#ulimit -c unlimited

3. 바이너리를 실행하다가 segment fault가 발생하면..
core파일이 생성됐는지 확인!
core.xxxx 처럼 뒤에 숫자가 붙어있다.

# ll -t
-rw------- 1 root root 764497920 Jun 20 08:20 core.19018

4. core파일을 gdb로 열어서 확인
실행 해보면 어떤 바이너리를 실행한 core 파일인지 확인 가능
# gdb -c core.19018
GNU gdb (GDB) Fedora (7.0.1-50.fc12)
Copyright (C) 2009 Free Software Foundation, Inc.

... 중략 ...

Core was generated by `test_coredump'.

... 중략 ...
#0  0x0000003a606327f5 in ?? ()
(gdb)

5. 바이너리 파일을 지정 해준 후 core파일을 열어서 디버깅 시작

# gdb -c core.32258 ./test_coredump


6. ulimit -c 로 core file size 원복
계속해서 core 파일을 생성하면 불필요한 하드 공간을 차지하게 되므로..
검증작업이 끝났다면 core file 크기를 원복 시켜주는게 좋습니다. 

#ulimit -c 0

 ※ gdb 활용법은 아래 포스팅을 참고하세요~
http://kthan.tistory.com/6


Posted by KT한
,

목적:

1. 실행파일을 gdb로 실행하면서 디버깅

# gdb [프로그램명]



2. 현재 실행중인 프로그램이 문제가 있는데.. 종료시키지 않고 디버깅 하고 싶다면..

attach 명령어를 사용해서 디버깅

먼저 디버깅할 프로세스의 PID를 구한다. 


#ps aux | grep [프로그램명]
root      4037  1.6  9.7 1909612 388600 ?      Ssl  Sep23 123:31 ./test_program

# gdb 

..중략..

(gdb) attach 4037


3. core파일을 디버깅

core파일을 생성하는 방법은 여러가지가 있는데요. 



3.1. gcore를 활용해서 core dump파일을 생성한 후 디버깅

#gdb -c [core파일명] [프로그램명] ,또는
#gdb [프로그램명][core파일명]

※ core dump 파일 만드는 방법은 단순히 gcore뒤에 core 파일을 만들 pid만 넣어주면 된다.

#gcore [-o filename] <pid>


3.2. gdb로 core파일을 생성하고 싶은 프로세스를 attach한 후 core dump파일 생성


(gdb) attach <pid>

(gdb) generate-core-file

Saved corefile core.<pid>


3.3. 실행중 segfault를 발생시키고 종료된 프로그램이 생성한 core파일이 있다면.. 


#gdb [프로그램명] [실행중인프로세스pid]


※ segfault 발생했을 때 core dump파일을 생성하도록 설정 하는 방법은 다음 포스트를 참조
http://kthan.tistory.com/45


 절차:

※ 컴파일시 -g 옵션을 사용해야 합니다. 


현재 위치에서 수행 가능한 명령어는 <tab>키를 누르면 조회됩니다. 

#gdb <binary>  

gdb를 실행하면 아래와 같은 프롬프트 화면이 나온다
(gdb)

"run"을 입력하면 프로그램이 실행된다.
만약 프로그램을 실행하는데 특정 옵션이 필요하다면 이곳에서 지정해줄 수 있다.
(gdb) run "--read /home/kthan/test.txt"
 

1. 프로그램이 비정상적으로 종료 되었다면..
스택을 보기 위해 bt(backtrace) 명령어를 사용한다. 현재 활성화된 서브루틴의 스택 프레임을 출력해준다.

 (gdb) bt

#0 Check (p=0x7fff9ffe3d10, lwssn=0x11b6bc20,
sPolicy=<value optimized out>, skey=<value optimized out>,    isnew=<value optimized out>) at stream.c:6858#1  Process (p=0x7fff9ffe3d10, lwssn=0x11b6bc20,

이런식으로 볼 수 있다. 
여기 나온 위치 값을 가지고 문제가 되는 소스의 위치를 알 수 있다. 


2. breaking point를 설정해서 원하는 만큼씩 실행하고 싶다면..실행하기 전에 먼저 breaking point를 설정한다. 

- func 함수의 시작위치에 설정
(gdb) b func 

-123번째 줄에 설정
(gdb) b 123   

-main.c 파일의 func 함수의 시작 위치에 설정
(gdb) b main.c:func 




설정한 breaking point는 "info b" 명령어로 조회 가능하다.

Num     Type      Disp Enb Address                                                         What

1       breakpoint     keep  y   0x0000000000444390 in SetupCompare at spo_check.c:178     breakpoint already hit 1 time
2       breakpoint     keep   y   0x0000000000441f80 in Setup    at spo_fast.c:116
3       breakpoint      keep  y   0x00000000004427c0 in Setup  at spo_full.c:99

Num: breakpoint의 고유번호
Type: breakpoint/watchpoint/catchpoint 정보
Disp: breakpoint의 특징
Enb: 현재 해당 breakpoint의 활성화 여부, 활성화/비활성화는 'enable br [Num]' 또는 'disable br [Num]'으로 변경가능


3. 원하는 원하는 만큼 위치를 옮겨가며 디버깅을 수행한다.

s(step) <반복횟수>  : 현재 출력된 행을 수행하고 멈추지만, 함수의 경우 함수의 내부로 들어가서 수행된다
 n(next)  : 현재 행을 수행하고 멈추지만, 함수의 경우 함수를 수행하고 넘어간다
 c(continue)  : 다음 브레이크 포인트를 만날때 까지 계속 수행한다
 u(until)  : for 문에서 빠져나와서 다음 브레이크 포인트까지 수행한다.
 finish : 현재 함수를 수행하고 빠져나감
 return : 현재 함수를 수행하지 않고 빠져나감
 return 123 : 현재 함수를 수행하지 않고 빠져나감, 단, 리턴값은 123
 si(step instruction)  : 현재의 인스트럭션을 수행, 함수 호출 시 내부로 들어간다.
 ni(next instruction)  : 현재의 인스트럭션을 수행, 함수 호출 시 내부로 들어가지 않는다.


4. 확인 해보고자 하는 값을 출력해가며 디버깅 수행

p(print) 변수 명 : 설정한 변수가 현재 가지고 있는 값을 출력
p *구조체 : 구조체의 값 출력

5. 종료
(gdb) quit


※gdb에 관한 고급 명령어는 다음 포스팅을 참고하세요.

 http://kthan.tistory.com/57

Posted by KT한
,