-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Crash in freethreading when acquiring/releasing the GIL in a finalizer #119585
Comments
Thanks -- I was able to reproduce the issue easily with your repro. The problem is roughly:
I think the fix is relatively simple: don't decrement the Line 2801 in a150679
|
…readState_Clear()` Don't decrement `gilstate_counter` in `PyGILState_Release()` until after `PyThreadState_Clear()` is called. A destructor called from `PyThreadState_Clear()` may call back into `PyGILState_Ensure()` and PyGILState_Release()` and if `gilstate_counter` is zero, it will try to create a new thread state before the current active thread state is destroyed.
…ate_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.
…readState_Clear()` (pythonGH-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. (cherry picked from commit bcc1be3) Co-authored-by: Sam Gross <[email protected]>
…d `PyThreadState_Clear()` (pythonGH-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. (cherry picked from commit bcc1be3) Co-authored-by: Sam Gross <[email protected]>
…d `PyThreadState_Clear()` (pythonGH-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. (cherry picked from commit bcc1be3) Co-authored-by: Sam Gross <[email protected]>
…hreadState_Clear()` (GH-119753) (#119859) 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 bcc1be3) Co-authored-by: Sam Gross <[email protected]>
…hreadState_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 bcc1be3)
@colesbury Thanks for the quick PR to fix it. I'm closing the issue since I'm assuming it was left open as an oversight and not because there's more to do. But please correct that if I'm wrong. |
…readState_Clear()` (python#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.
…readState_Clear()` (python#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.
Bug report
Bug description:
bug.cpp
setupbug.py
testbug.py
Build with
python setupbug.py build_ext --inplace
Run with
python -Xgil=0 testbug.py
I'm a little unclear on exactly what's going wrong here, but essentially it's destroying the C object from within
merge_queued_objects(&brc->local_objects_to_merge);
,callInDestruction()
callsPyGILState_Ensure
andPyGILState_Release
(which is unnecessary because it already has the GIL, but should be fine anyway), and it's around here that it crashes with a segmentation fault.If I remove the GIL handing from
callInDestruction
then it doesn't crash for me.This is a cut-down version of something I've seen in Cython cython/cython#6214 (comment) with a very similar crash but happening in a slightly different way.
CPython versions tested on:
3.13
Operating systems tested on:
Linux
Linked PRs
PyGILState_Release()
andPyThreadState_Clear()
#119753PyGILState_Release()
andPyThreadState_Clear()
(GH-119753) #119859PyGILState_Release()
andPyThreadState_Clear()
(GH-119753) #119861The text was updated successfully, but these errors were encountered: