Dain.Bora.Net  ver 2.0  
About Me
프로필
나의 가족
용's X-file
숙's X-file
다인홈피 ver 1.0
소중한 사람들
가족들
친구들
직장동료들
다인&건희
다인이 이야기
건희 이야기
엄마 이야기
기억속으로
가족들과 함께
즐거운 추억들
사진 & 물생활
디카 이야기
행복한 물생활
포토갤러리
게시판
부스러기들
자료실
좋은글
스터디
방명록
먹고자고놀고
가볼만한곳
먹고싶은것
링크
카운터
오늘 : 28
전체 : 31728
날자 : 2020/09/29

Category Category
[정보보안][정보보안전문가][리눅스]GDB사용법
# C/C++   2011-05-12 10:17
이상용
[정보보안][정보보안전문가][리눅스]GDB사용법

GDB 사용법

Debugging이란

Debugging은 bug, 즉, 컴퓨터 프로그램 상의 논리적 오류를 찾아 해결하는 과정이다.



Debugging 방법

l        프로그램 소스를 눈으로 따라가며, 머리로 실행시켜 논리적 오류를 찾아낸다. 이것은 프로그래머로 하여금 정말 많은 에너지를 소비하게 하며, 자신이 작성한 프로그램인 경우 선입견으로 인해 오류를 찾아내기 힘든 경우가 많다.

l        프로그램의 중간 중간에 ‘printf’를 사용하여 실행 상태를 출력하도록 한다. 이렇게 함으로써 변수에 잘못된 값이 들어가는지 여부를 사람이 직접 계산하는 것보다 좀 더 쉽게 알 수 있다.

l        Debugging tool (예, gdb, dbx, xdbx 등)을 이용한다. Debugging tool들은 프로그램이 실행 중일 때, 변수들의 값이나 수행되는 statement을 보여주며, 필요에 따라 변수 값을 변경하여 실험을 해 볼 수 있도록 해준다.



gdb (GNU Debugger)

gdb는 C, C++, Modula-2로 구현된 프로그램을 디버그할 수 있는 도구이다. 버그를 잡는 걸 돕기 위해 gdb는 다음과 같은 작업들을 가능하게 한다 프로그램의 행동에 영향을 줄 수 있는 각종 조건을 설정한 후, 프로그램을 시작한다
l        특정 조건을 만나면 프로그램을 정지시킨다
l        프로그램이 정지됐을 때 무슨 일이 일어났는지 검사한다
l        프로그램 내부 설정을 바꾸어서 버그를 수정함으로써 다른 버그를 계속 찾아나간다.

</PRE>
gdb 실행

$ gdb [prog [core|procID]]

l         prog: 디버깅할 프로그램

l         core: 프로그램 실행 중에 “segmentation fault” 등의 오류에 의해 비정상적으로 종료할 때 생성되는 파일로, 그때의 시스템의 내부 상태를 그대로 저장해 놓은 것이다. 이 파일을 인자로 주면 실행파일이 비정상적으로 종료된 곳이 소스코드의 어느 부분인지를 표시해 준다.

l         procID: 이미 실행중인 프로그램을 debugging하려면 해당 process의 id (PID)를 주면 되는데, 이 때 주의 할 것은 PID와 같은 이름의 파일이 있을 경우 gdb가 core파일로 여기게 되는 점이다.

주의: Debugging하고자 하는 실행파일은 gcc에서 –g 옵션을 주어 compile함으로써 gdb가 필요로 하는 부가 정보들이 추가된 것을 사용해야 제대로 debugging을 수행할 수 있다.



gdb 명령어

gdb를 실행하여 gdb prompt ‘(gdb) ’가 표시된 상태에서 gdb 명령어를 사용하여 디버깅을 진행한다.

참고: class와 command의 축약형도 지원된다. (예, ‘run’명령어를 축약형 ‘r’로 대신할 수 있다.)

l         도움말 (help)

help [class|command]

도움말, 명령어 분류 목록 출력, 해당 class에 속한 명령어 목록 표시, 해당 command에 대한 도움말 표시

l         프로그램 수행 (running)

kill

디버깅 중인 프로그램의 실행을 강제로 종료시킨다.

