gh-119585: Fix crash involving PyGILState_Release() and PyThreadState_Clear() (#119753)

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.
This commit is contained in:
Sam Gross 2024-05-31 10:50:52 -04:00 committed by GitHub
parent 891c1e36f4
commit bcc1be39cb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 36 additions and 0 deletions

View file

@ -764,6 +764,14 @@ test_thread_state(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
static PyObject *
gilstate_ensure_release(PyObject *module, PyObject *Py_UNUSED(ignored))
{
PyGILState_STATE state = PyGILState_Ensure();
PyGILState_Release(state);
Py_RETURN_NONE;
}
#ifndef MS_WINDOWS
static PyThread_type_lock wait_done = NULL;
@ -3351,6 +3359,7 @@ static PyMethodDef TestMethods[] = {
{"test_get_type_dict", test_get_type_dict, METH_NOARGS},
{"test_reftracer", test_reftracer, METH_NOARGS},
{"_test_thread_state", test_thread_state, METH_VARARGS},
{"gilstate_ensure_release", gilstate_ensure_release, METH_NOARGS},
#ifndef MS_WINDOWS
{"_spawn_pthread_waiter", spawn_pthread_waiter, METH_NOARGS},
{"_end_spawned_pthread", end_spawned_pthread, METH_NOARGS},