From: "naruse (Yui NARUSE)" Date: 2012-06-08T05:19:41+09:00 Subject: [ruby-dev:45711] [ruby-trunk - Bug #6556] ネストした配列の inspect で segv Issue #6556 has been updated by naruse (Yui NARUSE). ko1 (Koichi Sasada) wrote: > (2012/06/08 0:36), naruse (Yui NARUSE) wrote: > > ./miniruby -e'10000.times.inject(x=[]){|a,|a<<(b=[]);b};x.inspect' > > で segv します。 > > > > > > % ./miniruby -e'10000.times.inject(x=[]){|a,|a<<(b=[]);b};x.inspect'|&less > > -e:1: [BUG] Segmentation fault > > ruby 2.0.0dev (2012-06-06 trunk 35950) [x86_64-freebsd9.0] > > マシンスタックのオーバーフローなので,もうしょうがない気がしますが..., > マシンスタックの深さを何かでチェックする? マシンスタックのオーバーフローでも本来 SEGV をキャッチして SystemStackError 例外があがるはずです。 で、どうも thread_pthread.c の ruby_stack_overflowed_p での stack overflow 判定に 失敗しているのが理由のようです。もっと特定すると、 if (addr > (void *)((char *)base - size) && addr <= base) return 1; の base - size がちょっと大きいのが理由で、要するに size が小さすぎます。 理由は、メインスレッドのスタックサイズは ruby_init_stack() が由来なのですが、 最後で、以下の通りあらかじめ size を減らしているため、その誤差で取りこぼしているようです。 space = size > 5 * 1024 * 1024 ? 1024 * 1024 : size / 5; native_main_thread.stack_maxsize = size - space; なので、この誤差を補正するといアプローチの場合、例えば size = size / (size == native_main_thread.stack_maxsize ? 4 : 5); あるいは size /= 4; とすればよいようです。 ---------------------------------------- Bug #6556: ネストした配列の inspect で segv https://bugs.ruby-lang.org/issues/6556#change-27078 Author: naruse (Yui NARUSE) Status: Open Priority: Normal Assignee: Category: Target version: ruby -v: ruby 2.0.0dev (2012-06-06 trunk 35950) [x86_64-freebsd9.0] ./miniruby -e'10000.times.inject(x=[]){|a,|a<<(b=[]);b};x.inspect' で segv します。 % ./miniruby -e'10000.times.inject(x=[]){|a,|a<<(b=[]);b};x.inspect'|&less -e:1: [BUG] Segmentation fault ruby 2.0.0dev (2012-06-06 trunk 35950) [x86_64-freebsd9.0] -- Control frame information ----------------------------------------------- c:3116 p:---- s:6234 b:6234 l:006233 d:006233 CFUNC :inspect c:3115 p:---- s:6232 b:6232 l:006231 d:006231 CFUNC :inspect c:3114 p:---- s:6230 b:6230 l:006229 d:006229 CFUNC :inspect (中略) c:0005 p:---- s:0012 b:0012 l:000011 d:000011 CFUNC :inspect c:0004 p:---- s:0010 b:0010 l:000009 d:000009 CFUNC :inspect c:0003 p:0041 s:0007 b:0007 l:001458 d:002430 EVAL -e:1 c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH c:0001 p:0000 s:0002 b:0002 l:001458 d:001458 TOP -e:1:in `
' -e:1:in `inspect' -e:1:in `inspect' (中略) -e:1:in `inspect' -e:1:in `inspect' -- C level backtrace information ------------------------------------------- 0x44c8bd at /home/naruse/obj/ruby/miniruby ../../ruby/error.c:269 0x44c9d8 at /home/naruse/obj/ruby/miniruby ../../ruby/error.c:288 0x518181 at /home/naruse/obj/ruby/miniruby ../../ruby/signal.c:577 0x800ca7723 <_pthread_sigmask+707> at /lib/libthr.so.3 0x800ca7897 <_pthread_sigmask+1079> at /lib/libthr.so.3 0x7ffffffff003 -- Other runtime information ----------------------------------------------- * Loaded script: -e * Loaded features: 0 enumerator.so [NOTE] You may have encountered a bug in the Ruby interpreter or extension libraries. Bug reports are welcome. For details: http://www.ruby-lang.org/bugreport.html zsh: abort (core dumped) ./miniruby -e'p 10000.times.inject(x=[]){|a,|a<<(b=[]);b};x.inspect' -- http://bugs.ruby-lang.org/