[Bug:1.9] SEGV by File.foreach("keywords")

e$B0J2<$N$h$&$K$9$k$He(B SEGV e$B$7$^$9!#e(B

% ./ruby -ve ’
e = File.foreach(“keywords”)
loop {
p e.next
}

ruby 1.9.0 (2008-06-07 revision 16875) [i686-linux]
“%{\n”
“struct kwtable {const char *name; int id[2]; enum lex_state_e
state;};\n”
-e:4: [BUG] Segmentation fault
ruby 1.9.0 (2008-06-07 revision 16875) [i686-linux]

– stack frame ------------
0000 (0xb7ac2008): 00000004
0001 (0xb7ac200c): 00000001
0002 (0xb7ac2010): 00000004
0003 (0xb7ac2014): 00000001
0004 (0xb7ac2018): 0819c320
0005 (0xb7ac201c): 00000004
0006 (0xb7ac2020): 00000001
0007 (0xb7ac2024): 00000004
0008 (0xb7ac2028): 00000004
0009 (0xb7ac202c): b7b41f75
0010 (0xb7ac2030): 00000004
0011 (0xb7ac2034): b7ac2021 (= 6)
0012 (0xb7ac2038): 00000004
0013 (0xb7ac203c): 0819c320
0014 (0xb7ac2040): 00000004
0015 (0xb7ac2044): 00000001 <- lfp <- dfp
– control frame ----------
c:0007 p:---- s:0016 b:0016 l:000015 d:000015 CFUNC :next
c:0006 p:0010 s:0013 b:0012 l:000006 d:000011 BLOCK -e:4
c:0005 p:---- s:0012 b:0012 l:000011 d:000011 FINISH :class_eval
c:0004 p:---- s:0010 b:0010 l:000009 d:000009 CFUNC :loop
c:0003 p:0024 s:0007 b:0007 l:000006 d:000006 TOP -e:3
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
:private_class_method
c:0001 p:0000 s:0002 b:0002 l:000001 d:000001 TOP :17

DBG> : “-e:4:in next'" DBG> : "-e:4:inblock in '”
DBG> : “-e:3:in loop'" DBG> : "-e:3:in'”
– backtrace of native function call (Use addr2line) –
0x810b7ba
0x8132e9e
0x8132efb
0x80cb360
0xb7f5d440
0x80ff7d2
0x81035eb
0x810850e
0x805aaf7
0x80fa193
0x8105fb3
0x80ff7d2
0x81035eb
0x81037e3
0x805a10c
0x805a1af
0x8058ba5
0xb7dbeea8
0x8058aa1

e$B$J$+$@$G$9!#e(B

At Sun, 8 Jun 2008 00:27:53 +0900,
Tanaka A. wrote in [ruby-dev:34988]:

e$B0J2<$N$h$&$K$9$k$He(B SEGV e$B$7$^$9!#e(B

% ./ruby -ve ’
e = File.foreach(“keywords”)
loop {
p e.next
}

e$B<j85$G:F8=$G$-$J$$$H;W$C$?$i!"=$@5$7$F$"$j$^$7$?!#$D$^$j!“e(BCe$B$G:ne(B
e$B$i$l$?e(BEnumeratore$B$,e(Bsvare$B$r%”%/%;%9$9$k$H$$$&!“e(Btest_knownbugs.rbe$B$Ke(B
e$B$9$G$K$$$/$D$+$”$k%F%9%H$N%P%j%(!<%7%g%s$G$9!#e(B

Index: vm.c

— vm.c (revision 17037)
+++ vm.c (working copy)
@@ -99,11 +99,12 @@ rb_control_frame_t *
vm_get_ruby_level_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
{

  • while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
  • if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
  •  return cfp;
    
  • }
  • if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) return 0;
  • while (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
    cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
  • if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
  •  return RUBY_VM_NEXT_CONTROL_FRAME(cfp);
    
  • }
    }
  • return 0;
  • return cfp;
    }

@@ -527,4 +528,7 @@ vm_cfp_svar_get(rb_thread_t *th, rb_cont
while (cfp->pc == 0) {
cfp++;

  • if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
  •  return lfp_svar_get(th, 0, key);
    
  • }
    }
    return lfp_svar_get(th, cfp->lfp, key);
    @@ -536,4 +540,8 @@ vm_cfp_svar_set(rb_thread_t *th, rb_cont
    while (cfp->pc == 0) {
    cfp++;
  • if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
  •  lfp_svar_set(th, 0, key, val);
    
  •  return;
    
  • }
    }
    lfp_svar_set(th, cfp->lfp, key, val);
    Index: vm_insnhelper.c
    ===================================================================
    — vm_insnhelper.c (revision 17037)
    +++ vm_insnhelper.c (working copy)
    @@ -843,21 +843,16 @@ static inline NODE *
    lfp_svar_place(rb_thread_t *th, VALUE *lfp)
    {
  • NODE *svar;
  • VALUE *svar;
  • if (th->local_lfp != lfp) {
  • svar = (NODE *)lfp[-1];
  • if ((VALUE)svar == Qnil) {
  •  svar = NEW_IF(Qnil, Qnil, Qnil);
    
  •  lfp[-1] = (VALUE)svar;
    
  • }
  • if (lfp && th->local_lfp != lfp) {
  • svar = &lfp[-1];
    }
    else {
  • svar = (NODE *)th->local_svar;
  • if ((VALUE)svar == Qnil) {
  •  svar = NEW_IF(Qnil, Qnil, Qnil);
    
  •  th->local_svar = (VALUE)svar;
    
  • }
  • svar = &th->local_svar;
  • }
  • if (NIL_P(*svar)) {
  • *svar = (VALUE)NEW_IF(Qnil, Qnil, Qnil);
    }
  • return svar;
  • return (NODE *)*svar;
    }