run [args]

디버깅할 프로그램의 수행을 시작한다. 프로그램 실행에 필요한 argument (args)를 지정할 수 있다. args를 지정하지 않으면 바로 이전의 run실행이나 “set args”명령에 의해 미리 주어진 argument를 사용한다. 입출력 방향 재지정 (“>”, “<”, “>>”)을 사용할 수 있다.

set args [args]

프로그램이 시작될 때, 디버깅할 프로그램에 전달할 argument를 설정한다.

next [n]

멈춰진 프로그램에서 프로그램의 다음 n(default=1)개의 문장을 수행한 후 멈춘다. 함수일 경우, 함수 전체를 수행한다.

step [n]

멈춰진 프로그램에서 프로그램의 다음 n(default=1)개의 문장을 수행한 후 멈춘다. 함수일 경우, 함수 내부로 들어가 한 문장씩 수행한다.

continue [n]

시그널(Ctrl-C)이나 breakpoint 등에 의해 멈춰진 프로그램의 수행을 계속한다. n이 지정될 경우, 이후 n-1번의 breakpoint는 무시하고, n번째 breakpoint에서 수행을 멈춘다.

until [[file:]n|function]

프로그램이 현재 라인보다 큰 라인이나 또는 지정된 라인이나 어드레스 또는 함수에 도달할 때까지 수행한다(break 명령과 동일한 argument). 또한, 현재 stack frame을 빠져나올 때도 멈춘다. loop를 지날 때, 첫번째 loop수행에서는 next명령과 동일하지만 두번째 loop수행부터는 그 loop를 벗어날 때까지 멈추지 않는다.

l         스택 검사 (stack)

스택은 스택 프레임으로 구성된다. gdb는 스택 프레임에 번호를 지정하는데, 가장 안쪽에 있는(현재 실행중인) 프레임에 대해 0번부터 번호를 부여한다. gdb는 항상 한 프레임을 선택된 프레임으로 간주하며, 선택된 프레임에 대하여 변수 값 보기가 이루어진다. 아래 명령어들에서 숫자나 어드레스를 사용하여 다른 프레임을 지정할 수도 있다.

bt (또는 backtrace 또는 where) [[-]N]

모든 스택 프레임이나 가장 안쪽에 있는 N개의 프레임에 대한 backtrace를 출력한다. argument가 음수(-N)일 때, 가장 바깥쪽에 있는 N개의 프레임을 출력한다.

frame [N]

스택 프레임을 선택하고 출력한다. N은 선택할 프레임 번호(혹은 프레임의 주소)를 가리킨다. Argument가 없으면 현재 선택된 프레임을 출력한다.

up [N]

현재 선택된 프레임을 호출한 스택 프레임 (caller)을 선택하고 출력한다. N은 몇 개의 프레임 위로 올라가야 할지를 말해준다.

down [N]

현재 선택된 프레임에 의해 호출된 스택 프레임 (callee)을 선택하고 출력한다. N은 몇 개의 프레임 아래로 내려가야 할지를 말해준다.

return [rvalue]

선택된 스택 프레임으로 하여금 호출자 (caller)에게로 리턴하게 한다. 실행은 현재 선택된 것보다 위에 있는 프레임 (caller)에서 계속될 것이다. rvalue는 리턴 값을 지정한다.

set variable [variable] = [exp]

[variable]의 값을 [exp] 계산 결과로 대치한다. set variable 대신 set만 써도 된다.



l         데이터 검사 (data)

whatis EXP

expression! EXP의 data 타입을 출력한다.

ptype TYPE

타입 TYPE의 정의를 출력한다.

print [EXP]

expression! EXP의 값을 출력한다. EXP에 사용될 수 있는 변수는 선택된 프레임에 있는 변수이거나 전역 변수이다.

printf  [“format string”, arg1, arg2, arg3, ..., argn]

printf 형식으로 출력한다.

display [EXP]

expression! EXP의 값을 프로그램이 멈출 때마다 출력한다.

delete display (또는 undisplay) [N …]

프로그램이 정지할 때마다 출력되는 몇몇 expression!을 취소한다. N은 취소할 expression!의 번호를 지정한다. Argument가 없으면 모든 자동 출력 expression!을 취소한다.

