From: Yusuke ENDOH Date: 2009-11-24T23:36:54+09:00 Subject: [ruby-dev:39768] [Bug:trunk] race condition of /#{ foo }/o 遠藤です。 以下のようにすると SEGV します。 $ cat race.rb f = proc {|s| /#{ sleep 1; s }/o } [ Thread.new { f.call("foo"); nil }, Thread.new { sleep 0.5; f.call("bar"); nil }, ].each {|t| t.join } GC.start p f.call $ ./ruby race.rb race.rb:6: [BUG] Segmentation fault ruby 1.9.2dev (2009-11-24 trunk 25908) [i686-linux] -- control frame ---------- c:0004 p:---- s:0011 b:0011 l:000010 d:000010 CFUNC :p c:0003 p:0083 s:0007 b:0007 l:001d8c d:0022e8 EVAL race.rb:6 c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH c:0001 p:0000 s:0002 b:0002 l:001d8c d:001d8c TOP --------------------------- race.rb:6:in `
' race.rb:6:in `p' セグメンテーション違反です onceinlinecache を通ってから setinlinecache に着く前までの間 (= /#{ sleep 1; s }/o の評価が始まってから終わるまでの間) に 複数のスレッドが突入すると、インラインキャッシュのアクセスが race condition になっていて適切にマークされなくなるようです。 解決方法としては、当該範囲がクリティカルセクションになるよう 同期を行うか、または何かをする必要があると思います。 once フラグのある正規表現を複数スレッドで同時に評価した場合の 意味はどうなるでしょうか。 -- Yusuke ENDOH