2014年04月

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

cool.io という Ruby C拡張ライブラリをいじっていて SEGV 起こしてしまったので追いたい。

gcc のオプションを -O0 -ggdb3 にしたほうが SEGV 追いやすいとのことなので、Makefile 吐いていじる

$ ruby ext/cool.io/extconf.rb
$ vim Makefile

おまけ:Makefile いじって gcc のオプションに --savetemps を足すと、プリコンパイルを通した結果の .i ファイルが作られる。プリコンパイル結果を追いたい場合捗る。

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

$ ulimit -c unlimited

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

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

$ gdb `rbenv which ruby` core.2101
(gdb) bt
#0  0x00d98410 in __kernel_vsyscall ()
#1  0x00138df0 in raise () from /lib/libc.so.6
#2  0x0013a701 in abort () from /lib/libc.so.6
#3  0x006a0877 in rb_bug (fmt=0x6d19b5 "Segmentation fault") at error.c:309
#4  0x005c0e86 in sigsegv (sig=11, info=0x959461c, ctx=0x959469c) at signal.c:672
#5  <signal handler called>
#6  ev_feed_event (loop=0x96a08e0, w=0xb7c0a844, revents=256) at ../../../../ext/cool.io/../libev/ev.c:1702
#7  0x004b0eeb in timers_reify (loop=0x96a08e0, flags=2) at ../../../../ext/cool.io/../libev/ev.c:1725
#8  ev_run (loop=0x96a08e0, flags=2) at ../../../../ext/cool.io/../libev/ev.c:3460
#9  0x004a9d3d in ev_loop (argc=1, argv=0xb7c8d01c, self=154926840) at ../../../../ext/cool.io/../libev/ev.h:826
#10 Coolio_Loop_run_once (argc=1, argv=0xb7c8d01c, self=154926840) at ../../../../ext/cool.io/loop.c:226
#11 0x006269b5 in call_cfunc_m1 (func=0x4a9c50 <Coolio_Loop_run_once>, recv=154926840, argc=1, argv=0xb7c8d01c) at vm_insnhelper.c:1325
#12 0x0062c22c in vm_call_cfunc_with_frame (th=0x96fca08, reg_cfp=0xb7d0cfb8, ci=<value optimized out>) at vm_insnhelper.c:1469
#13 0x0063d40d in vm_exec_core (th=0x96fca08, initial=<value optimized out>) at insns.def:1017
#14 0x00642b27 in vm_exec (th=0x96fca08) at vm.c:1201
#15 0x00643ecb in invoke_block_from_c (th=0x96fca08, proc=0x9645ec8, self=154913200, defined_class=147225780, argc=0, argv=0x93bfc6c, blockptr=0x0) at vm.c:648
#16 vm_invoke_proc (th=0x96fca08, proc=0x9645ec8, self=154913200, defined_class=147225780, argc=0, argv=0x93bfc6c, blockptr=0x0) at vm.c:696
#17 0x00657e33 in thread_start_func_2 (th=0x96fca08, stack_start=<value optimized out>) at thread.c:512
#18 0x0065804e in thread_start_func_1 (th_ptr=0x96fca08) at thread_pthread.c:765
#19 0x0083c852 in start_thread () from /lib/libpthread.so.0
#20 0x001e3a8e in clone () from /lib/libc.so.6

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

(gdb) frame 6
#6  ev_feed_event (loop=0x96a08e0, w=0xb7c0a844, revents=256) at ../../../../ext/cool.io/../libev/ev.c:1702
1702        pendings [pri][w_->pending - 1].events |= revents;
(gdb) p w
$1 = (void *) 0xb7c0a844
(gdb) p pendings
$2 = {0x0, 0x0, 0x9687ed8, 0x0, 0x0}
(gdb) p pri
$3 = 6832926
(gdb) p w_->pending
Cannot access memory at address 0x4

0x4 は ruby の nil らしいので、そこがおかしい

ToDo: watchpoint 張って追いかける

てきとうで cool な favicon を作る

社内で運用しているツールにはすべからく favicon を付けて、ブックマークバーの幅を節約したい。

こちらのページで1文字アイコンが簡単に作れるので便利。
http://box.aflat.com/buttonmaker/
ef6ec5a6ea1522f926637406f4351e51
余白があると favicon として見た目が良くないのでテキストサイズを大きめにするなどして調整すると良い(by 自称 favicon 職人)

あとは画像を ico に変換してくれるサイトは一杯あるので、どれかを使えばよい
http://ao-system.net/favicon/index.php
とか

A Ruby and Fluentd committer working at DeNA. 記事本文および記事中のコード片は引用および特記あるものを除いてすべて修正BSDライセンスとします。 #ruby #fluentd #growthforecast #haikanko #yohoushi #specinfra #serverspec #focuslight
はてぶ人気エントリー