From: Ryan Davis Date: 2004-04-16T13:09:08+09:00 Subject: Possible bug in init_copy or rb_gc_copy_finalizer? The following code: #!/usr/bin/ruby -w obj = Object.new ObjectSpace.define_finalizer(obj) { |an_id| puts "finalizing #{an_id}" } obj2 = obj.clone causes the following output: ./blah.rb:5: warning: copy_finalizer: descarding old finalizers finalizing 935212 finalizing 935242 Eric and I think this is the correct patch: <517> cvs diff -du object.c gc.c Index: object.c =================================================================== RCS file: /src/ruby/object.c,v retrieving revision 1.134.2.8 diff -d -u -r1.134.2.8 object.c --- object.c 14 Apr 2004 04:06:52 -0000 1.134.2.8 +++ object.c 16 Apr 2004 04:03:46 -0000 @@ -263,7 +263,7 @@ } clone = rb_obj_alloc(rb_obj_class(obj)); RBASIC(clone)->klass = rb_singleton_class_clone(obj); - RBASIC(clone)->flags = (RBASIC(obj)->flags | FL_TEST(clone, FL_TAINT)) & ~FL_FREEZE; + RBASIC(clone)->flags = (RBASIC(obj)->flags | FL_TEST(clone, FL_TAINT)) & ~(FL_FREEZE|FL_FINALIZE); init_copy(clone, obj); RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE; Index: gc.c =================================================================== RCS file: /src/ruby/gc.c,v retrieving revision 1.168.2.1 diff -d -u -r1.168.2.1 gc.c --- gc.c 12 Apr 2004 10:11:34 -0000 1.168.2.1 +++ gc.c 16 Apr 2004 04:03:47 -0000 @@ -1719,12 +1719,10 @@ if (!finalizer_table) return; if (!FL_TEST(obj, FL_FINALIZE)) return; - if (FL_TEST(dest, FL_FINALIZE)) { - rb_warn("copy_finalizer: discarding old finalizers"); - } if (st_lookup(finalizer_table, obj, &table)) { st_insert(finalizer_table, dest, table); } + RBASIC(dest)->flags |= FL_FINALIZE; } static VALUE ----- 1) We added FL_FINALIZE to the flags to strip from the cloned object, 2) We think that the removed FL_TEST isn't necessary because rb_gc_copy_finalizer is only called from init_copy so far and we have stripped FL_FINALIZE from the flags just before calling init_copy. 3) We set the finalize flag on the cloned object after we insert the cloned object into the finalizer_table. Please let us know if this is sufficient. Thank you