summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorT. Wouters <thomas@python.org>2023-11-12 00:03:34 (GMT)
committerGitHub <noreply@github.com>2023-11-12 00:03:34 (GMT)
commitce6a533c4bf1afa3775dfcaee5fc7d5c15a4af8c (patch)
treead689a3eee99cfb35b706ad0c604de3bcca15437
parent21615f77b5a580e83589abae618dbe7c298700e2 (diff)
downloadcpython-ce6a533c4bf1afa3775dfcaee5fc7d5c15a4af8c.zip
cpython-ce6a533c4bf1afa3775dfcaee5fc7d5c15a4af8c.tar.gz
cpython-ce6a533c4bf1afa3775dfcaee5fc7d5c15a4af8c.tar.bz2
gh-111777: Fix assertion errors on incorrectly still-tracked GC object destruction (#111778)
In PyObject_GC_Del, in Py_DEBUG mode, when warning about GC objects that were not properly untracked before starting destruction, take care to untrack the object _before_ warning, to avoid triggering a GC run and causing the problem the code tries to warn about. Also make sure to save and restore any pending exceptions, which the warning would otherwise clobber or trigger an assertion error on.
-rw-r--r--Modules/gcmodule.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 3505b08..568e02a 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -2396,14 +2396,16 @@ PyObject_GC_Del(void *op)
size_t presize = _PyType_PreHeaderSize(((PyObject *)op)->ob_type);
PyGC_Head *g = AS_GC(op);
if (_PyObject_GC_IS_TRACKED(op)) {
+ gc_list_remove(g);
#ifdef Py_DEBUG
+ PyObject *exc = PyErr_GetRaisedException();
if (PyErr_WarnExplicitFormat(PyExc_ResourceWarning, "gc", 0,
"gc", NULL, "Object of type %s is not untracked before destruction",
((PyObject*)op)->ob_type->tp_name)) {
PyErr_WriteUnraisable(NULL);
}
+ PyErr_SetRaisedException(exc);
#endif
- gc_list_remove(g);
}
GCState *gcstate = get_gc_state();
if (gcstate->generations[0].count > 0) {