ダンプされたcoreを元にエラー原因を解析する方法
Railsアプリを書いてる場合はあまり関係ないですが、
セグメンテーションエラー(SEGV)などに遭遇した場合に、
原因を調査する方法を紹介します。
まずは、coreを吐かせるためにulimitの設定をします。
sh>>
% ulimit -c
0
% ulimit -c unlimited
% ulimit -c
unlimited
<<--
ulimit -cが0になっている場合は、coreを吐かないので、
適当な値を設定するか、unlimitedにします。
あとは、プログラムを実行してランタイムエラーを引き起こし、
coreファイルを出力させます。
sh>>
% ./command
zsh: segmentation fault (core dumped) ./command
<<--
さて、今度はgdbの出番です。
gdbは対話型のデバッガです。
以下のように、gdbにオプションを指定して起動します。
pre>>
% gdb ./command --core=./core
.. snip ..
Core was generated by `./command'.
Program terminated with signal 11, Segmentation fault.
#0 0x08048a43 in vec_sub (a=0x804e248, b=0xbfa9e720) at vec.c:124
124 const __m128 t_vec5 = (*a) ;
(gdb)
<<--
すると、上記のように対話セッションが開始されます。
あとは、表示された内容や、gdbのコマンドを使って原因を解析すればOKです。
例えば上記の出力の例では、aのアドレスが16バイト境界に乗っていないのが
原因であることが推察できます。
ソースコードが手元にある場合は、gccに-gオプションをつけてコンパイル
することで、lコマンドによって以下のようにエラーが発生した場所の周辺の
ソースコードを見たりすることができるようになります。
pre>>
(gdb) l
119 return t_vec3 ;
120 }
121
122 __m128 vec_sub (const __m128 * a, const __m128 * b)
123 {
124 const __m128 t_vec5 = (*a) ;
125 const __m128 t_vec4 = (*b) ;
126 const __m128 t_vec6 = _mm_sub_ps( t_vec5 , t_vec4 ) ;
127 return t_vec6 ;
128 }
<<--
gdbを終了する場合は、qコマンドを実行します。