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

スタックの検査(backtrace, frame)

スタックの検査 [backtrace, frame]

プログラムにおいて,ある関数に対する1回の呼び出しが発生した場所,関数への引数,関数内部のローカル変数などを含む情報は,スタック・フレームと呼ばれるメモリ域に保存される.

先ほどと同様に,実行ファイルを引数として gdb を起動させる.

$ gdb test1
...

change 関数にブレークポイントを設定する.

(gdb) break change
Breakpoint 1 at 0x400688: file test1.c, line 34.

run コマンドでプログラムを実行して,continue コマンドを2回使用する.

(gdb) run
Starting program: /home/staff/luxin/OLD/program1/test1
3       2       1

Breakpoint 1, change (x=0x601028, j=2) at test1.c:34
34                 j-1, x[j-1], j, x[j]);
(gdb) continue
Continuing.
x[1] = 2 <-> x[2] = 1

Breakpoint 1, change (x=0x601028, j=1) at test1.c:34
34                 j-1, x[j-1], j, x[j]);
(gdb) continue
Continuing.
x[0] = 3 <-> x[1] = 1
1       3       2

Breakpoint 1, change (x=0x601028, j=2) at test1.c:34
34                 j-1, x[j-1], j, x[j]);

backtrace コマンドを実行することによって,フレームの要約情報を表示する. 表示されたフレームは,プログラムが現在いる場所にどのように到達したかを示す.

(gdb) backtrace
+0  change (x=0x601028, j=2) at test1.c:34
+1  0x00000000004005a4 in sort (x=0x601028, n=3) at test1.c:15
+2  0x00000000004006f3 in main () at test1.c:39

各関数を中心として、そのまわりの10行を表示する.

(gdb) list 34
29          printf("\n");
30      }
31
32      void change(int x[], int j) {
33          printf("x[%d] = %d <-> x[%d] = %d\n",
34                 j-1, x[j-1], j, x[j]);
35      }
36
37      void main(void) {
38          show(x, NUM);

frame コマンドを使用して,任意のフレームについての情報を取得する.

(gdb) frame 0
+0  change (x=0x601028, j=2) at test1.c:34
34                 j-1, x[j-1], j, x[j]);
(gdb) print j
$1 = 2
(gdb) frame 1
+1  0x00000000004005a4 in sort (x=0x601028, n=3) at test1.c:15
15                      change(x, j);
(gdb) print j
$2 = 2
(gdb) frame 2
+2  0x00000000004006f3 in main () at test1.c:39
39          sort(x, NUM);
(gdb) print j
No symbol "j" in current context.

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

(gdb) continue
Continuing.
x[1] = 3 <-> x[2] = 2
1       2       3

Program exited with code 02.
(gdb) quit


最終更新日:2015/03/05 10:01:20