ちょっくらrubyでgdbつかってみる。
rubyをgdb使って遊んでみる。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