summaryrefslogtreecommitdiff
path: root/Objects
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2015-11-01 16:13:45 +0200
committerSerhiy Storchaka <storchaka@gmail.com>2015-11-01 16:13:45 +0200
commit08aa6773b42c066ff913075ff27e1d896e16e445 (patch)
treec934cb6b8185067dcb400a8d8bf9ff41b809d79e /Objects
parenta4e35018f9f9530e92f861ef8486a31057704adb (diff)
parent68e5a6ac5dd6a2c84984a77ce2e76a8ecde9ab3f (diff)
downloadcpython-08aa6773b42c066ff913075ff27e1d896e16e445.tar.gz
Issue #25395: Fixed crash when highly nested OrderedDict structures were
garbage collected.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/odictobject.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/Objects/odictobject.c b/Objects/odictobject.c
index 4bdd45ab82..a03e99567e 100644
--- a/Objects/odictobject.c
+++ b/Objects/odictobject.c
@@ -1431,17 +1431,28 @@ static PyMemberDef odict_members[] = {
static void
odict_dealloc(PyODictObject *self)
{
+ PyThreadState *tstate = PyThreadState_GET();
+
PyObject_GC_UnTrack(self);
- Py_TRASHCAN_SAFE_BEGIN(self);
+ Py_TRASHCAN_SAFE_BEGIN(self)
+
Py_XDECREF(self->od_inst_dict);
if (self->od_weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *)self);
_odict_clear_nodes(self);
- Py_TRASHCAN_SAFE_END(self);
- /* must be last */
+ /* Call the base tp_dealloc(). Since it too uses the trashcan mechanism,
+ * temporarily decrement trash_delete_nesting to prevent triggering it
+ * and putting the partially deallocated object on the trashcan's
+ * to-be-deleted-later list.
+ */
+ --tstate->trash_delete_nesting;
+ assert(_tstate->trash_delete_nesting < PyTrash_UNWIND_LEVEL);
PyDict_Type.tp_dealloc((PyObject *)self);
+ ++tstate->trash_delete_nesting;
+
+ Py_TRASHCAN_SAFE_END(self)
};
/* tp_repr */