ちょっくらrubyでgdbつかってみる。

rubygdb使って遊んでみる。rubyのbinaryは${HOME}/bin/rubyにあるとする。

まぁ、とりあえずbinaryの設定も説明しておくと、こんな感じで設定する

wget ftp://core.ring.gr.jp/pub/lang/ruby/1.9/ruby-1.9.0-0.tar.gz
tar zxvf ftp://core.ring.gr.jp/pub/lang/ruby/1.9/ruby-1.9.0-0.tar.gz
cd ruby-1.9.0-0
./configure --prefix=${HOME} && make && make install

以上でbinaryが${HOME}/binにできあがるわけである。

そして、emacs内でgdbを起動。(emacs内以外でもgdbはつかえるが、めんどくさいし、ソースが見れないし、いいことない)

$M-x gdb

fileコマンドでバイナリを読み込む

(gdb)file ~/bin/ruby

つぎにbreakpoint および 実行内容について考える。

breakpointに何を設定すればいいかわからないので、とりあえずrubyのソースを読み適当な関数を探す。

というわけで、以下のような関数を発見した。

str_alloc

この関数は、文字列を生成するときにまず使用されると予想されるので、この関数をbreak pointとする

(gdb) b str_alloc

と、こんな感じでbreakpointを設定する。つぎは実行処理について考える。とりあえず今回stringがでてくる処理を考えればよさそうである。というわけで、以下のようなコマンドにしておく

ruby -e 'p "aho"'

gdbないではrubyコマンドがそのまま、runに置き換えられるので、実行する内容は以下のようになる。

(gdb)r(run) -e 'p "aho"'

とりあえず実行してみる。するとgdbとソースの位置が変更され、以下のようなメッセージが出てくる

[Thread debugging using libthread_db enabled]
[New Thread 0xb7da36c0 (LWP 25449)]
[Switching to Thread 0xb7da36c0 (LWP 25449)]

Breakpoint 6, str_alloc (klass=0) at string.c:162
(gdb)

とりあえずstr_allocにきたようである。とりえあずどういった経由で、ここまでたどり着いたか知るためにbtコマンドを実行する

(gdb) bt
#0  str_alloc (klass=0) at string.c:162
#1  0x080c79ae in str_new (klass=0, ptr=0x8134fab "", len=0) at string.c:186
#2  0x080c80e7 in rb_enc_str_new (ptr=0x8134fab "", len=0, enc=0x8171d78) at string.c:209
#3  0x080872e7 in rb_intern3 (name=0x8134fab "", len=0, enc=0x8171d78) at parse.y:8988
#4  0x08087748 in rb_intern2 (name=0x8134fab "", len=0) at parse.y:8998
#5  0x0808781e in Init_sym () at parse.y:8753
#6  0x0806918b in rb_call_inits () at inits.c:60
#7  0x0805d7fd in ruby_init () at eval.c:86
#8  0x08057f08 in main (argc=3, argv=0xbfb073a4, envp=0xbfb073b4) at main.c:35

こんな感じになる. これからどうしようか。。。 うーむ. かんがえておこう(w