disable display [N …]

프로그램이 정지할 때마다 출력되는 몇몇 expression!을 disable한다. N은 disable할 expression!의 번호를 지정한다. Argument가 없으면 모든 자동 출력 expression!을 disable한다.

enable display [N …]

프로그램이 정지할 때마다 출력되는 몇몇 expression!을 enable한다. N은 enable할 expression!의 번호를 지정한다. Argument가 없으면 모든 자동 출력 expression!을 enable한다.

l         특정 지점에서 프로그램 정지 (breakpoints)

watch [EXP]

expression! EXP에 대한 watchpoint를 설정한다. EXP의 값이 변할 때마다 프로그램의 수행을 멈춘다.

break [[file:]n|function]

특정 라인(n)이나 함수(function)에 breakpoint를 설정한다. Argument가 없으면 현재 수행 위치에 breakpoint를 설정한다. 프로그램이 수행 중에 지정된 breakpoint에 도착하면 수행을 멈춘다.

clear [[file:]n|function]

특정 라인(n)이나 함수(function)에 설정된 breakpoint를 제거한다. Argument가 없으면 현재 수행 위치에 설정된 모든 breakpoint를 제거한다.

delete [N …]

몇몇 breakpoint나 자동 출력 expression!을 제거한다. N은 제거할 breakpoint 번호를 가리킨다. Argument가 없으면 모든 breakpoint를 제거한다.

disable [N …]

몇몇 breakpoint를 disable시킨다. N은 disable할 breakpoint를 가리킨다. Argument가 없으면 모든 breakpoint를 disable시킨다. disable된 breakpoint는 enable에 의해 다시 동작하도록 할 수 있다.

enable [N …]

몇몇 breakpoint를 enable시킨다. N은 enable할 breakpoint를 가리킨다.

condition [<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><?XML:NAMESPACE PREFIX = ST1 />N  COND]

breakpoint N에서 COND가 true일 때만 멈추도록 명시한다.



l         검사할 파일 (files)

cd [DIR]

작업 디렉토리를 DIR로 설정한다

pwd

작업 디렉토리를 출력한다.

core-file [FILE]

FILE을 core dump 파일로 사용한다.

file [FILE]

FILE을 디버깅할 프로그램으로 사용한다.

list [[file:]n|function][, [file:]n|function]

지정된 함수나 라인 앞뒤의 11라인을 출력한다. 콤마로 분리된 두 개의 Argument는 출력할 시작 라인과 끝 라인을 가리킨다. Argument가 없으면 앞서 출력된 라인 이후의 10개 라인을 출력한다. “list –”는 앞서 출력된 라인 이전의 10개 라인을 출력한다.

l         상태 조회 (status)

info

디버깅 중인 프로그램에 대한 여러가지를 보여 주기 위한 포괄적인 명령어

info breakpoints (또는 info watchpoints) [N]

설정된 breakpoint의 상태를 보여준다. N은 특정 breakpoint 번호를 가리킨다. Argument가 없으면 모든 breakpoint의 상태를 보여 준다.

info args

현재 스택 프레임의 인자 변수를 보여준다.

info display

프로그램이 멈출 때 출력할 expression!들을 보여준다.

l         지원도구 (support)

help [class|command]

도움말, 명령어 분류 목록 출력, 해당 class에 속한 명령어 목록 표시, 해당 command에 대한 도움말 표시

quit

gdb를 종료한다.

make [args]

‘make’를 실행한다.



gdb 사용 예제

gdb 사용법을 익히기 위해 bug가 있는 간단한 프로그램을 gdb를 사용하여 디버깅해 보자. 먼저, /afs/p/class/cse/yjsuh/csed103F2004/lab/lecture_note/bug.c를 각자의 디렉토리로 복사한다.

$ mkdir debug; cd debug

$ cp /afs/p/class/cse/yjsuh/csed103F2004/lab/lecture_note/bug.c ./



bug.c 소스 코드는 다음과 같다.

#include <stdio.h>



int score[5];





int sum(int cnt)

