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