観察日記 2010-11-25

今日は「Ruby 1.8.7 の新パッチリリースが12月25日公開予定」や「blade復活」、「JIS Ruby 意見受付公告」と、トピックの多い一日でした。

SEGV 時の C level backtrace

<nurse> C level backtrace全部出るようにしませんか
<shyouhei> 全部というと
<nurse> 行数もほしいある
<shyouhei> そりゃポータブルには取れない
<shyouhei> パッチあったら突っ込んでいいですよ
<nurse> 途中抜けてるのはなに?
<shyouhei> おれもほしいから。
<nurse> なるほろ
<shyouhei> Mac死ねってことにしてELFだけなんとかすればwin32系はそのうちうささんが何とかする気もちょっと
<shyouhei> 途中抜けてるのは最適化された関係で関数がインライン展開されたとかがありうる。
<yugui> gdbが取ってるんだからo-machも取れば取れるんだろうな。
<yugui> あと変なオブジェクト形式というとAS/400
<shyouhei> gdbは単にaddr2line(1)からひっぱてきてるのではないか疑惑
<shyouhei> man> addr2line
{util_mput} addr2line http://tinyurl.com/2w4kxt6
<nurse> http://0xcc.net/blog/archives/000073.html ふむ
{util_mput} 普通のやつらの下を行け: BFDでデバッグ情報の取得 - bkブロ... http://tinyurl.com/2fjxeml
<nurse> win32はすでになんかできてたような、行数は無理だっけ
<shyouhei> http://reality.sgiweb.org/davea/dwarflicense.html libdwarfがLGPLらしいのでこれがあるならlinkするとかいう選択肢はあるかもしれない。
{util_mput} DA's DWARF Page http://tinyurl.com/22u4eva
<n0kada> SEGVしたらデバッガを走らせるとか
<shyouhei> デバッガが存在するという仮定はおかしい。
<n0kada> もちろんあるときだけで
<shyouhei> 我々はなぜSEGVのバックトレース情報を充実させようとしているのか?
<n0kada> 日常的に必要だから
<shyouhei> 普段からデバッガがある環境で生きてる人間なら普段からgdb --argsで生きればいい
<shyouhei> そうじゃないでしょう
<shyouhei> redmineに報告されてくる情報を多くしたいからじゃないの
<shyouhei> つまり想定ユーザーは俺らじゃない。
<shinh_____> gdbのaddr2lineはaddr2line(1)より効率的にやってたと思いますどうでもいいですが
<n0kada> じゃ常に最適化禁止で
<shyouhei> 最適化されてたらredmineに報告しろっていう最後のを出さないようにするのはありかもとちょっと思う
<nurse> debianだったら-dbg入れろって言うとか
<shyouhei> gccなら定数見たら最適化かかってるか分かる
<shyouhei> __OPTIMIZE__だっけ
<nurse> ほう
<n0kada> http://msdn.microsoft.com/en-us/library/b0084kay%28VS.80%29.aspx を見ると
<n0kada> VCにはなさげ
<shyouhei> マクロ以外で調べれるのかもしらんけどね
<n0kada> Makefile.subかconfigureでoptflagsを調べりゃ
<shyouhei> とも限らない。
<shyouhei> gccには__attribute__((optimize(...)))という凶悪な機能があるので
<n0kada> 別に完璧を求めなくてもいいんじゃね
<shyouhei> ま、gccなら定数見るのが簡単かつ完璧なんじゃないですか。
<n0kada> ついでに最適化を切るとか
<shyouhei> 最適化されてるかどうか知るのに比べて最適化切るのはさらに輪をかけて難しそう
<n0kada> デフォルトを-O3から-O0に変えるだけ
<ko1_ndk> glibc の backtrace に比べ、addr2line のほうがリッチな出力を出したと思う
<ko1_ndk> で、gdb のほうがもっとリッチ
<shyouhei> gdbまで必要ないので
<shyouhei> 過不足なく情報が取れればOK
<n0kada> そういやgithubはまだ止まってんの
<shyouhei> * 行数が知りたい
<shyouhei> * static関数も見たい
<shyouhei> の二点だけ満たされればいいよ
<ko1_ndk> addr2line に突っ込めば、その点は満たされなかったっけ
<shyouhei> libelfとlibdwarfでだいたいいけそうなきがするよ
<shinh_____> libdwarf とか使わん方がラクくらいの勢いですけどね…
<ko1_ndk> そうなんだ
<shinh_____> 結局状態機械回すとか自分でやる必要があったような
<shyouhei> とりあえずドキュメントはなさそうというところまでは確認した。
<ko1_ndk> PCは表引きできる?
<ko1_ndk> PC->行番号
<shinh_____> ELF 用の addr2line とかだけならこのへんに昔書いたのが https://github.com/shinh/test/blob/1f58c3c370e690595f3d2e0d12d4ed8e8aafab55/addr2line.cc
<shinh_____> libdwarfってDWARF読むところまでだったと思うんで
<shinh_____> 読んでから解釈しなきゃならんかったと思うんですよね
<ko1_ndk> なるほど
<ko1_ndk> やっぱ gdb 呼ぶのが早いんじゃないか
<shinh_____> 正しいと思いますね
<shinh_____> SEGV したら gdb attach させるとかで普通に便利
<shyouhei> まあ開発者はそれで便利ですね
<shyouhei> バグ報告にはてんで役に立たないけど。
<shinh_____> gdb -p -ex 'bt' -ex 'p "Please send the above stacktrace"' とかなら…
<shinh_____> --eval-command=COMMAND, -ex みたいな感じで

