[Bug:trunk] rubyspec: ObjectSpace.define_finalizer doesn't call self-referencing finalizers FAILED

e$B$J$+$@$5$s$+$^$D$b$H$5$se(B
e$B1sF#$G$9!#e(B

e$B0J2<$N$h$&$K$9$k$He(B T_ZOMBIE
e$B$,8+$($F$7$^$&$N$O%P%0$G$7$g$&$+!#e(B

$ ./ruby -ve ’
obj = “test”
ObjectSpace.define_finalizer(obj, proc { begin; p obj; ensure; p $!;
end })

ruby 1.9.2dev (2010-02-10 trunk 26632) [i686-linux]
#<NotImplementedError: method `inspect’ called on unexpected
T_ZOMBIE object (0x8248df0 flags=0x3e klass=0x0)>

[ruby-core:23918] e$B$G!“e(Bobj e$B$X$Ne(B reference
e$B$,$”$k$+$i$3$l$O2s<}e(B
e$B$5$l$J$$$h$&$J$3$H$,=q$+$l$F$$$^$9$,!"7k6I2s<}$5$l$k$h$&$Ke(B
e$B$J$C$F$$$k$h$&$G$9!#e(B

[ruby-core:24095] e$B$G%P%0$H$7$FEPO?$5$l$F$$$^$9$,!"$I$C$A$,e(B
e$B@5$7$$$N$+$h$/$o$+$j$^$;$s!#e(B
rubyspec e$B$K2s<}$5$l$J$$$3$H$r3NG’$9$ke(B spec
e$B$,F~$C$F$$$F!"<:GTe(B
e$B$7$F$$$^$9!#e(B

e$B2s<}$5$l$k$N$,@52r$@$H$7$?$i!“Nc30%a%C%;!<%8$+$ie(B unexpected
e$B$Oe(B
e$B>C$9$Y$-$@$H;W$$$^$9!#e(B
e$B8+$($J$$$N$,@52r$@$H$7$?$i!”%P%0$J$s$G$7$g$&!#e(B

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

2010e$BG/e(B2e$B7ne(B11e$BF|e(B0:29 Yusuke ENDOH [email protected]:

e$B0J2<$N$h$&$K$9$k$He(B T_ZOMBIE e$B$,8+$($F$7$^$&$N$O%P%0$G$7$g$&$+!#e(B

$ ./ruby -ve ’
obj = “test”
ObjectSpace.define_finalizer(obj, proc { begin; p obj; ensure; p $!; end })

ruby 1.9.2dev (2010-02-10 trunk 26632) [i686-linux]
#<NotImplementedError: method `inspect’ called on unexpected
T_ZOMBIE object (0x8248df0 flags=0x3e klass=0x0)>

e$B!Ve(BT_ZOMBIE
e$B$,8+$($?$i%P%0!W$H$$$&$J$+$@$5$s$H$5$5$@$5$s$NG’Dj$re(B
e$BD:$-$^$7$?!#e(BGC
e$B$K6=L#$J$$$N$G<+?.$O$J$$$G$9$,!"0l1~D4$Y$^$7$?!#e(B

ruby e$B=N;;~$K<B9T$5$l$=$&$Je(B rb_objspace_call_finalizer
e$B$NCf$G!"e(B
/
run finalizers */ e$B$H$$$&2U=j$,$“$j!“e(Bchain_finalized_object
e$B$7$F$+$ie(B run_final e$B$r$9$k!”$H$$$&$h$&$J%3!<%I$,$”$j$^$9!#e(B

chain_finalized_object e$B$NCf$G$Oe(B FL_FINALIZE
e$B$J%%V%8%'%/%H$OL5e(B
e$B>r7o$Ke(B T_ZOMBIE e$B$K$5$l!"e(Bdfree e$B$,e(B 0
e$B$K$5$l$^$9!#$=$7$Fe(B run_final
e$B$NCf$G$Oe(B T_ZOMBIE e$B$K$J$C$?%
%V%8%'%/%H$Ne(B finalizer
e$B$r8F$s$G$7$^e(B
e$B$&$h$&$G$9!#e(B(e$B4V0c$C$F$?$i$9$_$^$;$se(B)

e$BLdBjE@e(B (e$B5?LdE@e(B) e$B$Oe(B 2 e$B$D$"$j$^$9!#e(B

  1. dfree e$B$,e(B 0 e$B$K$5$l$F$7$^$C$?$i!"e(Bfree
    e$B$,8F$Y$J$/$J$k5$$,$9$ke(B
    e$B$1$l$I$$$$$N$+!)e(B (e$B$I$&$;=*N;D>A0$@$+$i$$$$!)e(B MVM
    e$B$K$J$C$?$ie(B
    e$B:$$k$+$be(B)

  2. e$BBP>]%%V%8%'%/%H$,6/@)E$Ke(B T_ZOMBIE e$B$K$J$C$F$+$ie(B
    finalizer
    e$B$,8F$P$l$k$N$GEvA3e(B T_ZOMBIE e$B$J%*%V%8%'%/%H$,e(B finalizer
    e$B$+$ie(B
    e$B8+$($k$1$l$I!"$I$&$9$k$N$,@5$7$$!)e(B

GC e$B$K6=L#$N$"$k?M$K9M$($F$[$7$$$G$9!#e(B

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

2010e$BG/e(B2e$B7ne(B11e$BF|e(B19:08 Yusuke ENDOH [email protected]:

e$B0J2<$N$h$&$K$9$k$He(B T_ZOMBIE e$B$,8+$($F$7$^$&$N$O%P%0$G$7$g$&$+!#e(B
snip
GC e$B$K6=L#$N$"$k?M$K9M$($F$[$7$$$G$9!#e(B

e$B4|BT$7$F$$$?e(B wanabe
e$B$5$s$K!V8+$J$$@k8@!W$r$5$l$F$7$^$C$?$N$G!"e(B
e$B<+J,$G$$$$2C8:$K9M$($F$_$^$7$?!#e(B

r18398 e$B$Ge(B runs finalizers with the object terminated. e$B$H$$$&e(B
e$BJQ99$,F~$C$F$$$?$N$G!"$3$l$re(B revert e$B$9$k$h$&$J46$8$G%Q%C%A$re(B
e$B=q$$$F$_$^$7$?!#e(BT_ZOMBIE e$B$O8+$($J$/$J$C$?$h$&$G$9!#e(B

$ ./ruby -e ’
obj = “test”
ObjectSpace.define_finalizer(obj, proc { begin; p obj; ensure; p $!;
end })

e$B$^$?!"e(Bmake check e$B$G$be(B objectspace e$B$N%(%i!<$,e(B 1
e$B$DA}$($k$@$1$Ne(B
e$B$h$&$G$9!#e(B

e$B$1$l$I!"0J2<$Ne(B 2 e$B$D$N$h$/$o$+$i$J$$5sF0$KG:$^$5$l$F$$$^$9!#e(B

  1. e$BBP>]%*%V%8%'%/%H$r%H%C%W%l%Y%k$N%m!<%+%kJQ?t$KBeF~$9$k$He(B
    e$B%U%!%$%J%i%$%6$,<B9T$5$l$J$$e(B

e$B2s<}$5$l$J$$e(B

$ ./ruby -e ’
def foo; proc { p :foo }; end
s = “foo”
ObjectSpace.define_finalizer(s, foo)

e$B%m!<%+%kJQ?t$KF~$l$J$1$l$P2s<}$5$l$ke(B

$ ./ruby -e ’
def foo; proc { p :foo }; end
ObjectSpace.define_finalizer(“foo”, foo)

:foo

e$B%H%C%W%l%Y%k$G$J$1$l$P2s<}$5$l$ke(B

$ ./ruby -e ’
class C
def self.foo; proc { p :foo }; end
s = “foo”
ObjectSpace.define_finalizer(“foo”, foo)
end

e$B%U%!%$%J%i%$%6$Ne(B proc e$B$+$i%H%C%W%l%Y%k$N%m!<%+%kJQ?t$,$J$<$+e(B
e$B%^!<%/$5$l$k$s$G$7$g$&$+!#e(B
test/ruby/test_objectspace.rb e$B$,$3$N5sF0$K0MB8$7$F<:GT$9$ke(B
e$B$h$&$G$9!#e(B

  1. Enumerator#next e$B$r;H$&$H2s<}$5$l$J$$e(B

e$B2s<}$5$l$J$$e(B

$ ./ruby -e ’
module M
def self.callback
proc { p “finalized” }
end
def self.run
@enum = 1.enum_for(:upto, 3)
@enum.next
ObjectSpace.define_finalizer(“foo”, callback)
end
end
M.run

next e$B$r;H$o$J$1$l$P2s<}$5$l$ke(B

$ ./ruby -e ’
module M
def self.callback
proc { p “finalized” }
end
def self.run
@enum = 1.enum_for(:upto, 3)
#@enum.next
ObjectSpace.define_finalizer(“foo”, callback)
end
end
M.run

“finalized”

Enumerator e$B$r%$%s%9%?%s%9JQ?t$KF~$l$J$1$l$P2s<}$5$l$ke(B

$ ./ruby -e ’
module M
def self.callback
proc { p “finalized” }
end
def self.run
enum = 1.enum_for(:upto, 3)
enum.next
ObjectSpace.define_finalizer(“foo”, callback)
end
end
M.run

“finalized”

e$B$*$=$i$/e(B Fiber
e$B$N%^%7%s%9%?%C%/$NCf$K;2>H$,$“$k$N$G$O$J$$$+$He(B
e$B;W$$$^$9$,!”$I$&BP=h$7$?$b$N$+$o$+$j$^$;$s!#e(B
rubyspec e$B$,$3$N5sF0$K0MB8$7$F<:GT$7$^$9e(B (Enumerator e$B$Ne(B spec
e$B$He(B
e$B$"$o$;$F<B9T$7$?$H$-$@$1<:GT$9$ke(B) e$B!#e(B

e$B$b$&>/$79M$($F$$^$9$,!"$=$l$G$be(B T_ZOMBIE
e$B$,8+$($k$h$j$O$$$$$He(B
e$B;W$&$N$G!“H?BP$,$J$1$l$P$H$j$”$($:%3%
%C%H$7$h$&$H;W$$$^$9!#e(B

diff --git a/gc.c b/gc.c
index 4cfc23c…32b7436 100644
— a/gc.c
+++ b/gc.c
@@ -2652,7 +2652,7 @@ 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) {
  • if ((p->as.basic.flags & (FL_FINALIZE|FL_MARK)) == FL_FINALIZE) {
    if (BUILTIN_TYPE(p) != T_ZOMBIE) {
    p->as.free.flags = FL_MARK | T_ZOMBIE; /* remain marked */
    RDATA(p)->dfree = 0;
    @@ -2661,9 +2661,7 @@ chain_finalized_object(st_data_t key, st_data_t
    val, st_data_t arg)
    *final_list = p;
    return ST_CONTINUE;
    }
  • else {
  • return ST_DELETE;
  • }
  • return ST_DELETE;
    }

void
@@ -2681,15 +2679,16 @@ rb_objspace_call_finalizer(rb_objspace_t
*objspace)

 /* run finalizers */
 if (finalizer_table) {
  • finalize_deferred(objspace);
  • while (finalizer_table->num_entries > 0) {
  • do {
  •  finalize_deferred(objspace);
    
  •  mark_tbl(objspace, finalizer_table, 0);
     st_foreach(finalizer_table, chain_finalized_object,
    
  •       (st_data_t)&final_list);
    
  •  if (!(p = final_list)) break;
    
  •  do {
    
  • final_list = p->as.free.next;
  • run_final(objspace, (VALUE)p);
  •  } while ((p = final_list) != 0);
    
  •       (st_data_t)&deferred_final_list);
    
  • } while (deferred_final_list);
  • if (finalizer_table->num_entries) {
  •  rb_warning("%d finalizer%s left not-invoked due to 
    

self-reference",

  •       finalizer_table->num_entries,
    
  •       finalizer_table->num_entries > 1 ? "s" : "");
    
    }
    st_free_table(finalizer_table);
    finalizer_table = 0;

2010e$BG/e(B2e$B7ne(B13e$BF|e(B10:31 Yusuke ENDOH [email protected]:

e$B$3$l<+BN$O$R$g$C$H$7$?$i%P%0$J$N$+$b$7$l$^$;$s$,!"0lHLE*$K8@$C$F!“e(B
conservative GC e$B$@$H%U%!%$%J%i%$%6$,M=4|$;$:%*%V%8%'%/%H<+BN$K;2>H$re(B
e$B;}$C$F$7$^$&2DG=@-$,$”$k$N$G!“e(Bself-referencial e$B$J%U%!%$%J%i%$%6$re(B
e$B<B9T$7$J$$$H$$$&J}?K$@$H!”%U%!%$%J%i%$%6$,IT2D2r$K<B9T$5$l$J$$;vBV$Ne(B
e$BH/@8$rHr$1$i$l$J$$$H$$$&7kO@$K;j$j$^$7$?!#e(B

e$B$=$&$$$($P!“e(B1.8 e$B$Ne(B tempfile.rb
e$B$O!”%U%!%$%J%i%$%6$H$7$Fe(B
Proc e$B$8$c$J$/$FIaDL$N%*%V%8%'%/%H$r;H$&$h$&$K$7$F!“e(B
e$BJQ$J;2>H$r;}$?$J$$$h$&$K$7$F$”$k$s$G$9$,!“e(B
e$B$=$&$9$k$N$O4X78$”$j$^$9$+$M!#e(B

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

2010e$BG/e(B2e$B7ne(B12e$BF|e(B22:32 Yusuke ENDOH [email protected]:

2010e$BG/e(B2e$B7ne(B11e$BF|e(B19:08 Yusuke ENDOH [email protected]:

e$B0J2<$N$h$&$K$9$k$He(B T_ZOMBIE e$B$,8+$($F$7$^$&$N$O%P%0$G$7$g$&$+!#e(B
snip
e$B$b$&>/$79M$($F$$^$9$,!"$=$l$G$be(B T_ZOMBIE e$B$,8+$($k$h$j$O$$$$$He(B
e$B;W$&$N$G!“H?BP$,$J$1$l$P$H$j$”$($:%3%
%C%H$7$h$&$H;W$$$^$9!#e(B

e$BC/$K$bAj<j$K$5$l$:<d$7$$8B$j$G$9$,!"B3Js$G$9!#e(B

e$B$3$N%Q%C%A$r$"$F$k$H!“e(BEnumerator#next e$B$He(B Tempfile
e$B$rAH$_9g$o$;$?;~$Ke(B
Tempfile e$B$,>C$5$l$J$/$J$j$^$7$?!#$3$l$OeJ@32$,$”$j$=$&$G$9!#e(B

require “tempfile”
e = 1.enum_for(:upto, 3)
e.next
t = Tempfile.new(“foo”)
p t.path

e$B$3$l<+BN$O$R$g$C$H$7$?$i%P%0$J$N$+$b$7$l$^$;$s$,!"0lHLE*$K8@$C$F!“e(B
conservative GC
e$B$@$H%U%!%$%J%i%$%6$,M=4|$;$:%*%V%8%'%/%H<+BN$K;2>H$re(B
e$B;}$C$F$7$^$&2DG=@-$,$”$k$N$G!“e(Bself-referencial
e$B$J%U%!%$%J%i%$%6$re(B
e$B<B9T$7$J$$$H$$$&J}?K$@$H!”%U%!%$%J%i%$%6$,IT2D2r$K<B9T$5$l$J$$;vBV$Ne(B
e$BH/@8$rHr$1$i$l$J$$$H$$$&7kO@$K;j$j$^$7$?!#e(B

e$B=N;;~$K$O!"BP>]%%V%8%'%/%H$r2s<}$9$kA0$KI,$:%U%!%$%J%i%$%6$rAv$i$;$ke(B
e$B$H$$$&$N$O$I$&$G$7$g$&$+!#0l1~!"e(Bmake check e$B$He(B make
test-rubyspec e$B$,e(B
e$B40Av$9$k$3$H$O3N$+$a$F$$$^$9!#e(B

e$BH?BP$,$J$1$l$P%3%_%C%H$7$F!"e(Brubyspec e$BB&$b=$@5$7$^$9!#e(B

diff --git a/gc.c b/gc.c
index 4cfc23c…759b14e 100644
— a/gc.c
+++ b/gc.c
@@ -2588,11 +2588,29 @@ run_single_final(VALUE arg)
}

static void
-run_final(rb_objspace_t *objspace, VALUE obj)
+run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE objid, VALUE
table)
{
long i;
int status;

  • VALUE args[3], table, objid;
  • VALUE args[3];
  • args[1] = 0;
  • args[2] = (VALUE)rb_safe_level();
  • if (!args[1] && RARRAY_LEN(table) > 0) {
  •    args[1] = rb_obj_freeze(rb_ary_new3(1, objid));
    
  • }
  • for (i=0; i<RARRAY_LEN(table); i++) {
  •    VALUE final = RARRAY_PTR(table)[i];
    
  •    args[0] = RARRAY_PTR(final)[1];
    
  •    args[2] = FIX2INT(RARRAY_PTR(final)[0]);
    
  •    rb_protect(run_single_final, (VALUE)args, &status);
    
  • }
    +}

+static void
+run_final(rb_objspace_t *objspace, VALUE obj)
+{

  • VALUE table, objid;
    RUBY_DATA_FUNC free_func = 0;

    objid = rb_obj_id(obj); /* make obj into id */
    @@ -2610,17 +2628,7 @@ run_final(rb_objspace_t *objspace, VALUE obj)

    if (finalizer_table &&
    st_delete(finalizer_table, (st_data_t*)&obj, &table)) {

  • args[1] = 0;
  • args[2] = (VALUE)rb_safe_level();
  • if (!args[1] && RARRAY_LEN(table) > 0) {
  •  args[1] = rb_obj_freeze(rb_ary_new3(1, objid));
    
  • }
  • for (i=0; i<RARRAY_LEN(table); i++) {
  •  VALUE final = RARRAY_PTR(table)[i];
    
  •  args[0] = RARRAY_PTR(final)[1];
    
  •  args[2] = FIX2INT(RARRAY_PTR(final)[0]);
    
  •  rb_protect(run_single_final, (VALUE)args, &status);
    
  • }
  • run_finalizer(objspace, obj, objid, table);
    }
    }

@@ -2652,18 +2660,33 @@ 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) {
  • if ((p->as.basic.flags & (FL_FINALIZE|FL_MARK)) == FL_FINALIZE) {
    if (BUILTIN_TYPE(p) != T_ZOMBIE) {
    p->as.free.flags = FL_MARK | T_ZOMBIE; /* remain marked */
    RDATA(p)->dfree = 0;
    }
    p->as.free.next = *final_list;
    *final_list = p;
  • return ST_CONTINUE;
  • }
  • else {
  • return ST_DELETE;
    }
  • return ST_CONTINUE;
    +}

+struct force_finalize_list {

  • VALUE obj;
  • VALUE table;
  • struct force_finalize_list *next;
    +};

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

  • struct force_finalize_list **prev = (struct force_finalize_list
    **)arg;
  • struct force_finalize_list *curr = ALLOC(struct
    force_finalize_list);
  • curr->obj = key;
  • curr->table = val;
  • curr->next = *prev;
  • *prev = curr;
  • return ST_DELETE;
    }

void
@@ -2681,15 +2704,22 @@ rb_objspace_call_finalizer(rb_objspace_t
*objspace)

 /* run finalizers */
 if (finalizer_table) {
  • finalize_deferred(objspace);
  • while (finalizer_table->num_entries > 0) {
  • do {
  •  finalize_deferred(objspace);
    
  •  mark_tbl(objspace, finalizer_table, 0);
     st_foreach(finalizer_table, chain_finalized_object,
    
  •       (st_data_t)&final_list);
    
  •  if (!(p = final_list)) break;
    
  •  do {
    
  • final_list = p->as.free.next;
  • run_final(objspace, (VALUE)p);
  •  } while ((p = final_list) != 0);
    
  •       (st_data_t)&deferred_final_list);
    
  • } while (deferred_final_list);
  • /* force to run finalizer */
  • while (finalizer_table->num_entries) {
  •  struct force_finalize_list *list = 0;
    
  •  st_foreach(finalizer_table, force_chain_object, 
    

(st_data_t)&list);

  •  while (list) {
    
  • struct force_finalize_list *curr = list;
  • run_finalizer(objspace, curr->obj, rb_obj_id(curr->obj),
    curr->table);
  • list = curr->next;
  • xfree(curr);
  •  }
    
    }
    st_free_table(finalizer_table);
    finalizer_table = 0;

ruby 1.9.2dev (2010-02-10 trunk 26632) [i686-linux]
rubyspec e$B$K2s<}$5$l$J$$$3$H$r3NG’$9$ke(B spec e$B$,F~$C$F$$$F!"<:GTe(B
e$B$7$F$$$^$9!#e(B

e$B2s<}$5$l$k$N$,@52r$@$H$7$?$i!“Nc30%a%C%;!<%8$+$ie(B unexpected e$B$Oe(B
e$B>C$9$Y$-$@$H;W$$$^$9!#e(B
e$B8+$($J$$$N$,@52r$@$H$7$?$i!”%P%0$J$s$G$7$g$&!#e(B

e$BK:$l$=$&$K$J$k$N$G!"e(BIRCe$B$N5DO@$rE>5-e(B

  1. objecte$B$Oe(Breferencee$B$,$"$k8B$j2s<}$5$l$J$$e(B
  2. finalizere$B$Oe(Bobjecte$B$,2s<}$5$l$k;~$K8F$P$l$ke(B
  3. e$B%W%m%;%9=*N;;~$Oe(Bfinalizere$B$,@dBP8F$P$l$ke(B

e$B$Ne(B1,2e$B$He(B3e$B$,N>N)IT2DG=$H$$$&;EMM%P%0$NOC$@$H;W$C$F$$$^$9!#%W%m%;%9=N;;~$Ke(B
e$B$^$@;2>H$5$l$F$$$k%
%V%8%’%/%H$O2<5-e(BA)e$B!"e(BB)e$B$I$A$i$G$b%k!<%k0cH?e(B

A) e$B;2>H$5$l$F$$$F$b6/@)E*$K%U%!%$%J%i%$%6$r8F$Ve(B
e$B!J8=>u$3$A$i!#$+$D%U%!%$%J%i%$%68F$VD>A0$K!Ke(B
B)
e$B%W%m%;%9=N;;~$K$^$@;2>H$5$l$F$$$k%%V%8%’%/%H$O%U%!%$%J%i%$%68F$P$J$$e(B
e$B!Je(B[ruby-dev:40410]e$B$N$h$&$Ke(Btempfilee$B$,>C$($J$/$J$k!Ke(B

e$B$N$G!";EMML@3N2=$,I,MW$G$7$g$&!#e(B
e$B$b$7D6$+$7$3$$%W%m%;%9=*N;=hM}$r:n$l$P8=>u$N;EMM$GLdBj$J$$$N$G$"$l$P!"e(B
e$B%D%C%3%_$O4?7^$7$^$9!#e(B

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

2010e$BG/e(B2e$B7ne(B13e$BF|e(B10:40 Tanaka A. [email protected]:

e$B$=$&$9$k$N$O4X78$“$j$^$9$+$M!#e(B
[ruby-dev:40409] e$B$N%Q%C%Ae(B + e$BC1=c$Ke(B Tempfile::Remover
e$B$rI|3h$5$;$F$_$?e(B
e$B$@$1$G$O!”$d$C$Q$j>C$($J$$$h$&$G$7$?!#$I$3$+$GITMW$Je(B mark
e$B$r$7$F$k$Ne(B
e$B$+$J$"!#e(B

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

2010e$BG/e(B2e$B7ne(B16e$BF|e(B11:25 KOSAKI Motohiro
[email protected]:

e$BK:$l$=$&$K$J$k$N$G!"e(BIRCe$B$N5DO@$rE>5-e(B

  1. objecte$B$Oe(Breferencee$B$,$"$k8B$j2s<}$5$l$J$$e(B
  2. finalizere$B$Oe(Bobjecte$B$,2s<}$5$l$k;~$K8F$P$l$ke(B
  3. e$B%W%m%;%9=*N;;~$Oe(Bfinalizere$B$,@dBP8F$P$l$ke(B

e$B$Ne(B1,2e$B$He(B3e$B$,N>N)IT2DG=$H$$$&;EMM%P%0$NOC$@$H;W$C$F$$$^$9!#e(B

e$B$O$$!#e(B

e$B%W%m%;%9=N;;~$Ke(B
e$B$^$@;2>H$5$l$F$$$k%
%V%8%'%/%H$O2<5-e(BA)e$B!"e(BB)e$B$I$A$i$G$b%k!<%k0cH?e(B

A) e$B;2>H$5$l$F$$$F$b6/@)E*$K%U%!%$%J%i%$%6$r8F$Ve(B
e$B!J8=>u$3$A$i!#$+$D%U%!%$%J%i%$%68F$VD>A0$K!Ke(B
B) e$B%W%m%;%9=N;;~$K$^$@;2>H$5$l$F$$$k%%V%8%'%/%H$O%U%!%$%J%i%$%68F$P$J$$e(B
e$B!Je(B[ruby-dev:40410]e$B$N$h$&$Ke(Btempfilee$B$,>C$($J$/$J$k!Ke(B

e$B$N$G!";EMML@3N2=$,I,MW$G$7$g$&!#e(B

  1. object e$B$Oe(B reference e$B$,$"$k8B$j2s<}$5$l$J$$e(B
  2. finalizer e$B$Oe(B object e$B$,2s<}$5$l$k;~e(B
    *e$B$^$?$O%W%m%;%9=N;;~e(B e$B$K8F$P$l$ke(B

e$B$H$$$&;EMM$G$$$$$H;W$$$^$9!#Cj>]E*$K8@$&$J$i!"!V$=$l$h$j@h$Ke(B
object e$B$Ke(B
e$BBP$9$kA`:n$r9T$&5!2q$,$J$/$J$k;~E@!W$H$+$G$9$+$M!#!V$=$l$h$j@h!W$NDj5A$,e(B
e$BHyL/$G$9$,!#e(B

e$B$=$N$h$&$K$9$k%Q%C%A$,e(B [ruby-dev:40410]
e$B$G$9!#Bg$-$JH?BP$O$J$+$C$?$N$Ge(B
e$B0lC6%3%_%C%H$7$^$9!#LdBj$,5/$-$?$i8@$C$F$/$@$5$$!#e(B

e$B%A%1%C%He(B #2732 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 r26684.
Yusuke, 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/2732