[3.13] gh-154175: Fetch _PY_GIL_DROP_REQUEST_BIT under GIL (#157013)

gh-154175: Fetch _PY_GIL_DROP_REQUEST_BIT under GIL

Once the GIL is released the tstate may be freed which shows up as ASAN
and TSAN failures in test_io with daemon threads. Check the bit before
dropping the GIL so the tstate is guaranteed to still be allocated.

Remove the TSAN suppressions which were added for 3.13 as this should
fix this case.
This commit is contained in:
Cody Maloney authored and GitHub committed 2026-09-29 23:24:31 +02:00
1 parent d5527b6658
commit 6959d94c01
4 files changed
+10 -8

No files matched your search

@@ -0,0 +1,4 @@
Move GIL drop request bit fetching to live under the :term:`GIL` so the
:c:type:`PyThreadState` it accesses is guaranteed not to be deallocated.
Deallocation could occur when a daemon thread was shutting down after the
main thread.
+6 -2
View File
@@ -246,11 +246,16 @@ drop_gil(PyInterpreterState *interp, PyThreadState *tstate, int final_release)
Py_FatalError("drop_gil: GIL is not locked");
}
int drop_requested = 0;
if (!final_release) {
/* Sub-interpreter support: threads might have been switched
under our feet using PyThreadState_Swap(). Fix the GIL last
holder variable so that our heuristics work. */
_Py_atomic_store_ptr_relaxed(&gil->last_holder, tstate);
/* Checked here as tstate may freed outside gil. */
drop_requested = _Py_eval_breaker_bit_is_set(tstate,
_PY_GIL_DROP_REQUEST_BIT);
}
drop_gil_impl(tstate, gil);
@@ -262,8 +267,7 @@ drop_gil(PyInterpreterState *interp, PyThreadState *tstate, int final_release)
crash. We can use final_release to indicate the thread is done with the
GIL, and that's the only time we might delete the interpreter. See
https://github.com/python/cpython/issues/104341. */
if (!final_release &&
_Py_eval_breaker_bit_is_set(tstate, _PY_GIL_DROP_REQUEST_BIT)) {
if (!final_release && drop_requested) {
MUTEX_LOCK(gil->switch_mutex);
/* Not switched yet => wait */
if (((PyThreadState*)_Py_atomic_load_ptr_relaxed(&gil->last_holder)) == tstate)
-3
View File
@@ -3,8 +3,5 @@
race:get_allocator_unlocked
race:set_allocator_unlocked
# gh-124878: race condition when interpreter finalized while daemon thread runs
race:free_threadstate
# https://gist.github.com/mpage/daaf32b39180c1989572957b943eb665
thread:pthread_create
@@ -18,9 +18,6 @@ race:set_allocator_unlocked
# https://gist.github.com/swtaarrs/8e0e365e1d9cecece3269a2fb2f2b8b8
race:sock_recv_impl
# gh-124878: race condition when interpreter finalized while daemon thread runs
race:free_threadstate
# These warnings trigger directly in a CPython function.