読者です 読者をやめる 読者になる 読者になる

CubicLouve

Spring_MTの技術ブログです。https://github.com/SpringMT (http://spring-mt.tumblr.com/ からの移転)

core dump をとった後中身を見てみた(gdbruby編)

ruby gdb

core dumpしても中身みないとしょうもないので、中身の見方をざっくりメモ。

rubyを使ってる場合は、gdbrubyを使うのがオススメです(結局gdbを使うことになるのですが。。。)

環境は、Centos6.2です。

まずはgdbrubyを使ってbacktraceとかをざっくりとみてみる

自分はrbenvを使っているので、下記のコマンドをうちます。

$ gdbruby.rb [core file] `rbenv which ruby`
command:
gdb -silent -nw /path/to/.rbenv/versions/2.1.0/bin/ruby [core file]

environ:

ruby_version:
"2.1.0"

c_backtrace:
#0  0x00007f3a35158885 in raise () from /lib64/libc.so.6
#1  0x00007f3a3515a065 in abort () from /lib64/libc.so.6
#2  0x00007f3a362378fd in rb_bug (fmt=0x7f3a36409cd2 "Segmentation fault at %p") at error.c:341
#3  0x00007f3a36309609 in sigsegv (sig=<value optimized out>, info=0x7f3a39e12fb0, ctx=<value optimized out>) at signal.c:704
#4  <signal handler called>
・
・
・

まあこんなbacktraceがみれます。

ここからは中身を覗いていくためgdbを使っていきます。

打つコマンドは、gdbrubyの出力ででてきた、commandの部分をコピペして使います。

$ gdb -silent -nw /path/to/.rbenv/versions/2.1.0/bin/ruby [core file]
Reading symbols from /path/to/.rbenv/versions/2.1.0/bin/ruby...done.
[New Thread 14085]
[New Thread 14078]
[New Thread 14049]
Missing separate debuginfo for /path/to/.rbenv/versions/2.1.0/lib/ruby/2.1.0/x86_64-linux/enc/encdb.so
・
・
Core was generated by `ruby /path/to/.rbenv/versions/2.1.0/bin/rspec spec/hoge.rb'.
Program terminated with signal 6, Aborted.
#0  0x00007f3a35158885 in raise () from /lib64/libc.so.6
Missing separate debuginfos, use: ・・・・
(gdb) 

と出てきます。

btと打つと、backtraceが取れます。

(gdb) bt
#0  0x00007f3a35158885 in raise () from /lib64/libc.so.6
#1  0x00007f3a3515a065 in abort () from /lib64/libc.so.6
#2  0x00007f3a362378fd in rb_bug (fmt=0x7f3a36409cd2 "Segmentation fault at %p") at error.c:341
#3  0x00007f3a36309609 in sigsegv (sig=<value optimized out>, info=0x7f3a39e12fb0, ctx=<value optimized out>)
    at signal.c:704
#4  <signal handler called>
・
・

backtraceがとれたら、frameを移動します。 例えば、#2に移動する場合は、下記のようにします。

(gdb) frame 2
#2  0x00007f3a362378fd in rb_bug (fmt=0x7f3a36409cd2 "Segmentation fault at %p") at error.c:341

で、frame 2の変数fmtの中身が見たい場合は、

(gdb) p fmt
$3 = 0x7f3a36409cd2 "Segmentation fault at %p"

みたいにします。 メモリの内容を表示したい場合は、xコマンドを使います。

まだgdb丁稚なので、これくらいしか今のところしか使ってないです。。。。

その他

value optimized outって出ているのは、最適化されてしまって見れなくなっている値です。ruby-buildでrubyコンパイルしてると、デフォルトだと-O3で最適化されちゃっています。

ちなみに、rubyコンパイルオプションはこんな感じで調べました。

$ ruby -r rbconfig -e 'RbConfig::CONFIG.sort.each { |c| p c }'
・
["optflags", "-O3 -fno-fast-math"]
・
・

最適化のオプションとか渡してrbenv installコンパイルする場合は、RUBY_CFLAGSを設定すればよさそうです(実際にやってない)。

C拡張のモジュールの場合は、extconf.rb内で$CFLAGSを使えばできそうです。

あと、0x4はRubynilだそうです。