mirror of
https://github.com/python/cpython.git
synced 2025-08-09 19:38:42 +00:00
[3.12] gh-119585: Fix crash involving PyGILState_Release()
and PyThreadState_Clear()
(GH-119753) (#119861)
Make sure that `gilstate_counter` is not zero in when calling
`PyThreadState_Clear()`. A destructor called from `PyThreadState_Clear()` may
call back into `PyGILState_Ensure()` and `PyGILState_Release()`. If
`gilstate_counter` is zero, it will try to create a new thread state before
the current active thread state is destroyed, leading to an assertion failure
or crash.
(cherry picked from commit bcc1be39cb
)
This commit is contained in:
parent
d4680b9e17
commit
738cf21609
4 changed files with 36 additions and 0 deletions
|
@ -2277,12 +2277,18 @@ PyGILState_Release(PyGILState_STATE oldstate)
|
|||
/* can't have been locked when we created it */
|
||||
assert(oldstate == PyGILState_UNLOCKED);
|
||||
// XXX Unbind tstate here.
|
||||
// gh-119585: `PyThreadState_Clear()` may call destructors that
|
||||
// themselves use PyGILState_Ensure and PyGILState_Release, so make
|
||||
// sure that gilstate_counter is not zero when calling it.
|
||||
++tstate->gilstate_counter;
|
||||
PyThreadState_Clear(tstate);
|
||||
--tstate->gilstate_counter;
|
||||
/* Delete the thread-state. Note this releases the GIL too!
|
||||
* It's vital that the GIL be held here, to avoid shutdown
|
||||
* races; see bugs 225673 and 1061968 (that nasty bug has a
|
||||
* habit of coming back).
|
||||
*/
|
||||
assert(tstate->gilstate_counter == 0);
|
||||
assert(current_fast_get(runtime) == tstate);
|
||||
_PyThreadState_DeleteCurrent(tstate);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue