포럼 회원으로 등록하신분만 다운로드가 가능합니다. 최대 업로드 가능한 용량은 1GB 입니다.

aESOP S3C6410 보드에는 Native GDB가 기본으로 포함되어 제공 됩니다.

따라서, 일반 리눅스 PC에서 GDB를 사용하는 것과 동일하게 타깃 보드에서 GDB를 이용하여
응용프로그램 디버깅을 수행할 수 있습니다.

다음은 http://dualpage.muz.ro/ 에서 발췌해 온 GDB의 간단한 사용 방법 입니다.

대상 프로그램 지정

먼저 디버깅을 할 대상 프로그램을 지정하는 방법에는
두가지 방법이 있습니다.
1. open - 새로 프로그램을 지정한다.
2. attch - 이미 실행중인 프로그램을 지정한다.

먼저 open은 다음과 같이 하면 됩니다.

gdb 대상프로그램

dual5651@dualpage:~$ gdb ./exam1
GNU gdb 6.3-debian
Copyright 2004 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 "i386-linux"...Using host libthread_db library "/lib/libthread_db.so.1".
(gdb)

위는 성공적으로 대상 프로그램을 open하였을때의 모습입니다.
만약 존재하지 않는 프로그램을 open하고자 한다면 마지막 줄에
다음과 같은 메시지가 뜹니다.

This GDB was configured as "i386-linux"..../exam2:
그런 파일이나 디렉토리가 없음.

attch는 이미 실행중인 process를 디버깅하고자 할때 사용하는
것으로, 다음과 같이 사용하실 수 있습니다.

dual5651@dualpage:~$ ps -aux
USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND
root      1085  0.0  0.8  7176 2160 ?        Ss   20:50   0:00 sshd:
root      1087  0.0  0.8  7176 2160 ?        S    20:50   0:00 sshd:
root      1141  0.0  0.1  1344  312 tty1     S+   21:17   0:00 /root/exam
dual5651  1132  0.0  0.3  2480  856 pts/0   R+   21:14   0:00 ps -aux

먼저 ps -aux 명령을 이용하여 현재 실행중인 프로세스들의
목록을 출력하여 보았더니, root님이 /root/exam 이라는
프로그램을 실행중이신 것을 볼 수 있습니다. PID가 1141이라는
것을 잘 봐두어야 합니다. :)
이 프로세스를 attch하려면 다음과 같이 하면 됩니다.
gdb 대상프로그램 PID

dual5651@dualpage:~$ gdb /root/exam 1141
GNU gdb 6.3-debian
Copyright 2004 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 "i386-linux"...Using host libthread_db library "/lib/libthread_db.so.1".

Attaching to program: /root/exam, process 1141

프로세스 실행상태 관리

디버깅을 하려면 먼저 대상 프로그램을 켜야 할 것이고,
끝난후에는 디버깅 되는 대상을 죽여줘야 할 것입니다.
다음과 같은 명령어가 존재합니다.

run - 대상 프로그램을 시작 시킨다.
ex)run : 대상 프로그램을 시작 시킨다.

run 인자 - 대상 프로그램의 인자값을 준 상태로 시작 시킨다.
ex)run 1234 : 인자로써 1234를 주고 시작 시킨다.

kill - 대상 프로그램을 종료 시킨다.
ex)kill : 대상 프로그램을 종료 시킨다.

Break Point(중단점) 관리

Break Point는 디버깅을 하는데 있어서 아주 중요한
기능이라고 할 수 있겠습니다. (BP 없는 디버거는 꿈꿀수도 없죠 lol)
다음과 같은 BreakPoint관리 명령어가 존재합니다.

1. Break - Break Point 설치
2. clear,delete - Break Point 제거
3. disable - Break Point 비활성화
4. enable - Break Point 활성화
5. condition - Break Point에 조건 부여

Break
지정한 주소에 Break Point를 걸 수 있는 명령입니다.
다음과 같이 사용할 수 있습니다.

break 함수 - 지정한 함수에 BP를 설치 합니다.
ex)break main : main()함수에 BP를 설치한다.

break 주소 - 지정한 주소에 BP를 설치 합니다.
ex)break 0x08048454 - 0x08048454에 BP를 설치한다.

break - 인자 없는 break는 실행중인 현재 주소에 BP를 설치합니다.
ex)break - 현재 실행중인 주소에 BP를 설치한다.

실제로 BP를 설치하면 어떻게 되는지 알아 보도록 하겠습니다.

dual5651@dualpage:~$ gdb ./exam1
GNU gdb 6.3-debian
Copyright 2004 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 "i386-linux"...Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) break main
Breakpoint 1 at 0x804845a
(gdb) run
Starting program: /home/dual5651/exam1
Breakpoint 1, 0x0804845a in main ()
(gdb)

main에 Break Point를 설치한 상태에서 프로그램을 실행 시키니,
바로 main에 설치한 BP에 걸린 것을 볼 수 있습니다. :)
break 명령을 사용할 때에, Breakpoint 다음에 보여주는 숫자는
현재 설치한 BP의 번호입니다. 이 번호를 사용하여 해당 BP를
제거/비활성화/활성화 등의 관리를 합니다.

Clear, Delete
지정한 BP를 제거하거나, 모든 BP를 제거 할때 사용합니다.
두 명령어의 사용방법은 전혀 다른데,
다음과 같이 사용할 수 있습니다.

clear 함수 - 지정한 함수에 설치되어 있는 BP 제거
ex)clear main : main()함수에 설치된 BP 제거

delete BP번호 - 지정한 BP번호의 BP를 제거
ex)delete 1 : 1번 BP에 대한 BP제거

delete - 모든 BP를 제거
ex)delete - 모든 BP제거

실제로 BP를 설치 후, 제거해 보도록 하겠습니다.

(gdb) break main
Breakpoint 1 at 0x804845a
(gdb) clear main
Deleted breakpoint 1
(gdb) break main
Breakpoint 2 at 0x804845a
(gdb) delete 2
(gdb) break 0x80484e0
Function "0x80484e0" not defined.
Make breakpoint pending on future shared library load?
(y or [n]) y
Breakpoint 3 (0x80484e0) pending.
(gdb) delete
Delete all breakpoints? (y or n) y
(gdb)

clear는 친절하게 BP가 제거되면 알려주는데, delete는 안 그렇군요.:(

Disable
특정 BP를 비활성화 시키거나 모든 BP를 비활성화 시킵니다.
다음과 같이 사용할 수 있습니다.

disable 번호 - 지정한 번호에 대한 BP를 비활성화 시킵니다.
ex) disable 1 - 1번 BP를 비활성화 시킵니다.

disable - 모든 BP를 비활성화 시킵니다.
ex) disable - 모든 BP를 비활성화 시킵니다.

Enable
특정 BP를 활성화 시키거나 모든 BP를 활성화 시킵니다.
다음과 같이 사용할 수 있습니다.

enable 번호 - 지정한 번호에 대한 BP를 활성화 시킵니다.
ex) enable 1 - 1번 BP를 활성화 시킵니다.

enable - 모든 BP를 활성화 시킵니다.
ex) enable - 모든 BP를 활성화 시킵니다.

Condition
특정 BP에 조건을 부여할 수 있습니다.
다음과 같이 사용할 수 있습니다.

condition 번호 조건 - 지정한 번호에 대한 BP에 조건을 부여합니다.
ex) condition 1 $eax==5 : 1번 BP는 eax의 값이 5일때만 멈춘다.
ex) condition 1 $eax < 3 : 1번 BP는 eax의 값이 3미만일때만 멈춘다
ex) condition 1 ($eax < 3) && ($ecx > 5) : eax의 값이 3미만이고,
      ecx의 값이 5 초과 일때만 멈춘다.
ex) condition 1 ($eax < 3) || ($ecx > 5) : eax의 값이 3미만이거나,
      ecx의 값이 5촉
ex) condition 1 $eax=5 : 1번 BP가 작동할떄 eax의 값을 5로 만든다.

위의 예 말고도 원하는 특정한 조건일 때 멈추게 할수도 있거니와,
해당 BreakPoint에 걸렸을때 원하는 값으로 Set 시키는 용도로
사용할 수 있는 것입니다.  :)

Debugging중 상태 보기

Info

gdb로 디버깅 중, 현재 Register들의 상태라던지,
설치되어 있는 BreakPoint들의 상태가 궁금할 수 있습니다.
이럴떄 사용하는 명령어가 바로 info 입니다.
다음과 같이 사용할 수 있습니다.

info reg - 모든 레지스터들의 정보 출력
ex) info reg : 모든 레지스터들의 정보 출력

info reg 특정레지스터 - 특정레지스터의 정보 출력
ex) info reg eax - eax의 정보 출력
ex) info reg eax ebx - eax,ebx의 정보 출력

info breakpoints - 모든 BreakPoint들의 정보 출력
ex) info breakpoints - 모든 BreakPoint들의 정보 출력

info breakpoints BP번호 - 특정한 BP번호에 대한 정보 출력
ex) info breakpoints 1 - 1번 BP에 대한 정보 출력

info args - 프로세스가 시작될때 주어진 인자값 출력
ex) info args

info func - 프로세스가 사용하는 함수들에 대한 출력
ex) info func

info frame - 프로세스 프레임에 대한 정보 출력
ex)info frame

info display - 중단될 떄 마다 출력될 display들에 대한 출력
ex) info display

