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, Segmentation fault.
7 #0 0x08048a43 in vec_sub (a=0x804e248, b=0xbfa9e720) 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
コマンドを実行します。