ソフトウェア設計及び演習2017

Emacs上でのGDBの使用

Emacs上でのGDBの使用

バグがあるソーティングプログラムtest2.cをダウンロードする.

以下のように,ソースファイルをコンパイルして実行ファイルを作る.

$ gcc test2.c -g -o test2

実行してみると,「Segmentation fault」を表示するバグが発生した.

 ./test2
3       2       1
Segmentation fault

Emacs を立ち上げて,C-x 3 で Emacs のウィンドウを左右に分割する.

ソース用ウィンドウで test2.c ファイルを開く.以下のように,もう一回ソースファイルをコンパイルして実行ファイルを作る.

M-x compile
gcc test2.c -g -o test2

C-x o でデバッグ用ウィンドウへ移動する.

以下のコマンドで gdb を使用して,Emacs の上でデバッグしてみる.

M-x gdb 

そして,以下の実行コマンドが自動的に表示される.「Enter」キーを押して,gdb を起動させる.

Run gdb (like this): gdb -- annotate=3 test2

run コマンドでプログラムを実行して,バグが発生した場所を調べる.

(次に「#」で囲まれた部分が表示されない.その代わりに,ソース用ウィンドウの左側に,現在の行を指す矢印が表示される.)

(gdb) r
Starting program: /home/staff/luxin/OLD/program1/test2
3       2       1

Program received signal SIGSEGV, Segmentation fault.
0x000000000040058a in sort (x=0x601028, n=3) at test2.c:13
+13                  if (x[j-1] > x[j]) {#

continue コマンドを使用してプログラムの最後まで実行する.

(gdb) c
Continuing.

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.

バグが発生した13行目にブレークポイントを設定すして,再びrun コマンドでプログラムを実行する,

(gdb) b 13
Breakpoint 1 at 0x40056a: file test2.c, line 13.
(gdb) r
Starting program: /home/staff/luxin/OLD/program1/test2
3       2       1

Breakpoint 1, sort (x=0x601028, n=3) at test2.c:13
+13                  if (x[j-1] > x[j]) {#

watch コマンドで変数 j の書き込みを監視する.

(gdb) wa j
Hardware watchpoint 2: j

continue コマンドを3回使用する.変数 j を書き込み時に,内容の変化を調べる.

(gdb) c
Continuing.
Hardware watchpoint 2: j

Old value = 2
New value = 3
0x00000000004005df in sort (x=0x601028, n=3) at test2.c:12
+12              for (j = n-1; j > i; j++) {#
(gdb) c
Continuing.

Breakpoint 1, sort (x=0x601028, n=3) at test2.c:13
+13                  if (x[j-1] > x[j]) {#
(gdb) c
Continuing.
Hardware watchpoint 2: j

Old value = 3
New value = 4
0x00000000004005df in sort (x=0x601028, n=3) at test2.c:12
+12              for (j = n-1; j > i; j++) {#

変数 j が減らないので,いつも条件 j > i を満たしている.無限ループが発生する.

info breakpoints コマンドによって,設定されたすべてのポイントを表示して, delete コマンドでポイントを削除する.

(gdb) i b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000040056a in sort at test2.c:13
        breakpoint already hit 2 times
2       hw watchpoint  keep y                      j
        breakpoint already hit 2 times
(gdb) d 1
(gdb) d 2

continue コマンドを使用してプログラムの最後まで実行して,quit コマンドで gdb を終了させる.

(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x000000000040058a in sort (x=0x601028, n=3) at test2.c:13
+13                  if (x[j-1] > x[j]) {#
(gdb) q

最後に,C-x o でソース用ウィンドウへ移動する. 13行目にある「j++」を「j--」に書き直す.


最終更新日:2017/04/03 09:14:19