[Zope-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 Zope-Checkins mailing list