mirror of https://github.com/python/cpython
bpo-46070: _PyGC_Fini() untracks objects (GH-30577)
Py_EndInterpreter() now explicitly untracks all objects currently tracked by the GC. Previously, if an object was used later by another interpreter, calling PyObject_GC_UnTrack() on the object crashed if the previous or the next object of the PyGC_Head structure became a dangling pointer.
This commit is contained in:
parent
6be848922b
commit
1a4d1c1c9b
|
@ -0,0 +1,5 @@
|
|||
:c:func:`Py_EndInterpreter` now explicitly untracks all objects currently
|
||||
tracked by the GC. Previously, if an object was used later by another
|
||||
interpreter, calling :c:func:`PyObject_GC_UnTrack` on the object crashed if the
|
||||
previous or the next object of the :c:type:`PyGC_Head` structure became a
|
||||
dangling pointer. Patch by Victor Stinner.
|
|
@ -2161,12 +2161,36 @@ _PyGC_DumpShutdownStats(PyInterpreterState *interp)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gc_fini_untrack(PyGC_Head *list)
|
||||
{
|
||||
PyGC_Head *gc;
|
||||
for (gc = GC_NEXT(list); gc != list; gc = GC_NEXT(list)) {
|
||||
PyObject *op = FROM_GC(gc);
|
||||
_PyObject_GC_UNTRACK(op);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_PyGC_Fini(PyInterpreterState *interp)
|
||||
{
|
||||
GCState *gcstate = &interp->gc;
|
||||
Py_CLEAR(gcstate->garbage);
|
||||
Py_CLEAR(gcstate->callbacks);
|
||||
|
||||
if (!_Py_IsMainInterpreter(interp)) {
|
||||
// bpo-46070: Explicitly untrack all objects currently tracked by the
|
||||
// GC. Otherwise, if an object is used later by another interpreter,
|
||||
// calling PyObject_GC_UnTrack() on the object crashs if the previous
|
||||
// or the next object of the PyGC_Head structure became a dangling
|
||||
// pointer.
|
||||
for (int i = 0; i < NUM_GENERATIONS; i++) {
|
||||
PyGC_Head *gen = GEN_HEAD(gcstate, i);
|
||||
gc_fini_untrack(gen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* for debugging */
|
||||
|
|
Loading…
Reference in New Issue