https://github.com/python/cpython/commit/69fd1f218c8b26f75aa230c9459f24fe05fdd784
commit: 69fd1f218c8b26f75aa230c9459f24fe05fdd784
branch: 3.12
author: Neil Schemenauer <[email protected]>
committer: nascheme <[email protected]>
date: 2024-09-26T17:50:46-07:00
summary:
[3.12] gh-116510: Fix crash during sub-interpreter shutdown (gh-124536)
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.
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-12-05-45.gh-issue-116510.dhn8w8.rst
M Modules/gcmodule.c
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-12-05-45.gh-issue-116510.dhn8w8.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-12-05-45.gh-issue-116510.dhn8w8.rst
new file mode 100644
index 00000000000000..fc3f8af72d87bf
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2024-09-25-12-05-45.gh-issue-116510.dhn8w8.rst
@@ -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.
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index f8c774cbb75e56..e14d9d58f8c464 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -2174,6 +2174,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
_PyGC_Fini(PyInterpreterState *interp)
@@ -2182,9 +2189,25 @@ _PyGC_Fini(PyInterpreterState *interp)
Py_CLEAR(gcstate->garbage);
Py_CLEAR(gcstate->callbacks);
- /* We expect that none of this interpreters objects are shared
- with other interpreters.
- See https://github.com/python/cpython/issues/90228. */
+ /* Prevent a subtle bug that affects sub-interpreters that use basic
+ * single-phase init extensions (m_size == -1). Those extensions cause
objects
+ * 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.
+ */
+ for (int i = 0; i < NUM_GENERATIONS; i++) {
+ finalize_unlink_gc_head(&gcstate->generations[i].head);
+ }
+ finalize_unlink_gc_head(&gcstate->permanent_generation.head);
}
/* for debugging */
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]