실제로 디버깅 도 중 info 명령을 이용해 정보를 표시해 보겠습니다.

(gdb) break main
Breakpoint 1 at 0x804845a
(gdb) run
Starting program: /home/dual5651/exam1
Breakpoint 1, 0x0804845a in main ()
(gdb) info reg
eax            0x1      1
ecx            0x1      1
edx            0x40156db4       1075146164
ebx            0x401558c0       1075140800
esp            0xbffffad0       0xbffffad0
ebp            0xbffffaf8       0xbffffaf8
esi            0x40016540       1073833280
edi            0xbffffb54       -1073743020
eip            0x804845a        0x804845a
eflags         0x10282  66178
cs             0x23     35
ss             0x2b     43
ds             0x2b     43
es             0x2b     43
fs             0x0      0
gs             0x0      0
(gdb) info breakpoints
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x0804845a <main+6>
       breakpoint already hit 1 time
(gdb)


Display
중단될 떄 마다 특정한 값을 출력하고 싶다면,
display 명령을 사용하면 됩니다.
다음과 같이 사용할 수 있습니다.

display $레지스터 - 특정 레지스터 값을 중단될 떄 마다 출력
ex)display $eax : eax의 값을 중단될 떄 마다 출력

실제로 어떻게 표시되는지 해보겠습니다.

(gdb) watch $eax
1 : $eax = 0
(gdb) nexti
0x080484a2 in main ()
1: $eax = 0
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
1:   y  $eax


Watch

info와 특정한 레지스터의 값이 변경되었을 떄나,
변수의 값이 변경되었을 떄에 그 변경됨을 알고 싶다면,
watch 명령어를 사용할 수 있습니다.
다음과 같이 사용할 수 있습니다.

watch $레지스터 - 특정 레지스터의 값이 변경될 떄.
ex)watch $eax : $eax의 값이 변경될 떄 마다 알림

watch $주소 - 특정 주소의 값이 변경될 떄
ex)watch $804981c : 0x804981c의 값이 변경될때 알림

*watch는 BP와 마찬가지로 info watchpoints를 통해서
목록을 볼 수 있고, break관리에 쓰던 명령들을 쓸 수 있음.

실제로 진행 시켜 보면서 eax의 값이 변경되었을 떄
어떻게 gdb가 표시해주는지 보겠습니다.

(gdb) watch $eax
Watchpoint 2: $eax
(gdb) cont
Continuing.
Watchpoint 2: $eax
Old value = 1
New value = 0
0x08048462 in main ()
(gdb) info watchpoints
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x0804845a <main+6>
       breakpoint already hit 1 time
2   watchpoint     keep y              $eax
       breakpoint already hit 1 time
(gdb)



Printf

printf는 c언어를 해보신 분이라면 다 아는 함수죠.
지정한 형식에 따라 값을 출력해 줍니다.
다음과 같이 사용할 수 있습니다.

printf [“포맷스트링”, 인자1, 인자2, 인자3, ..., 인자n]
ex) printf "%x",$eax :eax 레지스터의 값을 16진수로 표시

x/포맷문자

메모리에 있는 값을 출력해야 할 떄가 있습니다.
그떄 사용하는 것이, x/ 입니다.
다음과 같이 사용할 수 있습니다.

x/x 주소 - 특정한 주소의 값을 16진수로 출력
ex) x/x 0x8048454 : 0x8048454의 값을 16진수로 출력

x/s 주소 - 특정한 주소의 값을 문자열로 출력
ex) x/s 0x8048454 : 0x8048454의 값을 문자열로 출력

x/50x 주소 - 특정한 주소부터 50개 만큼 16진수로 출력
ex) x/50x 0x8048454 : 0x8048454부터 50개만큼 출력

x/c 주소 - 특정한 주소의 값을 문자값으로 출력
ex) x/c 0x8048454 : 0x8048454에 있는 값을 문자로 출력

다 예를 들 수 없어서 이만 생략합니다. :)
실제로 사용하면 어떻게 출력되는지 해보겠습니다.

(gdb) x/s 0x8048680
0x8048680 <_IO_stdin_used+28>:   "Name : "
(gdb) x/10c 0x8048680
0x8048680 <_IO_stdin_used+28>:  78 'N'  97 'a'  109 'm' 101 'e' 32 ' '  58 ':' 32 ' '   0 ''
0x8048688 <_IO_stdin_used+36>:  83 'S'  101 'e'
(gdb) x/5x 0x8048680
0x8048680 <_IO_stdin_used+28>:  0x4e    0x61    0x6d    0x65    0x20
(gdb)


Disas

특정한 주소의 코드가 보고 싶을 떄 사용하는 명령어 입니다.
다음과 같이 사용할 수 있습니다.

disas - 가장 처음 부터 Disassemble한다.
ex) disas

