Jump in rescue clause in eval dumps core

e$B1sF#$H?=$7$^$9!#e(B

1.9 e$B$G8eCVe(B rescue e$B@a$NCf$Ge(B break e$B$de(B next e$B$de(B redo
e$B$r$9$k%3!<%I$re(B
eval e$B$9$k$HMn$A$^$9!#e(B

$ ./ruby -ve ‘eval “0 rescue break”’
ruby 1.9.0 (2007-08-10 patchlevel 0) [i686-linux]
-e:1: – control frame ----------
c:0004 p:---- s:0009 b:0009 l:000008 d:000008 CFUNC :eval
c:0003 p:0009 s:0005 b:0005 l:000004 d:000004 TOP -e:1
c:0002 p:---- s:0003 b:0003 l:000002 d:000002 FINISH :inherited
c:0001 p:---- s:0001 b:-001 l:000000 d:000000 ------

DBG> : “-e:1:in `’”
– backtrace of native function call (Use addr2line) –
0x80dac55
0x80f4093
0x80f415b
0x80b2250
0xffffe420
0x8104206
0x810b14c
0x80cf0f2
0x81028ae
0x81051fd
0x810b11e
0x80cf0f2
0x80cf6c7
0x80cf7f8
0x805b69d
0x805bb15
0x80d156e
0x80d3269
0x80d5de5
0x80d9554
0x80d988b
0x8059229
0x805d79d
0x8056df2
0xb7d6dea8
0x8056d21

[BUG] Segmentation fault
ruby 1.9.0 (2007-08-10) [i686-linux]

e$B%"%!<%H$7$^$7$?e(B (core dumped)

$ ./ruby -ve ‘eval “0 rescue next”’
ruby 1.9.0 (2007-08-10 patchlevel 0) [i686-linux]
-e:1: – control frame ----------
c:0004 p:---- s:0009 b:0009 l:000008 d:000008 CFUNC :eval
c:0003 p:0009 s:0005 b:0005 l:000004 d:000004 TOP -e:1
c:0002 p:---- s:0003 b:0003 l:000002 d:000002 FINISH :inherited
c:0001 p:---- s:0001 b:-001 l:000000 d:000000 ------

DBG> : “-e:1:in `’”
– backtrace of native function call (Use addr2line) –
0x80dac55

(snip)

0x8056d21

[BUG] Segmentation fault
ruby 1.9.0 (2007-08-10) [i686-linux]

e$B%"%!<%H$7$^$7$?e(B (core dumped)

$ ./ruby -ve ‘eval “0 rescue redo”’
ruby 1.9.0 (2007-08-10 patchlevel 0) [i686-linux]
-e:1: – control frame ----------
c:0004 p:---- s:0009 b:0009 l:000008 d:000008 CFUNC :eval
c:0003 p:0009 s:0005 b:0005 l:000004 d:000004 TOP -e:1
c:0002 p:---- s:0003 b:0003 l:000002 d:000002 FINISH :inherited
c:0001 p:---- s:0001 b:-001 l:000000 d:000000 ------

DBG> : “-e:1:in `’”
– backtrace of native function call (Use addr2line) –
0x80dac55

(snip)

0x8056d21

[BUG] Segmentation fault
ruby 1.9.0 (2007-08-10) [i686-linux]

e$B%"%!<%H$7$^$7$?e(B (core dumped)

NODE_BREAK e$B$de(B NODE_NEXT e$B$de(B NODE_REDO e$B$N%3%s%Q%$%k$Ge(B
parent_iseq e$B$re(B
e$B$?$I$k$H$-!"e(Biseq e$B$,e(B ISEQ_TYPE_EVAL
e$B$+$I$&$+$N%A%’%C%/$,$J$+$C$?$j!“e(B
COMPILE_ERROR e$B$,e(B while e$B$NCf$K$”$k$;$$$Ge(B while
e$BD>8e$NM>7W$J%3!<%I$,e(B
e$B<B9T$5$l$F$$$?$j$9$k$?$a$N$h$&$G$9!#e(B

e$B:#8e8e<T$N$h$&$J%_%9$rKI$0$?$a$K!"e(BCOMPILE_ERROR e$B%^%/%m$Ne(B

break e$B$re(B

goto e$B$KJQ$($F$*$/$N$b<j$+$b!)e(B

Index: compile.c

— compile.c (revision 12914)
+++ compile.c (working copy)
@@ -2903,9 +2903,14 @@
}
else {
rb_iseq_t *ip = iseq->parent_iseq;

  •  int error_type_eval = 0;
     while (ip) {
    
    level++;
  • if (ip->compile_data->redo_label != 0) {
  • if (ip->type == ISEQ_TYPE_EVAL) {
  •    error_type_eval = 1;
    
  •    break;
    
  • }
  • else if (ip->compile_data->redo_label != 0) {
    level = 0x8000;
    if (ip->compile_data->loopval_popped == 0) {
    /* need value */
    @@ -2919,7 +2924,12 @@
    }
    ip = ip->parent_iseq;
    }
  •  COMPILE_ERROR((ERROR_ARGS "Illegal break"));
    
  •  if (error_type_eval) {
    
  • COMPILE_ERROR((ERROR_ARGS “Can’t escape from eval with break”));
  •  }
    
  •  else {
    
  • COMPILE_ERROR((ERROR_ARGS “Illegal break”));
  •  }
    
    }
    break;
    }
    @@ -2942,18 +2952,26 @@
    }
    else {
    rb_iseq_t *ip = iseq->parent_iseq;
  •  int error_type_eval = 0;
     while (ip) {
    
    level = 0x8000;
    if (ip->type == ISEQ_TYPE_BLOCK) {
    level |= 0x4000;
    break;
    }
  • else if (ip->type == ISEQ_TYPE_EVAL) {
  •    error_type_eval = 1;
    
  •    break;
    
  • }
    else if (ip->compile_data->redo_label != 0) {
    break;
    }
    ip = ip->parent_iseq;
    }
  •  if (ip != 0) {
    
  •  if (error_type_eval) {
    
  • COMPILE_ERROR((ERROR_ARGS “Can’t escape from eval with next”));
  •  }
    
  •  else if (ip != 0) {
    
    COMPILE(ret, “next val”, node->nd_stts);
    add_ensure_iseq(ret, iseq);
    ADD_INSN1(ret, nd_line(node), throw,
    @@ -2987,19 +3005,24 @@
    else {
    rb_iseq_t *ip = iseq->parent_iseq;
    unsigned long level = 0x8000 | 0x4000;
  •  int error_type_eval = 0;
     while (ip) {
    
    if (ip->type == ISEQ_TYPE_BLOCK) {
    break;
    }
    else if (ip->type == ISEQ_TYPE_EVAL) {
  •    COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with redo"));
    
  •    error_type_eval = 1;
    
  •    break;
    
    }
    else if (ip->compile_data->redo_label != 0) {
    break;
    }
    ip = ip->parent_iseq;
    }
  •  if (ip != 0) {
    
  •  if (error_type_eval) {
    
  • COMPILE_ERROR((ERROR_ARGS “Can’t escape from eval with redo”));
  •  }
    
  •  else if (ip != 0) {
    
    add_ensure_iseq(ret, iseq);
    ADD_INSN1(ret, nd_line(node), throw,
    INT2FIX(level | 0x05) /* TAG_REDO */ );

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

e$B5^$+$9$h$&$G?=$7Lu$"$j$^$;$s$,e(B [ruby-dev:31372]
e$B$NBP=h$r$*4j$$$7$^$9!#e(B

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

Yusuke ENDOH wrote:

e$B5^$+$9$h$&$G?=$7Lu$"$j$^$;$s$,e(B [ruby-dev:31372] e$B$NBP=h$r$*4j$$$7$^$9!#e(B

1.9 e$B$G8eCVe(B rescue e$B@a$NCf$Ge(B break e$B$de(B next e$B$de(B redo e$B$r$9$k%3!<%I$re(B
eval e$B$9$k$HMn$A$^$9!#e(B

e$B!!$&!<$s!$$9$$^$;$s!%$$$m$$$m9M$($F!$e(Bevale$B$NCf$+$i$N6X;$r4KOB$9$k$+e(B
e$B$I$&$+G:$s$G$$$FJ|CV$7$F$$$^$7$?!%:#!$$3$l$K$D$$$F??LLL$K9M$($kM>M5e(B
e$B$,$J$$$N$Ge(B9e$B7nCf$^$G%Z%s%G%#%s%0$H$5$;$F$/$@$5$$!%e(B

e$B!!8=:_$N%P%0$rD>$9!$$H$$$&0UL#$GD:$$$?%Q%C%A$r$"$F$k$Y$-$J$N$+$J$!!%e(B
e$B$&!<$s!%e(B

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

e$B5^$+$9$h$&$G?=$7Lu$"$j$^$;$s$,e(B [ruby-dev:31372] e$B$NBP=h$r$*4j$$$7$^$9!#e(B

1.9 e$B$G8eCVe(B rescue e$B@a$NCf$Ge(B break e$B$de(B next e$B$de(B redo e$B$r$9$k%3!<%I$re(B
eval e$B$9$k$HMn$A$^$9!#e(B

e$B!!$&!<$s!$$9$$^$;$s!%$$$m$$$m9M$($F!$e(Bevale$B$NCf$+$i$N6X;$r4KOB$9$k$+e(B
e$B$I$&$+G:$s$G$$$FJ|CV$7$F$$$^$7$?!%:#!$$3$l$K$D$$$F??LLL$K9M$($kM>M5e(B
e$B$,$J$$$N$Ge(B9e$B7nCf$^$G%Z%s%G%#%s%0$H$5$;$F$/$@$5$$!%e(B

e$B$"!“8!F$Cf$G$7$?$i$$$$$G$9!#8+F($5$l$?$N$+$J!”$H;W$C$?$@$1$J$N$G!#e(B

eval(“next”) e$B$H$+$G$-$?J}$,LLGr$$$+$J$!$H$O;W$$$^$9!#e(B
e$B<B:]$KLr$KN)$A$=$&$JNc$O;W$$$D$-$^$;$s$,!#e(B