sysvbannerをGDBで動かしながら理解していこうかと思います。まずはソースを落としてきます。
takk@deb83:~$ apt-get source sysvbanner (省略) takk@deb83:~$ cd sysvbanner-1.0.15/ takk@deb83:~/sysvbanner-1.0.15$
GDBでデバッグするために、Makefileに-gオプションを付けます。元のMakefileはこのようになっていますので、
takk@deb83:~/sysvbanner-1.0.15$ cat -n Makefile
1 DESTDIR=
2
3 BIN=banner
4 SRC=$(BIN).c
5 MAN=$(BIN).1
6
7 $(BIN): $(SRC)
8 $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
9
10 install: $(BIN) $(MAN)
11 install -d $(DESTDIR)/usr/bin
12 install -m 755 $(BIN) $(DESTDIR)/usr/bin
13 install -d $(DESTDIR)/usr/share/man/man1
14 install -m 644 $(MAN) $(DESTDIR)/usr/share/man/man1
15
16 clean:
17 $(RM) $(BIN)
takk@deb83:~/sysvbanner-1.0.15$
8行目を、以下ように修正しておきます。
8 $(CC) -g $(CFLAGS) $^ -o $@ $(LDFLAGS)
では、makeします。
takk@deb83:~/sysvbanner-1.0.15$ make cc -g banner.c -o banner takk@deb83:~/sysvbanner-1.0.15$
GDBを起動しましょう。引数をbannerにして、gdbを実行します。
takk@deb83:~/sysvbanner-1.0.15$ gdb banner GNU gdb (Debian 7.7.1+dfsg-5) 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 "i586-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 banner...done. (gdb)
「list」(省略形「l」)を実行すると、ソースが確認できます。
(gdb) l
123 " # # # # # # # # # # ",
124 " # # # ###### ### # ### # # # #"};
125
126
127 int main(int argc, char **argv)
128 {
129 int a, b, c, len, ind;
130 char line[80];
131
132 for (argv++; --argc; argv++) {
(gdb)
10行しか表示されませんが、続きを見たいときは、Enterを押します。
(gdb)
133 len = strlen(*argv);
134 if (len > 10)
135 len = 10;
136 for (a = 0; a < 7; a++) {
137 for (b = 0; b < len; b++) {
138 if ((ind = (*argv)[b] - ' ') < 0)
139 ind = 0;
140 for (c = 0; c < 7; c++) {
141 line[b * 8 + c] = glyphs[(ind / 8 * 7) + a][(ind % 8 * 7) + c];
142 }
(gdb)
デフォルトではmain関数から表示されますので、ソースの他の場所を見たいときは、「list 行番号」を実行すれば良いです。
ただし、存在しない行番号を指定した場合は、以下のように注意されます。
(gdb) l 200 Line number 195 out of range; banner.c has 155 lines. (gdb)
一度表示したソースがまた見たくなった時は、「list 行番号」または「list 関数名」で表示すれば良いです。
(gdb) l main
123 " # # # # # # # # # # ",
124 " # # # ###### ### # ### # # # #"};
125
126
127 int main(int argc, char **argv)
128 {
129 int a, b, c, len, ind;
130 char line[80];
131
132 for (argv++; --argc; argv++) {
(gdb)
実行する前に、ブレイクポイントを設定します。「break 行番号」(省略形「b」)または「break 関数名」で設定できます。
(gdb) b main Breakpoint 1 at 0x8048440: file banner.c, line 132. (gdb)
では、実行してみましょう。「run 引数」(省略形「r」)で実行できます。
(gdb) r HELLO
Starting program: /home/takk/sysvbanner-1.0.15/banner HELLO
Breakpoint 1, main (argc=2, argv=0xbffff794) at banner.c:132
132 for (argv++; --argc; argv++) {
(gdb)
終了するには、「quit」(省略形「q」)を実行し、
(gdb) q A debugging session is active. Inferior 1 [process 30503] will be killed. Quit anyway? (y or n)
とにかく辞めるかと聞かれるので、yと答えれば良いです。
Quit anyway? (y or n) y takk@deb83:~/sysvbanner-1.0.15$
続く


コメント
[…] ← sysvbannerの動きをGDBで追う(GDBの起動) […]