{

   int i;

   int sum;



   for(i = 0; i < cnt; i++)

      sum += score[i];



   return sum;

}





int main()

{

   int cnt=0;



   printf("input scores. input -1 to finish.\n");

   while(1)

   {

      printf("score%d? ", cnt+1);

      scanf("%d", score[cnt]);

      if(score[cnt] == -1)

         break;

      cnt++;

   }



   printf("%d scores read.\n", cnt);



   printf("--- result ---\n");

   printf("sum: %d   avg: %d\n", sum(cnt), sum(cnt)/cnt);



   return 0;

}




본 소스 코드는 임의의 개수의 점수를 입력 받아 총점과 평균을 출력해 주는 프로그램이다. 이를 컴파일하여 실행 해보면 segmentation fault 오류가 나며 core파일이 생성되며 종료된다. 생성된 core 파일을 바탕으로 디버깅을 한다. 이때 컴파일시 –g 옵션을 써주어야 디버깅 정보를 볼 수 있다. 굵은 글씨가 사용자가 입력한 부분이다.



vision/endovert ~/gdb {298} gcc -g bug.c

vision/endovert ~/gdb {299} a.out

input scores. input -1 to finish.

score1? 100

Segmentation fault (core dumped)

vision/endovert ~/gdb {300} gdb

GNU gdb 5.0

Copyright 2000 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "alpha-dec-osf4.0d".

(gdb) file a.out

Reading symbols from a.out...done.

(gdb) core core

