]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Attempting to resurrect a dying instance of a new-style class in a
authorTim Peters <tim.peters@gmail.com>
Thu, 11 Jul 2002 07:06:44 +0000 (07:06 +0000)
committerTim Peters <tim.peters@gmail.com>
Thu, 11 Jul 2002 07:06:44 +0000 (07:06 +0000)
__del__ method died with

    Fatal Python error: GC object already in linked list

in both release and debug builds.  Fixed that.  Added a new test that
dies without the fix.

Lib/test/test_descr.py
Misc/NEWS
Objects/typeobject.c

index 2b38ecc4fa8b5f5193ff8745e1333269bb4c4a93..cd8911df6ce34fd0fc5f65a526257cfc8f74a15c 100644 (file)
@@ -2981,6 +2981,26 @@ def copy_setstate():
     vereq(b.foo, 24)
     vereq(b.getfoo(), 24)
 
+def subtype_resurrection():
+    if verbose:
+        print "Testing resurrection of new-style instance..."
+
+    class C(object):
+        container = []
+
+        def __del__(self):
+            # resurrect the instance
+            C.container.append(self)
+
+    c = C()
+    c.attr = 42
+    # The only interesting thing here is whether this blows up in a
+    # debug build, due to flawed GC tracking logic in typeobject.c's
+    # call_finalizer() (a 2.2.1 bug).
+    del c
+    del C.container[-1]  # resurrect it again for the heck of it
+    vereq(C.container[-1].attr, 42)
+
 def test_main():
     class_docstrings()
     lists()
@@ -3041,6 +3061,7 @@ def test_main():
     docdescriptor()
     imulbug()
     copy_setstate()
+    subtype_resurrection()
     if verbose: print "All OK"
 
 if __name__ == "__main__":
index 1e256cbd3d185ec6ea30af6ebd909fcaeb55b88a..9852beb9eadefa7352ce71ae4702045e98df5ab5 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -4,6 +4,9 @@ Release date: dd-mmm-2002
 
 Core and builtins
 
+- If a dying instance of a new-style class got resurrected by its class's
+  __del__ method, Python aborted with a fatal error.
+
 - Source that creates parse nodes with an extremely large number of
   children (e.g.,  test_longexp.py) triggers problems with the
   platform realloc() under several platforms (e.g., MacPython, and
index 1a99a1eb825d755ae33915b06037d3e0fd53d44f..e8c7ea7aef512ba875abc2046bf760475b77e970 100644 (file)
@@ -403,7 +403,8 @@ call_finalizer(PyObject *self)
 #ifdef COUNT_ALLOCS
                self->ob_type->tp_frees--;
 #endif
-               _PyObject_GC_TRACK(self);
+               /* This should still be a tracked gc'ed object. */
+               assert(((PyGC_Head *)(self)-1)->gc.gc_next != NULL);
                return -1; /* __del__ added a reference; don't delete now */
        }
 #ifdef Py_TRACE_REFS