[3.4] bpo-26617: Ensure gc tracking is off when invoking weakref call… · python/cpython@34fae03

@@ -1116,11 +1116,6 @@ subtype_dealloc(PyObject *self)

11161116

Py_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 */

11261121

base = type;

@@ -1131,30 +1126,36 @@ subtype_dealloc(PyObject *self)

1131112611321127

has_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-11381129

if (type->tp_finalize) {

1130+

_PyObject_GC_TRACK(self);

11391131

if (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+

*/

11461146

if (type->tp_weaklistoffset && !base->tp_weaklistoffset)

11471147

PyObject_ClearWeakRefs(self);

1148114811491149

if (type->tp_del) {

1150+

_PyObject_GC_TRACK(self);

11501151

type->tp_del(self);

11511152

if (self->ob_refcnt > 0) {

11521153

/* Resurrected */

11531154

goto endlabel;

11541155

}

1156+

_PyObject_GC_UNTRACK(self);

11551157

}

11561158

if (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