[Python-checkins] python/dist/src/Objects typeobject.c,2.165,2.166
gvanrossum@users.sourceforge.net
gvanrossum@users.sourceforge.net
Tue, 06 Aug 2002 14:41:47 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv1803
Modified Files:
typeobject.c
Log Message:
Fix SF bug 574207 (chained __slots__ dealloc segfault).
This is inspired by SF patch 581742 (by Jonathan Hogg, who also
submitted the bug report, and two other suggested patches), but
separates the non-GC case from the GC case to avoid testing for GC
several times.
Had to fix an assert() from call_finalizer() that asserted that the
object wasn't untracked, because it's possible that the object isn't
GC'ed!
Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.165
retrieving revision 2.166
diff -C2 -d -r2.165 -r2.166
*** typeobject.c 1 Aug 2002 14:38:53 -0000 2.165
--- typeobject.c 6 Aug 2002 21:41:44 -0000 2.166
***************
*** 402,406 ****
self->ob_refcnt = refcnt;
}
! assert(_Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
/* If Py_REF_DEBUG, the original decref dropped _Py_RefTotal, but
* _Py_NewReference bumped it again, so that's a wash.
--- 402,407 ----
self->ob_refcnt = refcnt;
}
! assert(!PyType_IS_GC(self->ob_type) ||
! _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
/* If Py_REF_DEBUG, the original decref dropped _Py_RefTotal, but
* _Py_NewReference bumped it again, so that's a wash.
***************
*** 424,429 ****
destructor basedealloc;
! /* This exists so we can DECREF self->ob_type */
if (call_finalizer(self) < 0)
return;
--- 425,472 ----
destructor basedealloc;
! /* Extract the type; we expect it to be a heap type */
! type = self->ob_type;
! assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
!
! /* Test whether the type has GC exactly once */
!
! if (!PyType_IS_GC(type)) {
! /* It's really rare to find a dynamic type that doesn't have
! GC; it can only happen when deriving from 'object' and not
! adding any slots or instance variables. This allows
! certain simplifications: there's no need to call
! clear_slots(), or DECREF the dict, or clear weakrefs. */
!
! /* Maybe call finalizer; exit early if resurrected */
! if (call_finalizer(self) < 0)
! return;
!
! /* Find the nearest base with a different tp_dealloc */
! base = type;
! while ((basedealloc = base->tp_dealloc) == subtype_dealloc) {
! assert(base->ob_size == 0);
! base = base->tp_base;
! assert(base);
! }
!
! /* Call the base tp_dealloc() */
! assert(basedealloc);
! basedealloc(self);
!
! /* Can't reference self beyond this point */
! Py_DECREF(type);
!
! /* Done */
! return;
! }
+ /* We get here only if the type has GC */
+
+ /* UnTrack and re-Track around the trashcan macro, alas */
+ _PyObject_GC_UNTRACK(self);
+ Py_TRASHCAN_SAFE_BEGIN(self);
+ _PyObject_GC_TRACK(self); /* We'll untrack for real later */
+
+ /* Maybe call finalizer; exit early if resurrected */
if (call_finalizer(self) < 0)
return;
***************
*** 431,435 ****
/* Find the nearest base with a different tp_dealloc
and clear slots while we're at it */
- type = self->ob_type;
base = type;
while ((basedealloc = base->tp_dealloc) == subtype_dealloc) {
--- 474,477 ----
***************
*** 457,461 ****
/* Finalize GC if the base doesn't do GC and we do */
! if (PyType_IS_GC(type) && !PyType_IS_GC(base))
_PyObject_GC_UNTRACK(self);
--- 499,503 ----
/* Finalize GC if the base doesn't do GC and we do */
! if (!PyType_IS_GC(base))
_PyObject_GC_UNTRACK(self);
***************
*** 465,471 ****
/* Can't reference self beyond this point */
! if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
! Py_DECREF(type);
! }
}
--- 507,513 ----
/* Can't reference self beyond this point */
! Py_DECREF(type);
!
! Py_TRASHCAN_SAFE_END(self);
}
***************
*** 2808,2812 ****
return Py_None;
}
!
static PyObject *
wrap_descr_delete(PyObject *self, PyObject *args, void *wrapped)
--- 2850,2854 ----
return Py_None;
}
!
static PyObject *
wrap_descr_delete(PyObject *self, PyObject *args, void *wrapped)
***************
*** 2993,2997 ****
return -1;
if (len < 0) {
! PyErr_SetString(PyExc_ValueError,
"__len__() should return >= 0");
return -1;
--- 3035,3039 ----
return -1;
if (len < 0) {
! PyErr_SetString(PyExc_ValueError,
"__len__() should return >= 0");
return -1;
***************
*** 4040,4044 ****
}
! static int recurse_down_subclasses(PyTypeObject *type, slotdef **pp,
PyObject *name);
--- 4082,4086 ----
}
! static int recurse_down_subclasses(PyTypeObject *type, slotdef **pp,
PyObject *name);