diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2015-11-01 16:13:45 +0200 |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2015-11-01 16:13:45 +0200 |
commit | 08aa6773b42c066ff913075ff27e1d896e16e445 (patch) | |
tree | c934cb6b8185067dcb400a8d8bf9ff41b809d79e /Objects | |
parent | a4e35018f9f9530e92f861ef8486a31057704adb (diff) | |
parent | 68e5a6ac5dd6a2c84984a77ce2e76a8ecde9ab3f (diff) | |
download | cpython-08aa6773b42c066ff913075ff27e1d896e16e445.tar.gz |
Issue #25395: Fixed crash when highly nested OrderedDict structures were
garbage collected.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/odictobject.c | 17 |
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 */ |