<shinh_____> なんかこないだ話題になってた ELF 用に backtrace に行情報足すってやつ適当にやってみたんですが需要あるんですかね… http://shinh.skr.jp/t/ruby-addr2line.patch
<nurse> とりあえずわたしがうれしい
<nurse> なんかSEGVさせてみた
<shinh_____> ちゃんと出てますかね全然テストしてないので動かなくても不思議はない感じですが
<nurse> そしてびるどできない
<nurse> FreeBSDじゃだめかしら
{nurse} ../../ruby/addr2line.c: In function 'fill_lines':
{nurse} ../../ruby/addr2line.c:365: error: 'Ehdr' undeclared (first use in this function)
{nurse} ../../ruby/addr2line.c:365: error: (Each undeclared identifier is reported only once
{nurse} ../../ruby/addr2line.c:365: error: for each function it appears in.)
{nurse} ../../ruby/addr2line.c:365: error: 'ehdr' undeclared (first use in this function)
{nurse} ../../ruby/addr2line.c:365: error: expected expression before ')' token
{nurse} ../../ruby/addr2line.c:366: error: 'Shdr' undeclared (first use in this function)
{nurse} ../../ruby/addr2line.c:366: error: 'shdr' undeclared (first use in this function)
{nurse} ../../ruby/addr2line.c:366: error: expected expression before ')' token
{nurse} ../../ruby/addr2line.c:368: error: 'shstr_shdr' undeclared (first use in this function)
{nurse} ../../ruby/addr2line.c:371: error: 'debug_line_shdr' undeclared (first use in this function)
<shinh_____> あー ElfW が無いのか…
<shinh_____> すいません自分で定義せにゃいかんですね
<nurse> Elf32_Ehdrとかはいるっぽいな
<shinh_____> ええ # if SIZEOF_VOIDP == 8
<shinh_____> # define ElfW(x) Elf64##_##x
<shinh_____> # else
<shinh_____> # define ElfW(x) Elf32##_##x
<shinh_____> # endif
<shinh_____> あたりを足すといい気がします
<nurse> なるほど
<nurse> 通った通った
<shinh_____> FreeBSD だとたぶん dl_iterate_phdr 無いからうまくいくとしても共有オブジェクトとかの行出ないですね…
<nurse> 全く行数が出なかった
<nurse> 残念
<shinh_____> zannnen
<nurse> 気を取り直してUbuntu
<shinh_____> そもそも 32bit とかテストしてないなーとかいう感じで動く気がしないですね…
<shinh_____> 僕もいろんなとこで遊んでみます…
<nurse> 32bit環境はわたしもまともに持ってないので大丈夫です(ぉぃ
<nurse> おー、でたでた
<shinh_____> それはよかった
<shinh_____> とりあえずさくらが FreeBSD なんでちょいと見てみます
<nurse> よろしぅ
<shinh_____> そもそもさくらの FreeBSD は execinfo.h が無くて backtrace すら出ないと判明…
<nurse> portsからdevel/libexecinfoを入れるのです
<shinh_____> なるほどさくらの環境で ports はきつそうだから今度自分で野良ビルドしてみますかね…
<shinh_____> というか FreeBSD 入ってる qemu イメージの2つや3つはどっかにありそうだ
<nurse> 普通にportsいけたよぅ
<nurse> あ、FreeBSDででない原因わかった、
<nurse> backtrace_symbolsの出すsymsのフォーマットが想定と違う(ゎ
<nurse> ちなみに、dl_iterate_phdrはある
<nurse> でた!
<nurse> っと思ったらminirubyでしかでないな
<nurse> fill_linesにも仮定があった
<shinh_____> fill_base_addr も同じようなことやってるのでご注意を…
<nurse> ふむ、動くようになった、が
<nurse> rubyからしか取れないので非常に嬉しくないな
<nurse> (librubyからとれない)
<shinh_____> fill_base_addr の方もなおされました?
<nurse> 直したつもりなんですが
<shinh_____> じゃあなんかまだ別の問題があるんですね…
<shinh_____> shared object がダメなのはそのへんがあやしい…

<nurse> info->dlpi_nameに"libruby.so.19"しか入ってなかった
...
<nurse> でた!
<nurse> http://nalsh.jp/patches/addr2line.patch FreeBSDでも動くようにした

バグ報告のOSごと内訳

<nurse> とりあえず報告の数十%はdebianな気がするので入れたい派
<shinh_____> そのへんの比率は興味あるんですけど報告者数で見ると linux > win > mac な感じとかなんですか
<shinh_____> それとも普通に win が多いのかな…
<nurse> 感覚的にそんな感じ
<nurse> linuxがwinの倍で、macとwinが同じくらいじゃないかなぁ
<shinh_____> なるほどやはり linux mac が世間の比に比べて多いわけですね
<nurse> ruby -v欄で絞り込めた
<nurse> linux474 darwin285 mswin182 mingw124
<nurse> ちなみにbsd48
<shinh_____> 体感がだいたいあってる感じですね…
<nurse> 今のが1.9で、Ruby全体にするとlinux749 darwin425 mswin251 mingw183か
<nurse> まぁ、傾向は同じ、linuxの差が開いてるかな