[3.4] bpo-26617: Ensure gc tracking is off when invoking weakref call… · python/cpython@34fae03
@@ -1116,11 +1116,6 @@ subtype_dealloc(PyObject *self)
11161116Py_TRASHCAN_SAFE_BEGIN(self);
11171117--_PyTrash_delete_nesting;
11181118-- tstate->trash_delete_nesting;
1119-/* DO NOT restore GC tracking at this point. weakref callbacks
1120- * (if any, and whether directly here or indirectly in something we
1121- * call) may trigger GC, and if self is tracked at that point, it
1122- * will look like trash to GC and GC will try to delete self again.
1123- */
1124111911251120/* Find the nearest base with a different tp_dealloc */
11261121base = type;
@@ -1131,30 +1126,36 @@ subtype_dealloc(PyObject *self)
1131112611321127has_finalizer = type->tp_finalize || type->tp_del;
113311281134-/* Maybe call finalizer; exit early if resurrected */
1135-if (has_finalizer)
1136-_PyObject_GC_TRACK(self);
1137-11381129if (type->tp_finalize) {
1130+_PyObject_GC_TRACK(self);
11391131if (PyObject_CallFinalizerFromDealloc(self) < 0) {
11401132/* Resurrected */
11411133 goto endlabel;
11421134 }
1135+_PyObject_GC_UNTRACK(self);
11431136 }
1144-/* If we added a weaklist, we clear it. Do this *before* calling
1145- tp_del, clearing slots, or clearing the instance dict. */
1137+/*
1138+ If we added a weaklist, we clear it. Do this *before* calling tp_del,
1139+ clearing slots, or clearing the instance dict.
1140+1141+ GC tracking must be off at this point. weakref callbacks (if any, and
1142+ whether directly here or indirectly in something we call) may trigger GC,
1143+ and if self is tracked at that point, it will look like trash to GC and GC
1144+ will try to delete self again.
1145+ */
11461146if (type->tp_weaklistoffset && !base->tp_weaklistoffset)
11471147PyObject_ClearWeakRefs(self);
1148114811491149if (type->tp_del) {
1150+_PyObject_GC_TRACK(self);
11501151type->tp_del(self);
11511152if (self->ob_refcnt > 0) {
11521153/* Resurrected */
11531154 goto endlabel;
11541155 }
1156+_PyObject_GC_UNTRACK(self);
11551157 }
11561158if (has_finalizer) {
1157-_PyObject_GC_UNTRACK(self);
11581159/* New weakrefs could be created during the finalizer call.
11591160 If this occurs, clear them out without calling their
11601161 finalizers since they might rely on part of the object