From 626bba4796ef0b723da0a1cdb580e84ef74c76be Mon Sep 17 00:00:00 2001 From: Shamil Abdulaev Date: Fri, 17 Oct 2025 20:13:48 +0300 Subject: [PATCH 1/3] Fix data race on eval_breaker during finalization --- Python/pystate.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Python/pystate.c b/Python/pystate.c index dbed609f29aa07..95f7177a288989 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -763,10 +763,10 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) Py_CLEAR(interp->audit_hooks); - // At this time, all the threads should be cleared so we don't need atomic - // operations for instrumentation_version or eval_breaker. + // Daemon threads may still access eval_breaker atomically via take_gil(). + // Use atomic store to prevent data races during finalization. interp->ceval.instrumentation_version = 0; - tstate->eval_breaker = 0; + _Py_atomic_store_uintptr(&tstate->eval_breaker, 0); for (int i = 0; i < _PY_MONITORING_UNGROUPED_EVENTS; i++) { interp->monitors.tools[i] = 0; From cc0db80af50031a95871244a96f0130fe7e8aee2 Mon Sep 17 00:00:00 2001 From: Shamil Abdulaev Date: Fri, 17 Oct 2025 20:24:42 +0300 Subject: [PATCH 2/3] add blurb --- .../2025-10-17-20-23-19.gh-issue-140257.8Txmem.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-10-17-20-23-19.gh-issue-140257.8Txmem.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-10-17-20-23-19.gh-issue-140257.8Txmem.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-17-20-23-19.gh-issue-140257.8Txmem.rst new file mode 100644 index 00000000000000..50f7e0e48ae369 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-17-20-23-19.gh-issue-140257.8Txmem.rst @@ -0,0 +1,2 @@ +Fix data race between interpreter_clear() and take_gil() on eval_breaker +during finalization with daemon threads. From 059570c40403d2e9058bbd7b17c30f04d7b718fa Mon Sep 17 00:00:00 2001 From: Shamil Date: Fri, 17 Oct 2025 20:57:36 +0300 Subject: [PATCH 3/3] Update Python/pystate.c Co-authored-by: Sam Gross --- Python/pystate.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Python/pystate.c b/Python/pystate.c index 95f7177a288989..c402d89a16145b 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -763,8 +763,9 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) Py_CLEAR(interp->audit_hooks); - // Daemon threads may still access eval_breaker atomically via take_gil(). - // Use atomic store to prevent data races during finalization. + // gh-140257: Threads have already been cleared, but daemon threads may + // still access eval_breaker atomically via take_gil() right before they + // hang. Use an atomic store to prevent data races during finalization. interp->ceval.instrumentation_version = 0; _Py_atomic_store_uintptr(&tstate->eval_breaker, 0);