mirror of https://github.com/python/cpython
gh-116510: Fix crash during sub-interpreter shutdown (gh-124645)
Fix a bug that can cause a crash when sub-interpreters use "basic" single-phase extension modules. Shared objects could refer to PyGC_Head nodes that had been freed as part of interpreter shutdown.
This commit is contained in:
parent
98b2ed7e23
commit
6f9525dd3f
|
@ -0,0 +1,3 @@
|
||||||
|
Fix a bug that can cause a crash when sub-interpreters use "basic"
|
||||||
|
single-phase extension modules. Shared objects could refer to PyGC_Head
|
||||||
|
nodes that had been freed as part of interpreter cleanup.
|
29
Python/gc.c
29
Python/gc.c
|
@ -1944,6 +1944,13 @@ _PyGC_DumpShutdownStats(PyInterpreterState *interp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
finalize_unlink_gc_head(PyGC_Head *gc) {
|
||||||
|
PyGC_Head *prev = GC_PREV(gc);
|
||||||
|
PyGC_Head *next = GC_NEXT(gc);
|
||||||
|
_PyGCHead_SET_NEXT(prev, next);
|
||||||
|
_PyGCHead_SET_PREV(next, prev);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_PyGC_Fini(PyInterpreterState *interp)
|
_PyGC_Fini(PyInterpreterState *interp)
|
||||||
|
@ -1952,9 +1959,25 @@ _PyGC_Fini(PyInterpreterState *interp)
|
||||||
Py_CLEAR(gcstate->garbage);
|
Py_CLEAR(gcstate->garbage);
|
||||||
Py_CLEAR(gcstate->callbacks);
|
Py_CLEAR(gcstate->callbacks);
|
||||||
|
|
||||||
/* We expect that none of this interpreters objects are shared
|
/* Prevent a subtle bug that affects sub-interpreters that use basic
|
||||||
with other interpreters.
|
* single-phase init extensions (m_size == -1). Those extensions cause objects
|
||||||
See https://github.com/python/cpython/issues/90228. */
|
* to be shared between interpreters, via the PyDict_Update(mdict, m_copy) call
|
||||||
|
* in import_find_extension().
|
||||||
|
*
|
||||||
|
* If they are GC objects, their GC head next or prev links could refer to
|
||||||
|
* the interpreter _gc_runtime_state PyGC_Head nodes. Those nodes go away
|
||||||
|
* when the interpreter structure is freed and so pointers to them become
|
||||||
|
* invalid. If those objects are still used by another interpreter and
|
||||||
|
* UNTRACK is called on them, a crash will happen. We untrack the nodes
|
||||||
|
* here to avoid that.
|
||||||
|
*
|
||||||
|
* This bug was originally fixed when reported as gh-90228. The bug was
|
||||||
|
* re-introduced in gh-94673.
|
||||||
|
*/
|
||||||
|
finalize_unlink_gc_head(&gcstate->young.head);
|
||||||
|
finalize_unlink_gc_head(&gcstate->old[0].head);
|
||||||
|
finalize_unlink_gc_head(&gcstate->old[1].head);
|
||||||
|
finalize_unlink_gc_head(&gcstate->permanent_generation.head);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* for debugging */
|
/* for debugging */
|
||||||
|
|
Loading…
Reference in New Issue