[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
``
`-
- (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
``
`-
*/
`
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
`