그룹명2/LINUX

GDB 사용법 정리

lseek 2016. 4. 20. 15:30

GDB 사용법 정리중..........


 

gdb사용하기.docx


1.     GDB(GNU Project debugger) 사용법

 

1.1.      사용하기 전에: GDB를 이용하기 위해서는 컴파일 과정에서 디버깅 정보(-g)를 삽입해야 한다.

/* main.c */

#include <stdio.h>

 

int main(int argc, char * argv[])

{

       printf("Hello,World!!!\n");

       return 0;

}

 

user0@pc0:~$ gcc -g -o main main.c

 

1.2.      컴파일이 정상 종료 되면 GDB를 실행한다.

gdb [프로그램명]

gdb [프로그램명] [프로세스PID]

gdb [프로그램명] [코어파일명] à 코어파일[1]을 이용해서 디버깅 할 때

gdb -c [코어파일명] [프로그램명]

 

user0@pc0:~$ gdb main

GNU gdb (Ubuntu 7.7-0ubuntu3) 7.7

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 생략 ~~~~~~~~~~~~~~~~~~

Reading symbols from main...done.

(gdb)

 

(gdb) 프롬프트 상태에서 명령을 내릴수 있다. 리눅스 쉘처럼 명령어 일부만 입력하고 TAB키를 누르면 자동 완성된다.

1.3.      종료 q(quit)

ctrl + d

(gdb) q

(gdb) quit

 

(gdb) quit

user0@pc0:~$

 

1.4.      도움말 보기 h(help)

(gdb) h

(gdb) help

(gdb) help [명령어]

(gdb) help all  // 모든 명령어를 보여준다.

(gdb) apropos 찿는단어

 

1.5.      소스보기 l(list)

옵션에 따라 실행중인 프로그램의 소스를 다양한 방법으로 볼 수 있다. 한번 l 명령을 내린 다음에는 엔터키를 입력하면 다음 소스를 보여준다. listsize를 조정하여 보여지는 라인수를 조정 할 수 있다.

(gdb) l

(gdb) l [행번호]  // 행번호를 중심으로 앞뒤 소스를 보여준다.

(gdb) l [함수명]  // 함수명을 중심으로 앞뒤 소스를 보여준다.

(gdb) l -  //이전 10라인을 출력한다.

(gdb) l [파일명]:[함수명]

(gdb) l [파일명]:10

(gdb) set listsize [행수] // 보여지는 소스의 라인수 설정

 

(gdb) l main

2      #include <time.h>

3      #include <stdlib.h>

4      #include <locale.h>

5     

6      int main(int argc, char * argv[])