Core was generated by `a.out'.

Program terminated with signal 11, Segmentation fault.

Reading symbols from /usr/shlib/libc.so...done.

#0  0x3ff800e1e4c in _doscan () from /usr/shlib/libc.so

(gdb) bt

#0  0x3ff800e1e4c in _doscan () from /usr/shlib/libc.so

#1  0x3ff8018ea80 in scanf () from /usr/shlib/libc.so

#2  0x120001384 in main () at bug.c:26

(gdb) list 26

21

22         printf("input scores. input -1 to finish.\n");

23         while(1)

24         {

25            printf("score%d? ", cnt+1);

26            scanf("%d", score[cnt]);

27            if(score[cnt] == -1)

28               break;

29            cnt++;

30         }

(gdb) quit

vision/endovert ~/gdb {301}


bt결과를 보면 26번째 행에서 core dump가 일어난 것을 볼 수 있다. 26번 행을 보면 scanf의 인자로 넣은 변수 score[cnt] 앞에 &가 빠졌음을 알 수 있다. 고쳐서 다시 컴파일 해본다. 이번엔 결과값이 이상하게 나온다. 다시 gdb를 사용하여 다시 디버깅해본다.

vision/endovert ~/gdb {303} gcc -g bug.c

vision/endovert ~/gdb {304} a.out

input scores. input -1 to finish.

score1? 100

score2? 100

score3? 100

score4? -1

3 scores read.

--- result ---

sum: 301   avg: 200

vision/endovert ~/gdb {305} gdb a.out

GNU gdb 5.0

Copyright 2000 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "alpha-dec-osf4.0d"...

(gdb) break sum

Breakpoint 1 at 0x120001268: file bug.c, line 7.

(gdb) run

Starting program: /afs/postech.ac.kr/home/std/endovert/gdb/a.out

input scores. input -1 to finish.

score1? 50

score2? 50

score3? 50

score4? -1

3 scores read.

--- result ---



Breakpoint 1, sum (cnt=0) at bug.c:7

7       {

(gdb) l

2

3       int score[5];

4

5

6       int sum(int cnt)

7       {

8          int i;

9          int sum;

10

11         for(i = 0; i < cnt; i++)

(gdb) print sum

$1 = 1

(gdb) next

11         for(i = 0; i < cnt; i++)

(gdb) step

12            sum += score[i];

(gdb) display sum

1: sum = 1

(gdb) s

11         for(i = 0; i < cnt; i++)

1: sum = 51

(gdb) s

12            sum += score[i];

1: sum = 51

(gdb) s

11         for(i = 0; i < cnt; i++)

1: sum = 101

(gdb) set sum = 100

(gdb) print sum

$2 = 100

(gdb) s

12            sum += score[i];

1: sum = 100

(gdb) s

11         for(i = 0; i < cnt; i++)

1: sum = 150

(gdb) s

14         return sum;

1: sum = 150

(gdb) s

15      }

1: sum = 150

(gdb) info display

Auto-display expression!s now in effect:

Num Enb Expression!

1:   y  sum

(gdb) delete display 1

(gdb) continue

Continuing.



Breakpoint 1, sum (cnt=3) at bug.c:7

7       {

(gdb) bt

#0  sum (cnt=3) at bug.c:7

#1  0x120001414 in main () at bug.c:35

(gdb) l 35

30         }

31

32         printf("%d scores read.\n", cnt);

33

34         printf("--- result ---\n");

35         printf("sum: %d   avg: %d\n", sum(cnt), sum(cnt)/cnt);

36

37         return 0;

38      }

39

(gdb) s

11         for(i = 0; i < cnt; i++)

(gdb) print sum

$3 = 150

(gdb) p i

$4 = 3

(gdb) s

12            sum += score[i];

(gdb) print sum

$5 = 150

(gdb) print i

$6 = 0

(gdb) return 150

Make sum return now? (y or n) y

#0  0x120001414 in main () at bug.c:35

35         printf("sum: %d   avg: %d\n", sum(cnt), sum(cnt)/cnt);

(gdb) c

Continuing.

sum: 150   avg: 50



Program exited normally.

(gdb) info break

Num Type           Disp Enb Address    What

1   breakpoint     keep y   0x120001268 in sum at bug.c:7

        breakpoint already hit 2 times

(gdb) delete 1

(gdb) info break

No breakpoints or watchpoints.

(gdb) q

vision/endovert ~/gdb {306}


합을 계산하는 sum함수에 breakpoint를 걸고 실행 시켜보면 초기의 sum의 값이 0이 아닌 다른 값 (이 경우 1)이 나옴을 볼 수 있다. sum값이 0으로 초기화 되도록 소스를 고친다.


Name       Pass       Secret Code   Resize  
List
   [C/C++] [정보보안][정보보안전문가][리눅스]GDB사용법  이상용 2011.05.12 523
27    [보안] 웹 보안 [3] 이상용 2008.05.28 2678
26    [자바스크립트] JavasScript 총 정리 [5] 이상용 2007.04.10 1149
25    [리눅스/유닉스] rrdtool 설치 [1] 이상용 2007.02.27 1758
24    [공통] Open Source 패러다임 쉬프트 [146] 이상용 2007.02.27 1228
23    [자바스크립트] Table Row 삭제하기 [74] 이상용 2006.12.01 817
22    [리눅스/유닉스] swatch를 이용해 로그파일을 실시간으로 모니터해 보자. [1] 이상용 2006.08.29 880
21    [리눅스/유닉스] cfengine 을 이용하여 여러대의 시스템관리 자동화 하기 [1] 이상용 2006.08.04 1269
20    [리눅스/유닉스] Content Management Systems (CMS) - OpenSource  이상용 2006.08.04 1867
19    [웹] Web 2.0이란 무엇인가 [1] 이상용 2006.08.02 796
18    [웹] [PHPA] using PHP Accelerator [2] 이상용 2006.02.16 9040
17    [공통] 정규 표현식  이상용 2006.01.05 642
16    [리눅스/유닉스] SELinux ?  이상용 2006.01.04 741
15    [리눅스/유닉스] apache2.0 + tomcat5.x 설치하기 [1] 이상용 2005.11.21 2310
14    [DB] mysql 설치 가이드  이상용 2005.11.20 890
13    [네트웍] Catalyst 4000-L3 Switch 구조와 setting [197] 이상용 2005.11.08 57213
12    [네트웍] 네트워크 진단 명령어(윈도우) [1] 이상용 2005.11.08 1230
11    [네트웍] DNS 운영 자료  이상용 2005.11.08 681
10    [네트웍] Cisco 6509 운영 메뉴얼 [1] 이상용 2005.11.08 4527
9    [리눅스/유닉스] GD 설치해 보자...  이상용 2005.09.29 1663
List   1 [2]  
Copyright 1999-2020 Zeroboard / skin by eggnara