Create TOC

2000년 5월 26일

gdb

조건

gdb로 디버깅하기 위해서는 gcc에 -g 옵션을 주고 컴파일해야 한다.

실행

gdb <실행파일명>

종료

quit

변수값 확인

print 변수명

Break/Watchpoints

breakpoint 설정

간단 설정

break <줄번호|함수명>

조건부 설정

break <줄번호> if <조건>

이미 설정된 breakpoint에 조건을 설정하려면 아래와 같이 하면 된다.

condition <break 번호> <조건>

breakpoint 목록 보기

info break

watchpoint 설정

watch <변수명|조건>

한줄씩 실행

한줄씩 실행. 함수 호출시 함수 내부로 들어가지 않는다.

next or n

한줄씩 실행. 함수 호출시 함수 내부로 들어간다.

step or s

계속 실행

continue

Stack trace

stack 출력

bt

출력 형식은 아래와 같다.

#frame번호 주소 in 함수명(인자) at 파일명:줄번호

예)

(gdb) bt
#0  0x80483ea in sum (a=8, b=8) at main.c:7
#1  0x8048435 in main (argc=1, argv=0xbffff9c4) at main.c:21

frame 이동

frame <frame번호>
up or down

지역변수 확인

info locals

예) backtrace 에서 특정 stack의 지역변수를 확인할때?

(gdb) frame 1
(gdb) info locals

Attach Process

gdb <실행파일명> <pid>

Palm/POSE와 gdb를 이용한 디버깅

prc-tools를 사용하면 m68k-palm-gdb를 사용해서 디버깅을 해야 한다.

디버깅을 위한 빌드

-g 옵션을 이용해 빌드한다.

# m68k-palmos-gcc -g -c hello.c -o hello.o
# m68k-palmos-gcc -g hello.o -o hello

이렇게 빌드하면 hello.prchello가 생성된다.

POSE 실행

POSE를 실행한다.

gdb 실행 및 설정

아래와 같이 m68k-palm-gdb를 실행한다.

# m68k-palmos-gdb hello
GNU gdb 5.3
Copyright 2002 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.
Thpe "show copyping" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
this GDB was configured as "--host=i686-pc-cygwin --target=m68k-palmos"...
(gdb)

gdb prompt 에서 아래와 같이 입력한다.

(gdb) target pilot localhost:6414
Remote debugging under PalmOS using localhost:6414
Waiting... (Press Ctrl-C to connect to halted machine)

디버깅

위 단계를 모두 거쳤으면 POSE에 hello.prc 를 설치하고 실행한다. hello.prc를 실행하는 순간 gdb에 아래와 같은 화면이 나온다.

Program received signal SIGSTOP, Stopped (signal).
0x00045888 in PilotMain (cmd=3, cmdPBP=0xa2260000, launchFlags=68) at hello.c:20
20 {
(gdb)

이제 디버깅을 하면 된다.

2000년 5월 15일

C++/Virtual Destructor

아래와 code를 보자.

class Sample {
public:
 Sample() { cout << "Sample" << endl; }
 ~Sample() { cout << "~Sample" << endl; }

};

class Derived : public Sample {
public:
 Derived() { cout << "Derived" << endl; }
 ~Derived() { cout << "~Derived" << endl; }
};


int main(int argc, char **argv)
{
 Sample *p = new Derived;

 delete p;
 return 0;
}

수행결과는 어떨까? 아마도

Sample
Derived
~Derived
~Sample

가 되어야 할 것처럼 보인다. 하지만 실제 수행해보면

Sample
Derived
~Sample

Derived의 destructor가 호출되지 않는 것을 볼 수 있다. 그 이유는 포인터 p는 Sample class 형 포인터 이기 때문에 Derived의 destructor을 알지 못한다. 따라서 위에 delete p 할 때 Sample의 destructor만을 호출하게 된다.

이 문제를 해결하기 위해서는 Simple class 에서 destructor 선언시 virtual 을 사용해야 한다.

virtual ~Sample() { cout << "~Sample" << endl; }