7      {

8            time_t * p_time;

9           

10           //p_time = (time_t *) malloc(sizeof(time_t));

11                  time(p_time);

1.6.      브레이크 포인트 걸기 b(break)[2]

(gdb) b [함수명] // 함수의 시작부분에 브레이크 포인트 설정

(gdb) b [라인넘버] // 해당 라인에 브레이크 포인트 설정

(gdb) b [파일명]:[함수명]  // 해당 파일의 함수의 시작부분에 브레이크포인트 설정

(gdb) b [파일명]:[라인넘버

(gdb) b [파일명]:[라인넘버]

(gdb) b *[ADDRESS]  // 해당 주소에 브레이크포인트 설정 예를 들면 b *0x400580 형식으로

(gdb) b [LOCATION] [if CONDITION] // [LOCATION]은 라인넘버, 함수, 주소가 될 수 있다.

                                   // CONDITION은 변수에 대한 Boolean expression이다.

                                   // b func if var == 0과 같은 형식으로 사용

 

 

브레이크 포인트 설정후에 condition 추가 하기/삭제하기

(gdb) condition [breakpoint number] CONDITION // CONDITIONBoolean 식이다.

(gdb) condition [breakpoint number] //CONDITION을 없이 명령을 내리면 condition이 삭제됨

 

1.7.      설정된 브레이크 포인트들 보기

(gdb) info breakpoints

 

(gdb) break 17

Breakpoint 6 at 0x40055d: file bugprg.c, line 17.

(gdb) break hello

Breakpoint 7 at 0x400531: file bugprg.c, line 13.

(gdb) braek main

Undefined command: "braek".  Try "help".

(gdb) break main

Breakpoint 8 at 0x400580: file bugprg.c, line 25.

(gdb) info breakpoints

Num     Type           Disp Enb Address            What

6       breakpoint     keep y   0x000000000040055d in gethour at bugprg.c:17

7       breakpoint     keep y   0x0000000000400531 in hello at bugprg.c:13

8       breakpoint     keep y   0x0000000000400580 in main at bugprg.c:25

(gdb)

 

Breakpoint number[3]는 설정된 브레이크 포인트들을 구분하는 고유값이다. 위에서 info breakpoints명령을 내렸을 때 제일 앞 열에 나오는 값이다.

1.8.      브레이크 포인트 지우기: cl(clear), d(delete)

(gdb) cl [[파일명:]함수명]

(gdb) cl [[파일명:]라인넘버]

(gdb) cl [*주소]

(gdb) d [breakpoints]

(gdb) d  // 모든 브레이크 포인트 지우기

1.9.      브레이크 활성화/비활성화: enable, disable

(gdb) enable [breakpoints] // enable 2 와 같이 하나, enable 2 3 와같이 여러 개를 동시에

// 지정 할수 있다.

(gdb) disable [breakpoints] //

 

1.10.    와치포인트 설정: watch[4]

(gdb) watch [변수명]

(gdb) watch [expression] // boolean expression 참인 조건

                         // i==0, i>15등과 같은 식이 들어감

                         // break point 처럼 condition 명령으로 추후에

//expression을 설정할 수도 있음

(gdb) info watchpoints  // watch point만 보여줌

(gdb) info breakpoints  // break point watch point둘다 보여줌

(gdb) enable [watchpoints]  // breakpoint와 같은 방법으로 watchpoint를 활성화함

(gdb) disable [watchpoints]  // breakpoint와 같은 방법으로 watchpoint를 비활성화함

 

(gdb) p &iCount

$7 = (int *) 0x804c3a4

(gdb) watch *0x804c3a4 == 1000

Hardware watchpoint 15: *134529956 == 1000

(gdb) c

 

..................

 

Hardware watchpoint 14: *134529956 == 1000

 

Old value = false

New value = true

main (argc=1, argv=0xbfb654b4) at Test.cpp:185

185                                             printf("test %d\n",iCount);

(gdb) p iCount

$6 = 1000

 

 

1.11.    와치포인트 보기: info watchpoints, info breakpoints

(gdb) info watchpoints  // watch point만 보여줌

(gdb) info breakpoints  // break point watch point둘다 보여줌

(gdb) enable [watchpoints]  // breakpoint와 같은 방법으로 watchpoint를 활성화함

(gdb) disable [watchpoints]  // breakpoint와 같은 방법으로 watchpoint를 비활성화함

 

 

1.12.    와치포인트 활성화/비활성화 enable/disable, delete

(gdb) enable [watchpoints]  // breakpoint와 같은 방법으로 watchpoint를 활성화함

(gdb) disable [watchpoints]  // breakpoint와 같은 방법으로 watchpoint를 비활성화함

(gdb) delete [watchpoints]  // breakpoint와 같은 방법으로 watchpoint를 지움

 

 

1.13.    프로그램 실행 r(run)

(gdb) r

(gdb) r arg1 arg2 // arg1 arg2를 인자로 프로그램 수행

// set args 참고

 

1.14.    프로그램 종료 k(kill)

(gdb) k

 

1.15.    진행 명령어

 

 

s [N]

Step

n [N]

Next : step over 함수내부로 들어가지 않음

c

Continue : 계속 진행

u

until

finish

 

return

 

return value

 

si

stepi

ni

nexti

 

1.16.    모든 지역변수 출력 info locals

Info locals // 현재 스택프레임의 지역변수 모든 지역 변수 출력

Breakpoint 1, main () at bugprg.c:29

29           for(i=0; i<100; i++){

(gdb) info locals

lval = 2331

i = 0

lstr = 0x400692 "I like you."

pt = 0x601060 <gtime>

(gdb) l

24     {

25           int lval = 2331,i;

26           char *lstr = "I like you.";

27           struct time *pt = >ime;

28          

29           for(i=0; i<100; i++){

30                  printf("array[i] = %s\n", array[i]);

31                  gtime.hour += gethour(i%2);

32           }

33    

(gdb)

 

1.17.    모든 전역변수/정적 변수 출력 info variables

(gdb) info variables // 사용자 작성 부분과 c 표준 라이브러리와 같은 라이브러리의 전역/정적

//변수들이 출력됨

 

1.18.    레지스터 출력 info variables

(gdb) info registers // 정수 레지스터 출력

(gdb) info all-registers // 거의 모든 레지스터를 출력

 

 

1.19.    개별 변수 출력 p(print)

(gdb) p EXP // EXP는 변수,함수명 간단한 식

(gdb) l

24        {

25           int lval = 2331,i;

26           char *lstr = "I like you.";

27           struct time *pt = >ime;

28          

29           for(i=0; i<100; i++){

30                  printf("array[i] = %s\n", array[i]);

31                  gtime.hour += gethour(i%2);

32           }

33       

(gdb) info locals

lval = 2331

i = 0

lstr = 0x400692 "I like you."

pt = 0x601060 <gtime>

(gdb) p lval

$53 = 2331

(gdb) p array

$54 = {0x400684 one", 0x400688 "two", 0x40068c "three", 0x0}

(gdb) p main // 함수의 주소가 출력된다.

$55 = {int ()} 0x400577 <main>

(gdb) p lval+2

$56 = 2333

(gdb) p pt

$57 = (struct time *) 0x601060 <gtime>

(gdb) p *pt

$58 = {hour = 1, min = 2, sec = 3}

(gdb) p gtime

$59 = {hour = 1, min = 2, sec = 3}

(gdb) p >ime

$60 = (struct time *) 0x601060 <gtime>

(gdb) p *(struct time *) 0x601060

$61 = {hour = 1, min = 2, sec = 3}

 

1.20.    코아(core 파일을 이용한 디버깅)

코어 파일이 생성 되지 않을 경우 다음과 같이 코어 파일 관련 내용을 확인 한다.

$ ulimit -a

core file size          (blocks, -c) 0

data seg size           (kbytes, -d) unlimited

scheduling priority             (-e) 0

file size               (blocks, -f) unlimited

pending signals                 (-i) 5853

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) 5853

virtual memory          (kbytes, -v) unlimited

file locks                      (-x) unlimited

 

 

다음과 같이 코어 파일 크기를 늘린다. 이는 한시적으로 설정된다. 다시 로그인 하거나 다른 터미널창을 열면 원래 값으로 복구 된다.

$ ulimit -c unlimited

 

$ 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) 5853

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) 5853

virtual memory          (kbytes, -v) unlimited

file locks                      (-x) unlimited

 

샘플 소스__________________________________

#include <stdio.h>

#include <time.h>

#include <stdlib.h>

#include <locale.h>

 

int main(int argc, char * argv[])

{

          time_t * p_time;

         

          //p_time = (time_t *) malloc(sizeof(time_t));

          time(p_time);

          printf("Current Time in seconds = %d\n", (int) * p_time);

         

          //char * p_time_string;

         

          //p_time_string = ctime(p_time);

          //printf("Current Time String = %s\n", p_time_string);

 

          return 0;

}

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

$ gcc -g -o my_time my_time.c

$ ./my_time

세그멘테이션 오류 (core dumped)

$ ls

core  my_time  my_time.c

 

 

다음 내용을 참고 하자

john@john-virtual-machine:~/fault_debugging$ gdb my_time core

GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1

Copyright (C) 2014 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law.  Type "show copying"

and "show warranty" for details.

This GDB was configured as "x86_64-linux-gnu".

Type "show configuration" for configuration details.

For bug reporting instructions, please see:

<http://www.gnu.org/software/gdb/bugs/>.

Find the GDB manual and other documentation resources online at:

<http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".

Type "apropos word" to search for commands related to "word"...

Reading symbols from my_time...done.

[New LWP 5209]

Core was generated by `./my_time'.

Program terminated with signal SIGSEGV, Segmentation fault.

#0  0x000000000040059c in main (argc=1, argv=0x7fff621e8b58) at my_time.c:12

12           printf("Current Time in seconds = %d\n", (int) * p_time);

(gdb) list

7         {

8            time_t * p_time;

9           

10           //p_time = (time_t *) malloc(sizeof(time_t));

11           time(p_time);

12           printf("Current Time in seconds = %d\n", (int) * p_time);

13          

14           //char * p_time_string;

15          

16           //p_time_string = ctime(p_time);

(gdb) b 11

Breakpoint 1 at 0x40058c: file my_time.c, line 11.

(gdb) r

Starting program: /home/john/fault_debugging/my_time

 

Breakpoint 1, main (argc=1, argv=0x7fffffffdfe8) at my_time.c:11

11           time(p_time);

(gdb) list

6         int main(int argc, char * argv[])

7         {

8            time_t * p_time;

9           

10           //p_time = (time_t *) malloc(sizeof(time_t));

11           time(p_time);

12           printf("Current Time in seconds = %d\n", (int) * p_time);

13          

14           //char * p_time_string;

15          

(gdb) s

12           printf("Current Time in seconds = %d\n", (int) * p_time);

(gdb) s

 

Program received signal SIGSEGV, Segmentation fault.

0x000000000040059c in main (argc=1, argv=0x7fffffffdfe8) at my_time.c:12

12           printf("Current Time in seconds = %d\n", (int) * p_time);

(gdb) print p_time

$1 = (time_t *) 0x0

(gdb)

$2 = (time_t *) 0x0

(gdb) print *p_time

Cannot access memory at address 0x0

(gdb)

 

 

 

 

1.21.    백트래이스(backtrace) 활용하기

 



[1] 코어 파일이란 프로세스가 문제가 생겨 종료되는 순간의 이미지 파일이다. 코어 파일에는 종료순간의 CPU context와 프로세스의 코드와 데이터, 스택 등의 정보가 들어 있어 디버깅 할 때 유용하게 사용할 수 있다.

[2] tb(tbreak) temporary breakpoint를 설정한다. b(break)와 사용방법은 같고 hit되었을 때 자동으로 clear 된다.

[3] 도움말을 보면 명령어 인자로 breakpoint number(s)를 단순이 breakpoint(s)로 생략해서 쓰는 경우가 많다.

[4] awatch, rwatch 명령어 참고



gdb사용하기.docx
0.03MB