Issue #5386 has been reported by Kazuki Tsujimoto.

----------------------------------------
Bug #5386: FiberオブジェクトのGC時にSEGV
http://redmine.ruby-lang.org/issues/5386

Author: Kazuki Tsujimoto
Status: Open
Priority: Normal
Assignee: Kazuki Tsujimoto
Category: core
Target version: 
ruby -v: ruby 1.9.4dev (2011-10-01 trunk 33368) [x86_64-linux]


=begin
辻本です。

ポータブルな再現コードが作れていないのですが、
Ubuntu 10.04 x86_64にて以下のコードを実行すると
FiberオブジェクトをGCする処理の中でSEGVします。

 require 'fiber'
 
 1.times {
   Fiber.new{}
 }
 
 2.times.map {|i|
   Thread.new {
     Fiber.new{}.resume
   }.join
 }.each {|t|
   t.join
 }
 
 GC.start
 GC.stress = true
 
 1.times {
   Fiber.new{}
 }

バックトレースを添付します。

調べてみたところ、GC.stress設定後の1回目のマークフェーズで

 Breakpoint 2, fiber_mark (ptr=0xad7130) at cont.c:265
 (gdb) rp ((rb_fiber_t*)ptr)->cont->saved_thread.self
 T_DATA(VM/thread): $1 = (struct RTypedData *) 0xaaf528

となっているFiberオブジェクトが、2回目のマークフェーズでは

 Breakpoint 2, fiber_mark (ptr=0xad7130) at cont.c:265
 (gdb) rp ((rb_fiber_t*)ptr)->cont->saved_thread.self
 T_NONE: $2 = (struct RBasic *) 0xaaf528

となっており、saved_thread.selfのマーク漏れのようです。

以下の修正で直りました。

 diff --git a/vm.c b/vm.c
 index 665351b..2ab2b92 100644
 --- a/vm.c
 +++ b/vm.c
 @@ -1735,6 +1735,7 @@ rb_thread_mark(void *ptr)
  	RUBY_MARK_UNLESS_NULL(th->first_proc);
  	if (th->first_proc) RUBY_MARK_UNLESS_NULL(th->first_args);
  
 +	RUBY_MARK_UNLESS_NULL(th->self);
  	RUBY_MARK_UNLESS_NULL(th->thgroup);
  	RUBY_MARK_UNLESS_NULL(th->value);
  	RUBY_MARK_UNLESS_NULL(th->errinfo);
=end



-- 
http://redmine.ruby-lang.org