Skip to content

Commit 1cd2b97

Browse files
[3.13] gh-116510: Fix crash during sub-interpreter shutdown (gh-124645) (#124649)
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. (cherry picked from commit 6f9525d) Co-authored-by: Neil Schemenauer <nas-github@arctrix.com>
1 parent caaf939 commit 1cd2b97

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
@@ -1926,6 +1926,13 @@ _PyGC_DumpShutdownStats(PyInterpreterState *interp)
19261926
}
19271927
}
19281928

1929+
static void
1930+
finalize_unlink_gc_head(PyGC_Head *gc) {
1931+
PyGC_Head *prev = GC_PREV(gc);
1932+
PyGC_Head *next = GC_NEXT(gc);
1933+
_PyGCHead_SET_NEXT(prev, next);
1934+
_PyGCHead_SET_PREV(next, prev);
1935+
}
19291936

19301937
void
19311938
_PyGC_Fini(PyInterpreterState *interp)
@@ -1934,9 +1941,25 @@ _PyGC_Fini(PyInterpreterState *interp)
19341941
Py_CLEAR(gcstate->garbage);
19351942
Py_CLEAR(gcstate->callbacks);
19361943

1937-
/* We expect that none of this interpreters objects are shared
1938-
with other interpreters.
1939-
See https://github.com/python/cpython/issues/90228. */
1944+
/* Prevent a subtle bug that affects sub-interpreters that use basic
1945+
* single-phase init extensions (m_size == -1). Those extensions cause objects
1946+
* to be shared between interpreters, via the PyDict_Update(mdict, m_copy) call
1947+
* in import_find_extension().
1948+
*
1949+
* If they are GC objects, their GC head next or prev links could refer to
1950+
* the interpreter _gc_runtime_state PyGC_Head nodes. Those nodes go away
1951+
* when the interpreter structure is freed and so pointers to them become
1952+
* invalid. If those objects are still used by another interpreter and
1953+
* UNTRACK is called on them, a crash will happen. We untrack the nodes
1954+
* here to avoid that.
1955+
*
1956+
* This bug was originally fixed when reported as gh-90228. The bug was
1957+
* re-introduced in gh-94673.
1958+
*/
1959+
finalize_unlink_gc_head(&gcstate->young.head);
1960+
finalize_unlink_gc_head(&gcstate->old[0].head);
1961+
finalize_unlink_gc_head(&gcstate->old[1].head);
1962+
finalize_unlink_gc_head(&gcstate->permanent_generation.head);
19401963
}
19411964

19421965
/* for debugging */

0 commit comments

Comments
 (0)