gdb手順
使用するコード
適当に。
/*test3.c*/
#include
int sub();
int main(){
printf("main\n");
sub();
return 0;
}
int sub(){
printf("sub\n");
return 0;
}
ただこの関数にいますよーって表示するだけのプログラム。
コンパイル
-gオプションを付けてコンパイルする。
%gcc -g -o test3 test3.c
%ls
test.c test3.dSYM test3
なんかへんなファイルが増えてる。こいつが gdb で読むのに必要。
gdb起動
gdbを起動する。引数は実行ファイル。
%gdb test
GNU gdb 6.3.50-20050815 (Apple version gdb-1705) (Fri Jul 1 10:50:06 UTC 2011)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries .. done
(gdb)
上は起動直後。(gdb)の後に gdb 用のコマンドを打ち込んで使う。今はプログラムが止まっている状態。ここから、ブレークポイントを設定しプログラムを run する。
(gdb) b sub
Breakpoint 1 at 0x100000ec4: file test3.c, line 12.
ブレークポイントの設定。b は break の b。b の後には、関数名やメソッド名、行数などが入る。今回は関数 sub を使用。
(gdb) r
Starting program: /Users/User/programing/C/test3
Reading symbols for shared libraries +........................ done
main
Breakpoint 1, sub () at test3.c:12
12 printf("sub\n");
上は起動。これでプログラムが動き、sub で止まった状態になる。
次は list 機能 l を試す。
(gdb) l
7 sub();
8 return 0;
9 }
10
11 int sub(){
12 printf("sub\n");
13 return 0;
14 }
(gdb)
プログラムのコードが見れる。
次はこれを進めていく。
step の s を使用する。
(gdb) s
sub
13 return 0;
少し進んだ。コード中の
printf("sub\n");
も実行されている。(gdb)
main () at test3.c:8
8 return 0;
s を再実行。ただエンターキーを押すだけで、前回実行したものを実行できる。覚えておくと便利。
(gdb)
Cannot access memory at address 0x0
0x0000000100000e74 in start ()
continue の c で、プログラムを終了や次のブレークポイントまで飛ばす。
(gdb) c
Continuing.
Program exited normally.
これでプログラムが終了。
プログラムが終ってしまったので、最実行する。次はブレークポイントを3行目に設定。
(gdb) b 3
Breakpoint 2 at 0x100000e84: file test3.c, line 3.
info b で ブレークポイントの情報が見れる。下のように表示される。
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000100000ec4 in sub at test3.c:12
2 breakpoint keep y 0x0000000100000e84 in main at test3.c:3
breakpoint already hit 1 time
このブレークポイントを、番号を指定して消去することができる。
delete の d のあとに、info b で見たブレークポイントの番号を指定すると消去。
(gdb) d 1
(gdb) info b
Num Type Disp Enb Address What
2 breakpoint keep y 0x0000000100000e84 in main at test3.c:3
breakpoint already hit 1 time
next の n は関数へ入らない。関数を読み飛ばす事ができる。
以下はブレークポイント2はそのままで最実行し、コマンド n を実行した時のもの。
(gdb) n
main
7 sub();
(gdb)
sub
8 return 0;
関数 sub() に入らず、main 関数の return 0; へ進んでいる。
次は finish/fin の使用例。これも一旦終わらせて、ブレークポイントを sub() のなか(12行目)に設定して新しく run した後に fin を実行している。
(gdb) fin
Run till exit from #0 sub () at test3.c:12
sub
main () at test.c:8
8 return 0;
Value returned is $1 = 0
fin は今いる関数を終わらせるものである。上記の例では関数 sub の中で始まっているが、fin を実行すると sub() が終了している。
(gdb) where
#0 sub () at test3.c:12
#1 0x0000000100000ea0 in main () at test3.c:7
これも、ブレークポイントが12行目の関数 sub() の中のままのもの。
where は関数を積んでいるスタックを見るものである。スタックなので、一番初めに読む main が下に来ており、次に sub() が着ている。
関数 test.c に以下の行を追加する。
int = i;
print の p で変数表示。以下が上の i を p で表示した結果である。
(gdb) p i
$1 = 3
以上、大体これくらいわかってればいいっぽい。アセンブラをはかすなら
(gdb)disas(gdb) disas
Dump of assembler code for function main:
0x0000000100000e80
0x0000000100000e81
0x0000000100000e84
0x0000000100000e88
0x0000000100000e8f
0x0000000100000e96
0x0000000100000e99
0x0000000100000e9e
0x0000000100000ea0
0x0000000100000ea2
0x0000000100000ea7
0x0000000100000eae
0x0000000100000eb1
0x0000000100000eb4
0x0000000100000eb7
0x0000000100000ebb
0x0000000100000ebc
End of assembler dump.
とかあったりもする。
ここまで見るのはバイナリハッカーとか言うらしい。なりたい。
とりあえず今日はここまで。
コメント
コメントを投稿