disas 함수 - 특정한 함수만 Disassemble 한다.
ex) disas main

disas 시작주소 끝주소 - 시작주소 부터 끝주소 까지 Disassemble
ex) disas 0x804845c 0x804849d
ex) disas main main+5

Debugging 진행

Nexti

Debugging을 할떄에 step by step을 하며 한줄씩 실행 시켜야
할떄가 있습니다. 그럴 떄 사용하는 명령어가 nexti입니다.
다음과 같이 사용할 수 있습니다.

nexti - 다음 명령어 까지 실행
ex)nexti : 다음 명령어 까지 실행

nexti 갯수 - 갯수 만큼의 명령어 실행
ex)nexti 5 : 5개의 명령어 실행

실제 사용해 보면 다음과 같습니다.

(gdb) nexti
0x0804845d in main ()
(gdb) nexti 5
0x08048477 in main ()
(gdb)

Cont

Debugging을 할때에 다음 BP까지의 명령들은 step by step을
건너 뛰고 싶을때 사용하는 명령어 입니다.
다음과 같이 사용할 수 있습니다.

cont - 다음 BP를 만날떄까지 실행
ex)cont - 다음 BP를 만날떄까지 실행

그 외의 명령어들

set - 특정한 값으로 변경 시킬때 사용합니다.
ex) set $eax=3 : eax의 값을 3으로 만듭니다.

quit - gdb를 종료합니다.
bt - 콜 스택을 보여줍니다.
cd - 작업 폴더 변경
pwd - 현재 폴더 출력
help - 도움말 정보를 출력합니다.
profile

인생은 연극이고 세상은 무대이다!

이솝 임베디드 포럼 운영 및 비즈니스와 관련된 것 이외에 E-Mail이나 메신저 및 휴대폰 등을 통한 개인적인 질문 및 답변은 받지 않습니다. 문의 사항은 이솝 임베디드 포럼 게시판을 이용해 주시면 감사하겠습니다.

엮인글 :
http://www.aesop.or.kr/index.php?mid=Board_Resources_S3C6410&document_srl=36631&act=trackback&key=76a

성인제

2009.03.21 02:50:01
*.83.228.60

오~~ 감사합니다. ^^

노희준

2009.03.21 04:54:41
*.35.144.9

참 고생한 흔적이 많네요. 개발 환경은 최고급이네요 ^^
List of Articles
번호 제목 글쓴이 날짜 조회 수
33 AESOP-6410 : linux-kernel-2.6.21.5 [4] JhoonKim 2009-03-22 4852
32 AESOP-6410 : u-boot-1.1.6 [4] 김재훈 2009-03-22 5213
31 AESOP-6410 : 개발 환경 구성과 케이블 이제현 2009-03-22 6011
30 AESOP-6410 : CP2102 USB to Serial Driver file [2] 김경호 2009-03-22 7548
29 AESOP-6410 : AESOP-6410 회로도 file [10] 이제현 2009-03-22 9052
28 AESOP-6410 : QT/X11 - Hello QT 컴파일 및 실행 방법 [2] 김재훈 2009-03-21 6818
27 AESOP-6410 : 멀티미디어 파일 재생 시험 방법 김재훈 2009-03-21 4990
26 AESOP-6410 : 보드 개발 환경 설정 방법 [1] 김재훈 2009-03-21 8479
25 AESOP-6410 : 자동 시작 프로그램 추가 및 제거 방법 김재훈 2009-03-21 6351
24 AESOP-6410 : 보드 부팅 환경 설정 방법 [2] 김재훈 2009-03-21 9764
23 AESOP-6410 : GTK+ 2.0 - Hello-GTK 샘플 코드 컴파일 방법 [3] 김재훈 2009-03-21 5549
22 AESOP-6410 : AESOP-6410 용 DNW 및 USB Device Driver. file [3] 이제현 2009-03-21 8769
» AESOP-6410 : Native GDB 사용 방법 [2] 김재훈 2009-03-21 5223
20 AESOP-6410 : SSH 및 SSH-Mount를 사용한 파일 전송 file [1] 김재훈 2009-03-21 5202
19 [공유]JAE를 사용하는 나노포커스 2Mega모듈도면입니다. file 신준석 2009-03-18 4866
18 3월 21일 하드웨어 세미나 자료 file 이제현 2009-03-17 4865
17 [공유]Nanofocus 2Mega 카메라모듈 도면입니다. file [4] 신준석 2009-03-17 5134
16 S3C64x0용 H.264 sample 영상 file [5] 고현철 2009-03-17 5390
15 S3C6400 - uBoot, UART Assembly Routine 분석 file [2] 김재훈 2008-08-19 6781
14 S3C6400 - uBoot, lowlevel_init.S 코드 분석 자료 file [6] 김재훈 2008-08-12 7748

사용자 로그인