以下のプログラムを対象にしてcdbの使い方を紹介してみます。
char msg[] "Hello world";今日ではデバッグする時にはccに「-g」オプションをつけますが、当時のccには特別なオプションは要りません。実行ファイルがa.outであれば、cdbはデフォルトで読み込みます。まずmain()にブレークポイントをかけて、実行してみます。
func(p)
char *p;
{
printf("%s\n", p);
}
main()
{
int i;
for (i = 0; i < 10; i++)
func(msg);
}
# cdbさらにfunc()にもブレークポイントをかけて、一時停止している実行を再開します。
main%b
%r
Breakpoint: main+4
func%bfunc()で実行が一時停止していますので、スタックトレースを見てみます。
%c
Breakpoint: func+4
$func()の引数pはスタック上に割り当てられています。その内容はmsg[]の先頭アドレスです。
Trace/BTP
0: func(01232)
1: main()
func:p=func()の先頭から逆アセンブルしてみます。またレジスタの値も見てみます。
0177744
func:p/
01232
func:p"
Hello world
func,5?ブレークポイントは関数の先頭にかけることが多いかもしれませんが、任意の位置にかけることもできます。ただし今日のデバッガのように親切ではないので、かけ間違えても何のメッセージも出ませんし、うまくブレークポイントにかからないかもしれません。
func: jsr r5,csv
mov 04(r5),(sp)
mov $msg+12,-(sp)
jsr pc,*$printf
tst (sp)+
$r
Trace/BTP
ps 0170004
pc 036 func+06
sp 0177730
r5 0177740
r4 0
r3 0
r2 0
r1 0
r0 034 func+04
func+12%bcdbのコマンド体系は、UNIX V6にもうひとつあるデバッガdbに似ています。しかしdbにはデバッガを抜けるためのコマンドが用意されているのに、cdbにはありません。しかたないので^Dでcdbを抜けるしかありません。
cdb(I)には以下のような記述があります。当時のマシン環境の常識が分からないので、意味がよく理解できないのですが、「no advance planning is necessary to use it」とわざわざ断っているのは、当時のデバッグでは何か特別な「planning」が必要だったということなのでしょうか。
An important feature of cdb is that even in the interactive case no advance planning is necessary to use it; in particular it is not necessary to compile or load the program in any special way nor to include any special routines in the object file.
0 件のコメント:
コメントを投稿