[Zodb-checkins] CVS: Cruft/ExtensionClass/src -
ExtensionClass.c:1.58.36.2
Tim Peters
tim.one at comcast.net
Wed Dec 1 12:55:32 EST 2004
Update of /cvs-repository/Cruft/ExtensionClass/src
In directory cvs.zope.org:/tmp/cvs-serv18420/lib/Components/ExtensionClass/src
Modified Files:
Tag: Zope-2_7-branch
ExtensionClass.c
Log Message:
subclass_dealloc(): Repair object resurrection.
A debug build of Python contains a doubly-linked list of all allocated
objects. In case an instance is resurrected by a __del__ method, the
instance needs to be added to that list again, else a segfault can occur
later when (if ever) the instance goes away normally (its __del__ method
stops resurrecting it). But ExtensionClass wasn't doing this, and a
repeatable segfault under a debug-build Python in test
checkMinimizeTerminates was the result.
Repaired by adding instance resurrection code from Python's classobject.c
instance_dealloc() to Zope's ExtensionClass.c subclass_dealloc().
=== Cruft/ExtensionClass/src/ExtensionClass.c 1.58.36.1 => 1.58.36.2 ===
--- Cruft/ExtensionClass/src/ExtensionClass.c:1.58.36.1 Mon Sep 15 14:14:55 2003
+++ Cruft/ExtensionClass/src/ExtensionClass.c Wed Dec 1 12:55:31 2004
@@ -3030,6 +3030,7 @@
#endif
PyErr_Fetch(&t,&v,&tb);
+ assert(self->ob_refcnt == 0);
Py_INCREF(self); /* Give us a new lease on life */
if (subclass_watcher &&
@@ -3048,8 +3049,31 @@
PyErr_Clear();
+ assert(self->ob_refcnt > 0);
if (--self->ob_refcnt > 0)
{
+ /* self has been resurrected. Make it look like the original
+ * Py_DECREF never happened. This code is copy/paste/modify from
+ * Python's instance_dealloc().
+ */
+ int refcnt = self->ob_refcnt;
+
+ _Py_NewReference((PyObject *)self);
+ self->ob_refcnt = refcnt;
+ /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
+ * we need to undo that.
+ */
+ _Py_DEC_REFTOTAL;
+ /* If Py_TRACE_REFS, _Py_NewReference re-added self to the
+ * object chain, so no more to do there.
+ * If COUNT_ALLOCS, the original decref bumped tp_frees, and
+ * _Py_NewReference bumped tp_allocs: both of those need to be
+ * undone.
+ */
+#ifdef COUNT_ALLOCS
+ --self->ob_type->tp_frees;
+ --self->ob_type->tp_allocs;
+#endif
PyErr_Restore(t,v,tb);
return; /* we added a reference; don't delete now */
}
More information about the Zodb-checkins
mailing list