関連: RubyのC拡張でSEGVおこした時の追い方、またはデバグ手法

https://github.com/mirakui/activerecord-mysql-index-hint.git の spec を流すと SEGV が起きるらしいので追いたい

gcc のオプションを -O0 -ggdb3 にして DEBUG シンボル付きにした方がほうが SEGV 追いやすいので、オプション付きで ruby を build する。ruby-build でやる場合はこう。オプション -k はソースコードを残して置くやつ

env RUBY_CFLAGS="-O0 -ggdb3" rbenv install 2.3.0 -k

コア吐かせる準備をしておく

$ ulimit -c unlimited

プログラム実行して SEGV 発生させる。すると core.{pid} なファイルができているはず。

ruby のパスと core ファイルを指定して gdb を起動し、backtrace を表示する

$ gdb `rbenv which ruby` core.24476
(gdb) bt
#0  0x00007f8532bc1625 in raise () from /lib64/libc.so.6
#1  0x00007f8532bc2e05 in abort () from /lib64/libc.so.6
#2  0x00007f8533dffc0b in die () at error.c:407
#3  0x00007f8533dffea8 in rb_bug_context (ctx=0x7f853466cbc0, fmt=0x7f8533e37eaf "Segmentation fault at %p") at error.c:437
#4  0x00007f8533d0da8c in sigsegv (sig=11, info=0x7f853466ccf0, ctx=0x7f853466cbc0) at signal.c:890
#5  <signal handler called>
#6  free_root (root=0x7f8535e79640, MyFlags=<value optimized out>) at my_alloc.c:365
#7  0x00007f852883160c in free_old_query (mysql=0x7f8535e79340) at client.c:838
#8  0x00007f8528831d3d in mysql_close (mysql=0x7f8535e79340) at client.c:2767
#9  0x00007f8528807cd1 in nogvl_close (ptr=0x7f8535e73010) at client.c:215
#10 0x00007f8528807dbe in decr_mysql2_client (wrapper=0x7f8535e73010) at client.c:252
#11 0x00007f8528807d2b in rb_mysql_client_free (ptr=0x7f8535e73010) at client.c:228
#12 0x00007f8533c68503 in run_final (objspace=0x7f85345feae0, zombie=140210098535240) at gc.c:2675
#13 0x00007f8533c6858b in finalize_list (objspace=0x7f85345feae0, zombie=140210098535240) at gc.c:2691
#14 0x00007f8533c6865c in finalize_deferred (objspace=0x7f85345feae0) at gc.c:2712
#15 0x00007f8533c687d7 in rb_objspace_call_finalizer (objspace=0x7f85345feae0) at gc.c:2778
#16 0x00007f8533c68796 in rb_gc_call_finalizer_at_exit () at gc.c:2764
#17 0x00007f8533c4ec40 in ruby_finalize_1 () at eval.c:130
#18 0x00007f8533c4f0a4 in ruby_cleanup (ex=6) at eval.c:221
#19 0x00007f8533c4f31b in ruby_run_node (n=0x7f8534c4c8e8) at eval.c:301
#20 0x00007f8533c4d169 in main (argc=2, argv=0x7fffe6e0f7a8) at main.c:36

補足: core じゃなくて直接追いたい場合はこう (rspec 流すと segv してた)

$ bundle exec gdb `rbenv which ruby`
(gdb) run -S rspec spec

sigsegv がおきた次のフレームに移動して変数の中身などを表示する

(gdb) frame 6
#6  free_root (root=0x7fde44360080, MyFlags=<value optimized out>) at my_alloc.c:365
365 my_alloc.c: そのようなファイルやディレクトリはありません.
    in my_alloc.c

あれ。my_alloc.c って ruby 本体じゃないなコレ ....

libmysqlclient っぽいので http://dev.mysql.com/downloads/connector/c/ からソースコードをダウンロード ...