Skip to content

Commit 6f9525d

Browse files
authored
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.
1 parent 98b2ed7 commit 6f9525d

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a bug that can cause a crash when sub-interpreters use "basic"
2+
single-phase extension modules. Shared objects could refer to PyGC_Head
3+
nodes that had been freed as part of interpreter cleanup.

Python/gc.c

+26-3
Original file line numberDiff line numberDiff line change
@@ -1944,6 +1944,13 @@ _PyGC_DumpShutdownStats(PyInterpreterState *interp)
19441944
}
19451945
}
19461946

1947+
static void
1948+
finalize_unlink_gc_head(PyGC_Head *gc) {
1949+
PyGC_Head *prev = GC_PREV(gc);
1950+
PyGC_Head *next = GC_NEXT(gc);
1951+
_PyGCHead_SET_NEXT(prev, next);
1952+
_PyGCHead_SET_PREV(next, prev);
1953+
}
19471954

19481955
void
19491956
_PyGC_Fini(PyInterpreterState *interp)
@@ -1952,9 +1959,25 @@ _PyGC_Fini(PyInterpreterState *interp)
19521959
Py_CLEAR(gcstate->garbage);
19531960
Py_CLEAR(gcstate->callbacks);
19541961

1955-
/* We expect that none of this interpreters objects are shared
1956-
with other interpreters.
1957-
See https://github.com/python/cpython/issues/90228. */
1962+
/* Prevent a subtle bug that affects sub-interpreters that use basic
1963+
* single-phase init extensions (m_size == -1). Those extensions cause objects
1964+
* to be shared between interpreters, via the PyDict_Update(mdict, m_copy) call
1965+
* in import_find_extension().
1966+
*
1967+
* If they are GC objects, their GC head next or prev links could refer to
1968+
* the interpreter _gc_runtime_state PyGC_Head nodes. Those nodes go away
1969+
* when the interpreter structure is freed and so pointers to them become
1970+
* invalid. If those objects are still used by another interpreter and
1971+
* UNTRACK is called on them, a crash will happen. We untrack the nodes
1972+
* here to avoid that.
1973+
*
1974+
* This bug was originally fixed when reported as gh-90228. The bug was
1975+
* re-introduced in gh-94673.
1976+
*/
1977+
finalize_unlink_gc_head(&gcstate->young.head);
1978+
finalize_unlink_gc_head(&gcstate->old[0].head);
1979+
finalize_unlink_gc_head(&gcstate->old[1].head);
1980+
finalize_unlink_gc_head(&gcstate->permanent_generation.head);
19581981
}
19591982

19601983
/* for debugging */

0 commit comments

Comments
 (0)