[Ruby 1.9 - Bug #369] (Open) Ruby 1.9.0-3$B$G(B R

e$B%A%1%C%He(B #369 e$B$,Js9p$5$l$^$7$?!#e(B (by Akira M.)


Bug #369: Ruby 1.9.0-3e$B$Ge(B R
http://redmine.ruby-lang.org/issues/show/369

e$B5/I<<Te(B: Akira M.
e$B%9%F!<%?%9e(B: Open
e$BM%@hEYe(B: Normal
e$BC4Ev<Te(B: Koichi Sasada
e$B%+%F%4%je(B: YARV
Target version:

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

Ruby1.9e$B$K$Fe(BRuby on
Railse$B$NCf$Ne(Bactionpacke$B$N%F%9%H$rAv$i$;$k$H!"=N;8e$Ke(Bcoree$B$rEG$-$J$,$i%"%!<%H$7$^$9!#e(B
Rubye$B$N%P!<%8%g%s$Oe(B1.9.0-3e$B$G!"e(BRailse$B$Oe(Bgite$B%j%]%8%H%j>e$NJs9p;~8=:_$Ne(Bedgee$B%P!<%8%g%s$K$F:F8=2DG=$G$9!#e(B
e$B$^$?!"e(BOSe$B$Oe(BOSX Leoparde$B$
$h$Se(BDebian
etche$B$K$F:F8=:Q$_$G$9!#e(B

e$B:F8=<j=g$*$h$S%(%i!<FbMF$K$D$$$F$O!"$3$A$i$N8eH>ItJ,$r$4;2>H$/$@$5$$!#e(B
((URL:http://qwik.jp/asakusarb/001_log.html))

e$B$b$&>/$7>:Y$J@Z$jJ,$1$r$7$?$$$H$3$m$J$N$G$9$,!“FCDj$N%F%9%H%1!<%9Fb$G$O$J$/$F%F%9%H$,A4$F@5>o=*N;$7$?8e$N=*N;=hM}$GMn$A$F$$$k$h$&$G!“AG?M$K$O$3$l0J>e$N@Z$jJ,$1$OFq$7$/!”$5$5$@$5$s$HCfED$5$s$K8+$F$$$?$@$$$?$H$3$m!”$3$N$^$^$G>e$2$F$7$^$C$FNI$$$H$N$3$H$@$C$?$N$G!"$R$H$^$:$3$N$h$&$J7A$GJs9p$5$;$FD:$-$^$9!#e(B

e$B%o%J%Y$H?=$7$^$9!#e(B

2008/07/29 18:28 Akira M. [email protected]:

Ruby1.9e$B$K$Fe(BRuby on Railse$B$NCf$Ne(Bactionpacke$B$N%F%9%H$rAv$i$;$k$H!"=N;8e$Ke(Bcoree$B$rEG$-$J$,$i%"%!<%H$7$^$9!#e(B
Rubye$B$N%P!<%8%g%s$Oe(B1.9.0-3e$B$G!"e(BRailse$B$Oe(Bgite$B%j%]%8%H%j>e$NJs9p;~8=:_$Ne(Bedgee$B%P!<%8%g%s$K$F:F8=2DG=$G$9!#e(B
e$B$^$?!"e(BOSe$B$Oe(BOSX Leoparde$B$
$h$Se(BDebian etche$B$K$F:F8=:Q$_$G$9!#e(B

e$B0J2<$GH/@8$9$ke(BSEGVe$B$HF1MM$J$N$G$O$J$$$+$H;W$$$^$9!#e(B
e$B%U%!%$%J%i%$%6$,J#?tDj5A$5$l$F$$$k$H$-!"$9$G$Ke(Bdfreee$B$,8F$P$l$?e(B
e$B%*%V%8%'%/%H$r;2>H$9$k$H5/$-$kLdBj$N$h$&$G$9!#e(B

$ ./ruby -ve ’
a1,a2,b1,b2=Array.new(4){“”}
ObjectSpace.define_finalizer(b2,proc{p :b2})
ObjectSpace.define_finalizer(b1,proc{p :b1, b1})

ObjectSpace.define_finalizer(a2,proc{p :a2, a1})
ObjectSpace.define_finalizer(a1,proc{p :a1})

ruby 1.9.0 (2008-08-06 revision 18383) [i386-mingw32]
:a1
:a2
[2014068]
:b1
-e:4: [BUG] Segmentation fault
ruby 1.9.0 (2008-08-06 revision 18383) [i386-mingw32]

– control frame ----------
c:0005 p:---- s:0011 b:0011 l:000010 d:000010 CFUNC :stuck_out_tongue:
c:0004 p:0012 s:0006 b:0006 l:000e5c d:000005 BLOCK -e:4
c:0003 p:---- s:0006 b:0006 l:000005 d:000005 FINISH :set_backtrace
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 CFUNC :call
c:0001 p:0000 s:0002 b:0002 l:000001 d:000001 TOP :483

DBG> : “-e:4:in p'" DBG> : "-e:4:in block in '”
DBG> : “:0:in `call’”

This application has requested the Runtime to terminate it in an unusual
way.
Please contact the application’s support team for more information.

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

At Wed, 6 Aug 2008 16:06:04 +0900,
wanabe wrote in [ruby-dev:35778]:

a1,a2,b1,b2=Array.new(4){""}
:b1
-e:4: [BUG] Segmentation fault

e$BK\Ev$Ke(BRailse$B$K$=$&$$$C$?%3!<%I$,$"$k$H$9$k$H!"$$$C$?$$2?$r$7$?$$e(B
e$B$s$G$7$g$&$+!#$3$l$i$N%U%!%$%J%i%$%6$O!“BP>]%*%V%8%’%/%H<+?H$r;2e(B
e$B>H$7$F$$$k$N$G!”$I$l$b8F$P$l$J$$$H$$$&$N$,@5$7$$F0:n$@$H;W$$$^$9!#e(B

Index: gc.c

— gc.c (revision 18386)
+++ gc.c (working copy)
@@ -2092,5 +2092,5 @@ chain_finalized_object(st_data_t key, st
{
RVALUE *p = (RVALUE *)key, **final_list = (RVALUE **)arg;

  • if (p->as.basic.flags & FL_FINALIZE) {
  • if ((p->as.basic.flags & (FL_FINALIZE|FL_MARK)) == FL_FINALIZE) {
    if (BUILTIN_TYPE§ != T_DEFERRED) {
    p->as.free.flags = FL_MARK | T_DEFERRED; /* remain marked */
    @@ -2116,4 +2116,5 @@ rb_gc_call_finalizer_at_exit(void)
    deferred_final_list = 0;
    finalize_list(objspace, p);
  •  mark_tbl(objspace, finalizer_table, 0);
     st_foreach(finalizer_table, chain_finalized_object,
          (st_data_t)&deferred_final_list);

e$BJs9p<T$N>>ED$G$9!#e(B

e$B$4BP1~$"$j$,$H$&$4$6$$$^$9!#e(B
e$B$J$+$@$5$s$Ne(BRuby 1.9e$B$N$[$&$N%Q%C%A$rEv$F$F;n$7$F$_$?$H$3$m!"e(B
e$B3N$+$KMn$A$J$$$h$&$K$J$j$^$7$?!#e(B

1.8e$B$N$[$&$K4X$7$F$O!"$b$H$b$HF1MM$N8=>]$,=P$F$$$J$+$C$?$N$Ge(B

e$B$3$A$i$G$OFC$K8!>Z$O$G$-$F$$$^$;$s!#e(B

e$BK\Ev$Ke(BRailse$B$K$=$&$$$C$?%3!<%I$,$"$k$H$9$k$H!"$$$C$?e(B
e$B$$2?$r$7$?$$$s$G$7$g$&$+!#e(B

Railse$B$NB&$K$bLdBj$,$"$j$=$&!"$H!"$J$+$@$5$s$K8@$o$l$?$N$G!"e(B
e$B$b$&>/$7DI$C$F$_$^$7$?!#e(B

e$B$3$N7o!":G>.%1!<%9$H$7$F$O!“e(BRailse$B$N%=!<%9%G%#%l%/%H%j$Ge(B
$ cd actionpack
$ ruby19 -Ilib:test “test/controller/session/cookie_store_test.rb”
e$B$K$F:F8=2DG=$G!”$3$NCf$N!"e(Btest_restores_double_encoded_cookies
e$B$H$$$&%F%9%H%1!<%9$GMn$A$F$$$k$3$H$,$o$+$j$^$7$?!#e(B

e$B$^$?!“e(Bactionpack/lib/action_controller/session/cookie_store.rb
e$B$Ne(B159e$B9TL$”$?$j$N!“e(B
@session.cgi.send :instance_variable_set, ‘@output_cookies’, [cookie]
e$B$H$$$&%3!<%I$r%3%a%s%H%”%&%H$9$l$P$I$&$d$iMn$A$J$/$J$k!"e(B
e$B$H$$$&$3$H$^$G$O$o$+$j$^$7$?!#e(B

e$B$;$C$+$/$J$N$G!"$I$J$?$+0J>e$N>pJs$G2?$+$*5$$E$-$NE@$,$"$l$Pe(B
e$B%U%#!<%I%P%C%/$r$$$?$@$1$l$P9,$$$G$9!#e(B

e$B$?$@$7!"$3$N>l$O$"$/$^$Ge(Bruby-deve$B$G$"$C$F!"e(B
e$B$3$Ne(BRedminee$B$Oe(BRailse$B$N%P%0$rD>$9$?$a$Ne(BITSe$B$G$Oe(B
e$B$J$$$N$G!"e(B
Rubye$BE*$K$O$3$N%A%1%C%H$O$3$l$K$F2r7h!“e(B
e$B$H$$$&$3$H$K$7$F$$$?$@$$$F!”$b$A$m$s9=$$$^$;$s!#e(B

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

At Wed, 6 Aug 2008 17:17:30 +0900,
Nobuyoshi N. wrote in [ruby-dev:35780]:

e$BK\Ev$Ke(BRailse$B$K$=$&$$$C$?%3!<%I$,$"$k$H$9$k$H!"$$$C$?$$2?$r$7$?$$e(B
e$B$s$G$7$g$&$+!#$3$l$i$N%U%!%$%J%i%$%6$O!“BP>]%*%V%8%’%/%H<+?H$r;2e(B
e$B>H$7$F$$$k$N$G!”$I$l$b8F$P$l$J$$$H$$$&$N$,@5$7$$F0:n$@$H;W$$$^$9!#e(B

1.8e$BMQ$N%Q%C%A$G$9!#e(B

Index: common.mk

— common.mk (revision 18383)
+++ common.mk (working copy)
@@ -391,5 +391,5 @@ file.$(OBJEXT): {$(VPATH)}file.c $(RUBY_
{$(VPATH)}rubyio.h {$(VPATH)}rubysig.h {$(VPATH)}util.h
{$(VPATH)}dln.h
-gc.$(OBJEXT): {$(VPATH)}gc.c $(RUBY_H_INCLUDES)
+gc.$(OBJEXT): {$(VPATH)}gc.c $(RUBY_H_INCLUDES) {$(VPATH)}rubyio.h
{$(VPATH)}rubysig.h {$(VPATH)}st.h {$(VPATH)}node.h
{$(VPATH)}env.h {$(VPATH)}re.h {$(VPATH)}regex.h
Index: gc.c

— gc.c (revision 18383)
+++ gc.c (working copy)
@@ -14,4 +14,5 @@

#include “ruby.h”
+#include “rubyio.h”
#include “rubysig.h”
#include “st.h”
@@ -1063,5 +1064,14 @@ gc_mark_children(ptr, lev)
}

-static void obj_free _((VALUE));
+static int obj_free _((VALUE));
+
+static inline void
+add_freelist§

  • RVALUE *p;
    +{
  • p->as.free.flags = 0;
  • p->as.free.next = freelist;
  • freelist = p;
    +}

static void
@@ -1073,7 +1083,5 @@ finalize_list§
run_final((VALUE)p);
if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */

  •  p->as.free.flags = 0;
    
  •  p->as.free.next = freelist;
    
  •  freelist = p;
    
  •  add_freelist(p);
    
    }
    p = tmp;
    @@ -1100,4 +1108,6 @@ free_unused_heaps()
    }

+#define T_DEFERRED 0x3a
+
void rb_gc_abort_threads(void);

@@ -1143,24 +1153,26 @@ gc_sweep()
RVALUE *free = freelist;
RVALUE *final = final_list;

  • int deferred;

    p = heaps[i].slot; pend = p + heaps[i].limit;
    while (p < pend) {
    if (!(p->as.basic.flags & FL_MARK)) {

  • if (p->as.basic.flags) {
  •    obj_free((VALUE)p);
    
  • }
  • if (need_call_final && FL_TEST(p, FL_FINALIZE)) {
  •    p->as.free.flags = FL_MARK; /* remain marked */
    
  • if (p->as.basic.flags &&
  •    ((deferred = obj_free((VALUE)p)) ||
    
  •     ((FL_TEST(p, FL_FINALIZE)) && need_call_final))) {
    
  •    if (!deferred) {
    
  •  p->as.free.flags = T_DEFERRED;
    
  •  RDATA(p)->dfree = 0;
    
  •    }
    
  •    p->as.free.flags |= FL_MARK;
       p->as.free.next = final_list;
       final_list = p;
    
    }
    else {
  •    p->as.free.flags = 0;
    
  •    p->as.free.next = freelist;
    
  •    freelist = p;
    
  •    add_freelist(p);
    
    }
    n++;
    }
  •  else if (RBASIC(p)->flags == FL_MARK) {
    
  •  else if (BUILTIN_TYPE(p) == T_DEFERRED) {
    
    /* objects to be finalized /
    /
    do nothing remain marked */
    @@ -1208,14 +1220,19 @@ rb_gc_force_recycle§
    VALUE p;
    {
  • RANY§->as.free.flags = 0;
  • RANY§->as.free.next = freelist;
  • freelist = RANY§;
  • add_freelist§;
    }

-static void
+static inline void
+make_deferred§

  • RVALUE *p;
    +{
  • p->as.basic.flags = (p->as.basic.flags & ~T_MASK) | T_DEFERRED;
    +}

+static int
obj_free(obj)
VALUE obj;
{

  • switch (RANY(obj)->as.basic.flags & T_MASK) {
  • switch (BUILTIN_TYPE(obj)) {
    case T_NIL:
    case T_FIXNUM:
    @@ -1230,5 +1247,5 @@ obj_free(obj)
    }
  • switch (RANY(obj)->as.basic.flags & T_MASK) {
  • switch (BUILTIN_TYPE(obj)) {
    case T_OBJECT:
    if (RANY(obj)->as.object.iv_tbl) {
    @@ -1273,5 +1290,6 @@ obj_free(obj)
    }
    else if (RANY(obj)->as.data.dfree) {
  • (*RANY(obj)->as.data.dfree)(DATA_PTR(obj));
  • make_deferred(RANY(obj));
  • return 1;
    }
    }
    @@ -1285,6 +1303,9 @@ obj_free(obj)
    case T_FILE:
    if (RANY(obj)->as.file.fptr) {
  •  rb_io_fptr_finalize(RANY(obj)->as.file.fptr);
    
  •  RUBY_CRITICAL(free(RANY(obj)->as.file.fptr));
    
  •  rb_io_t *fptr = RANY(obj)->as.file.fptr;
    
  •  make_deferred(RANY(obj));
    
  •  RDATA(obj)->dfree = (void (*)(void*))rb_io_fptr_finalize;
    
  •  RDATA(obj)->data = fptr;
    
  •  return 1;
    
    }
    break;
    @@ -1314,5 +1335,5 @@ obj_free(obj)
    break;
    }
  • return; /* no need to free iv_tbl */
  • break; /* no need to free iv_tbl */

    case T_SCOPE:
    

@@ -1337,4 +1358,6 @@ obj_free(obj)
RANY(obj)->as.basic.flags & T_MASK, obj);
}
+

  • return 0;
    }

@@ -1682,4 +1705,5 @@ os_obj_of(of)
case T_SCOPE:
case T_NODE:

  •  case T_DEFERRED:
       continue;
     case T_CLASS:
    

@@ -1929,4 +1953,19 @@ rb_gc_finalize_deferred()
}

+static int
+chain_finalized_object(st_data_t key, st_data_t val, st_data_t arg)
+{

  • RVALUE *p = (RVALUE *)key, **final_list = (RVALUE **)arg;
  • if ((p->as.basic.flags & (FL_FINALIZE|FL_MARK)) == FL_FINALIZE) {
  • if (BUILTIN_TYPE§ != T_DEFERRED) {
  •  p->as.free.flags = FL_MARK | T_DEFERRED; /* remain marked */
    
  •  RDATA(p)->dfree = 0;
    
  • }
  • p->as.free.next = *final_list;
  • *final_list = p;
  • }
  • return ST_CONTINUE;
    +}

void
rb_gc_call_finalizer_at_exit()
@@ -1937,18 +1976,12 @@ rb_gc_call_finalizer_at_exit()
/* run finalizers */
if (need_call_final) {

  • p = deferred_final_list;
  • deferred_final_list = 0;
  • finalize_list§;
  • for (i = 0; i < heaps_used; i++) {
  •  p = heaps[i].slot; pend = p + heaps[i].limit;
    
  •  while (p < pend) {
    
  • if (FL_TEST(p, FL_FINALIZE)) {
  •    FL_UNSET(p, FL_FINALIZE);
    
  •    p->as.basic.klass = 0;
    
  •    run_final((VALUE)p);
    
  • }
  • p++;
  •  }
    
  • }
  • do {
  •  p = deferred_final_list;
    
  •  deferred_final_list = 0;
    
  •  finalize_list(p);
    
  •  mark_tbl(finalizer_table, 0);
    
  •  st_foreach(finalizer_table, chain_finalized_object,
    
  •       (st_data_t)&deferred_final_list);
    
  • } while (deferred_final_list);
    }
    /* run data object’s finalizers */