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の起動) […]