From 8156b9019c051c3772947a94932e035d88b4098f Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Thu, 11 Jul 2002 07:06:44 +0000 Subject: [PATCH] Attempting to resurrect a dying instance of a new-style class in a __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 | 21 +++++++++++++++++++++ Misc/NEWS | 3 +++ Objects/typeobject.c | 3 ++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 2b38ecc4fa8b..cd8911df6ce3 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -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__": diff --git a/Misc/NEWS b/Misc/NEWS index 1e256cbd3d18..9852beb9eade 100644 --- 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 diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 1a99a1eb825d..e8c7ea7aef51 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -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 -- 2.47.3