なかだです。

At Sun, 8 Jun 2008 00:27:53 +0900,
Tanaka Akira wrote in [ruby-dev:34988]:
> 以下のようにすると SEGV します。
> 
> % ./ruby -ve '
> e = File.foreach("keywords")
> loop {
>   p e.next
> }
> '

手元で再現できないと思ったら、修正してありました。つまり、Cで作
られたEnumeratorがsvarをアクセスするという、test_knownbugs.rbに
すでにいくつかあるテストのバリエーションです。


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; }
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