From 261fa2901e6c90a43596ac9107d66d0e3e8f7036 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Wed, 19 Jul 2023 13:45:42 -0600 Subject: [PATCH 1/2] Don't always clear the interned state for a string. --- Objects/unicodeobject.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index f543c0a65b49f6..e8e8cab99c8140 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -14818,6 +14818,7 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp) PyObject *s, *ignored_value; while (PyDict_Next(interned, &pos, &s, &ignored_value)) { assert(PyUnicode_IS_READY(s)); + int shared = 0; switch (PyUnicode_CHECK_INTERNED(s)) { case SSTATE_INTERNED_IMMORTAL: // Skip the Immortal Instance check and restore @@ -14829,6 +14830,14 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp) #endif break; case SSTATE_INTERNED_IMMORTAL_STATIC: + /* It is shared between interpreters, so we should unmark it + only when this is the last interpreter in which it's + interned. We immortalize all the statically initialized + strings during startup, so we can rely on the + main interpreter to be the last one. */ + if (!_Py_IsMainInterpreter(interp)) { + shared = 1; + } break; case SSTATE_INTERNED_MORTAL: /* fall through */ @@ -14837,7 +14846,9 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp) default: Py_UNREACHABLE(); } - _PyUnicode_STATE(s).interned = SSTATE_NOT_INTERNED; + if (!shared) { + _PyUnicode_STATE(s).interned = SSTATE_NOT_INTERNED; + } } #ifdef INTERNED_STATS fprintf(stderr, From eeb53e775ff077ee35d8d2c10dd6c24315190765 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 20 Jul 2023 15:16:10 -0600 Subject: [PATCH 2/2] Add a NEWS entry. --- .../2023-07-20-15-15-57.gh-issue-105699.DdqHFg.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-07-20-15-15-57.gh-issue-105699.DdqHFg.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-20-15-15-57.gh-issue-105699.DdqHFg.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-20-15-15-57.gh-issue-105699.DdqHFg.rst new file mode 100644 index 00000000000000..4a257c6282220f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-07-20-15-15-57.gh-issue-105699.DdqHFg.rst @@ -0,0 +1,3 @@ +Python no longer crashes due an infrequent race when initialzing +per-interpreter interned strings. The crash would manifest when the +interpreter was finalized.