[Bug: trunk] Fiber transfer limitation

e$B!!$5$5$@$G$9!%e(B

e$B!!e(B1.9.2 e$B$KF~$l$FM_$7$$e(B Fiber
e$B$K4X$9$k;EMMJQ99$K$D$$$F!$0l$DK:$l$F$$$^$7$?!%e(B

e$B!!8=:_!$e(BFiber#transfer e$B$He(B Fiber.yield/Fiber#resume
e$B$O0l=o$K;H$&$J!$;H$Ce(B
e$B$FJQ$J$3$H$,5/$-$F$bCN$i$J$$$h!$$H$$$&N)>l$r<h$C$F$$$^$9!%$H$$$&$N$b!$0le(B
e$B=o$K;H$&$H4JC1$Ke(B SEGV e$B$5$;$k$3$H$,=PMh$k$+$i$G$9!%e(B

e$BNc!'e(B

require ‘fiber’
f2 = nil

f1 = Fiber.new{
p :f1_start
f2.resume
p :f1_end
}

f2 = Fiber.new{
p :f2_start
f1.resume
p :f2_end
}

f1.transfer

#=>
ruby 1.9.2dev (2010-03-16 trunk 26952) [i386-mswin32_90]
:f1_start
:f2_start
:f1_end
:f2_end
[BUG] Segmentation fault

e$B!!Nc$($PA0<T$,=PMh$k%/%i%9$re(B Coroutinee$B!$8e<T$,=PMh$k%/%i%9$re(B
SemiCoroutine
e$B$H$7$FDs6!$7$F:.$<$J$$$h$&$K$9$k$H$$$&<jCJ$b$"$k$N$G$9$,!$e(B
e$BBg%/%i%9<g5A$Ne(B Ruby e$B$H$O$J$8$_$^$;$s!%e(B

e$B!!$=$3$G!$e(BFiber#resume e$B$r$7$?!$$D$^$je(B Fiber.yield
e$B$9$k@h$,$"$ke(B Fiber e$B$Ke(B
e$B4X$7$F$Oe(B transfer e$B$r6X;_$7$h$&$H;W$$$^$9!%$^$?!$0lEY$G$be(B
Fiber#transfer
e$B$5$l$?@h$Ne(B Fiber e$B$re(B resume
e$B=PMh$J$$$h$&$K$7$h$&$H;W$$$^$9!%e(B

e$B$A$g$C$H!$$3$N@)8B$G==J,$J$N$+!$8!F$$,B-$j$F$J$$$s$G$9$,!%e(B

e$B!!Nc$@$H!$e(Bf1.resume e$B$N;~E@$GNc30$,Ht$V$3$H$K$J$j$^$9!%e(B

e$B!!:.$<$k$J4m81!$$H$7$F$$$?$H;W$&$N$G!$$3$NJQ99$G:$$k?M$O$"$s$^$j$$$J$$$se(B
e$B$8$c$J$$$+$J$!$H;W$$$^$9!%$H$$$&$+!$e(BSEGV
e$B$9$k%P%0$J$N$G2sHr$7$J$-$ce(B
e$B$J$!!$$H$$$&46$8$G$9!%e(B

e$B!!%P%?%P%?$H$9$_$^$;$s$,!$$48!F$2<$5$$!%e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:40833] [Bug: trunk] Fiber transfer limitation”
on Tue, 30 Mar 2010 04:19:56 +0900, SASADA Koichi [email protected]
writes:

|e$B!!e(B1.9.2 e$B$KF~$l$FM_$7$$e(B Fiber e$B$K4X$9$k;EMMJQ99$K$D$$$F!$0l$DK:$l$F$$$^$7$?!%e(B
|
|e$B!!8=:_!$e(BFiber#transfer e$B$He(B Fiber.yield/Fiber#resume e$B$O0l=o$K;H$&$J!$;H$Ce(B
|e$B$FJQ$J$3$H$,5/$-$F$bCN$i$J$$$h!$$H$$$&N)>l$r<h$C$F$$$^$9!%$H$$$&$N$b!$0le(B
|e$B=o$K;H$&$H4JC1$Ke(B SEGV e$B$5$;$k$3$H$,=PMh$k$+$i$G$9!%e(B

|e$B!!$=$3$G!$e(BFiber#resume e$B$r$7$?!$$D$^$je(B Fiber.yield e$B$9$k@h$,$"$ke(B Fiber e$B$Ke(B
|e$B4X$7$F$Oe(B transfer e$B$r6X;_$7$h$&$H;W$$$^$9!%$^$?!$0lEY$G$be(B Fiber#transfer
|e$B$5$l$?@h$Ne(B Fiber e$B$re(B resume e$B=PMh$J$$$h$&$K$7$h$&$H;W$$$^$9!%e(B

e$B0EL[$N6X;$O%I%-%e%a%s%H$K=q$$$F$bC/$bFI$^$J$$$N$Ge(B(e$B$$$$$9e(B
e$B$.!)e(B)e$B!"L@<(E*$K6X;
$9$k$N$ONI$$$3$H$G$O$J$$$+$H;W$$$^$9!#e(B

e$B%A%1%C%He(B #3050 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$B%+%F%4%je(B coree$B$K%;%C%He(B
e$BC4Ev<Te(B Koichi Sasadae$B$K%;%C%He(B
Target version 1.9.2e$B$K%;%C%He(B
ruby -v -e$B$K%;%C%He(B

e$B1sF#$G$9!#e(B

e$B!!8=:_!$e(BFiber#transfer e$B$He(B Fiber.yield/Fiber#resume e$B$O0l=o$K;H$&$J!$;H$Ce(B
e$B$FJQ$J$3$H$,5/$-$F$bCN$i$J$$$h!$$H$$$&N)>l$r<h$C$F$$$^$9!%$H$$$&$N$b!$0le(B
e$B=o$K;H$&$H4JC1$Ke(B SEGV e$B$5$;$k$3$H$,=PMh$k$+$i$G$9!%e(B

e$B:.$<$k$HM}2r:$Fq$J5sF0$K$J$k$N$O3N$+$J$s$G$9$,!“e(BSEGV
e$B$9$k$H$Oe(B
e$BCN$j$^$;$s$G$7$?!#e(B
e$B$3$NNc$K4X$7$F$O!”:G8e$N%Q%C%A$Ge(B SEGV
e$B$O$7$J$/$J$k$H;W$$$^$9!#e(B

e$B!!Nc$($PA0<T$,=PMh$k%/%i%9$re(B Coroutinee$B!$8e<T$,=PMh$k%/%i%9$re(B
SemiCoroutine e$B$H$7$FDs6!$7$F:.$<$J$$$h$&$K$9$k$H$$$&<jCJ$b$"$k$N$G$9$,!$e(B
e$BBg%/%i%9<g5A$Ne(B Ruby e$B$H$O$J$8$_$^$;$s!%e(B

e$BBg%/%i%9<g5A$O!V35G0E*$K;w$F$$$k$b$N$KJ#?t$N%/%i%9$r:n$i$J$$!We(B
e$B$@$H;W$$$^$9!#e(B
Coroutine e$B$He(B SemiCoroutine
e$B$O<BAu$O$[$H$s$I6&DL$7$F$$$k$b$N$N!"e(B
e$B35G0E*$K$O$+$J$j0[$J$C$F$$$k$H46$8$^$9!#e(Bgoto e$B$He(B function
call
e$B$/$i$$$K$O0c$$$^$9$h$M!#e(B
e$B$J$N$G!“JL$NL>A0$K$7$F$b$h$+$C$?$s$8$c$J$$$+$J$”!#:#99$G$9$,!#e(B

[ruby-dev:31596] e$B0JMh!“e(Btransfer
e$B$OMQES$,$o$+$i$J$$$o$j$K:.Mp$re(B
e$B>7$/$H8@$&!VI432$”$C$F0lMx$J$7!W$@$H;W$&$N$G!"$J$1$l$P$h$+$C$?e(B
e$B$N$K$H;W$C$F$$$^$9!#e(B

diff --git a/cont.c b/cont.c
index 185d812…b4b486d 100644
— a/cont.c
+++ b/cont.c
@@ -945,9 +945,15 @@ fiber_switch(VALUE fibval, int argc, VALUE *argv,
int is_resume)
}
else if (fib->status == TERMINATED) {
value = rb_exc_new2(rb_eFiberError, “dead fiber called”);

  • if (th->fiber != fibval) rb_exc_raise(value);
  • fibval = fib->prev;
  • if (NIL_P(fibval)) fibval = th->root_fiber;
  • if (th->fiber != fibval) {
  •  GetFiberPtr(th->fiber, fib);
    
  •  if (fib->status != TERMINATED) rb_exc_raise(value);
    
  •  fibval = th->root_fiber;
    
  • }
  • else {
  •  fibval = fib->prev;
    
  •  if (NIL_P(fibval)) fibval = th->root_fiber;
    
  • }
    GetFiberPtr(fibval, fib);
    cont = &fib->cont;
    cont->argc = -1;


Yusuke E. [email protected]

http://redmine.ruby-lang.org/issues/show/3050

e$B%A%1%C%He(B #3050 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$B%9%F!<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B
e$B?JD=e(B % 0e$B$+$ie(B100e$B$KJQ99e(B

This issue was solved with changeset r27713.
Koichi, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


http://redmine.ruby-lang.org/issues/show/3050

e$B!!$5$5$@$G$9!%e(B

(2010/05/03 22:57), Yusuke E. wrote::

e$B!!8=:_!$e(BFiber#transfer e$B$He(B Fiber.yield/Fiber#resume e$B$O0l=o$K;H$&$J!$;H$Ce(B
e$B$FJQ$J$3$H$,5/$-$F$bCN$i$J$$$h!$$H$$$&N)>l$r<h$C$F$$$^$9!%$H$$$&$N$b!$0le(B
e$B=o$K;H$&$H4JC1$Ke(B SEGV e$B$5$;$k$3$H$,=PMh$k$+$i$G$9!%e(B

e$B:.$<$k$HM}2r:$Fq$J5sF0$K$J$k$N$O3N$+$J$s$G$9$,!“e(BSEGV e$B$9$k$H$Oe(B
e$BCN$j$^$;$s$G$7$?!#e(B
e$B$3$NNc$K4X$7$F$O!”:G8e$N%Q%C%A$Ge(B SEGV e$B$O$7$J$/$J$k$H;W$$$^$9!#e(B

e$B!!?7$7$$;EMM$r9M$($k$N$O$7$s$I$=$&$@$7!$e(BSEGV
e$B$7$J$/$J$l$P$H$j$"$($:NI$$e(B
e$B$H;W$$$^$9$N$G!$1sF#$5$s$r?.$8$^$9!%e(B
e$B!!e(B

[ruby-dev:31596] e$B0JMh!“e(Btransfer e$B$OMQES$,$o$+$i$J$$$o$j$K:.Mp$re(B
e$B>7$/$H8@$&!VI432$”$C$F0lMx$J$7!W$@$H;W$&$N$G!"$J$1$l$P$h$+$C$?e(B
e$B$N$K$H;W$C$F$$$^$9!#e(B

e$B!!e(Bcontinuation e$B$H9g$o$;$F!$e(Bgem
e$B$H$+$KDI$$=P$7$A$c$($P$h$+$C$?$+$J$!!%e(B

e$B!!$A$J$_$K!$e(BControl flow
e$B$r@)8f$9$k!$$H$$$&0UL#$G!$;d$NCf$G$O$d$C$Q$jF1e(B
e$B$8$b$N$C$F%+%F%4%j!<$K!%e(B