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

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

`

1116

1116

`Py_TRASHCAN_SAFE_BEGIN(self);

`

1117

1117

`--_PyTrash_delete_nesting;

`

1118

1118

`-- tstate->trash_delete_nesting;

`

1119

``

`-

/* DO NOT restore GC tracking at this point. weakref callbacks

`

1120

``

`-

`

1121

``

`-

`

1122

``

`-

`

1123

``

`-

*/

`

1124

1119

``

1125

1120

`/* Find the nearest base with a different tp_dealloc */

`

1126

1121

`base = type;

`

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

`

1131

1126

``

1132

1127

`has_finalizer = type->tp_finalize || type->tp_del;

`

1133

1128

``

1134

``

`-

/* Maybe call finalizer; exit early if resurrected */

`

1135

``

`-

if (has_finalizer)

`

1136

``

`-

_PyObject_GC_TRACK(self);

`

1137

``

-

1138

1129

`if (type->tp_finalize) {

`

``

1130

`+

_PyObject_GC_TRACK(self);

`

1139

1131

`if (PyObject_CallFinalizerFromDealloc(self) < 0) {

`

1140

1132

`/* Resurrected */

`

1141

1133

` goto endlabel;

`

1142

1134

` }

`

``

1135

`+

_PyObject_GC_UNTRACK(self);

`

1143

1136

` }

`

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

`+

*/

`

1146

1146

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

`

1147

1147

`PyObject_ClearWeakRefs(self);

`

1148

1148

``

1149

1149

`if (type->tp_del) {

`

``

1150

`+

_PyObject_GC_TRACK(self);

`

1150

1151

`type->tp_del(self);

`

1151

1152

`if (self->ob_refcnt > 0) {

`

1152

1153

`/* Resurrected */

`

1153

1154

` goto endlabel;

`

1154

1155

` }

`

``

1156

`+

_PyObject_GC_UNTRACK(self);

`

1155

1157

` }

`

1156

1158

`if (has_finalizer) {

`

1157

``

`-

_PyObject_GC_UNTRACK(self);

`

1158

1159

`/* New weakrefs could be created during the finalizer call.

`

1159

1160

` If this occurs, clear them out without calling their

`

1160

1161

` finalizers since they might rely on part of the object

`