-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
gh-130202: Fix bug in _PyObject_ResurrectEnd
in free threaded build
#130281
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
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
… build This fixes a fairly subtle bug involving finalizers and resurrection in debug free threaded builds: if `_PyObject_ResurrectEnd` returns `1` (i.e., the object was resurrected by a finalizer), it's not safe to access the object because it might still be deallocated. For example: * The finalizer may have exposed the object to another thread. That thread may hold the last reference and concurrently deallocate it any time after `_PyObject_ResurrectEnd()` returns `1`. * `_PyObject_ResurrectEnd()` may call `_Py_brc_queue_object()`, which may internally deallocate the object immediately if the owning thread is dead. Therefore, it's important not to access the object after it's resurrected. We only violate this in two cases, and only in debug builds: * We assert that the object is tracked appropriately. This is now moved up betewen the finalizer and the `_PyObject_ResurrectEnd()` call. * The `--with-trace-refs` builds may need to remember the object if it's resurrected. This is now handled by `_PyObject_ResurrectStart()` and `_PyObject_ResurrectEnd()`. Note that `--with-trace-refs` is currently disabled in `--disable-gil` builds because the refchain hash table isn't thread-safe, but this refactoring avoids an additional thread-safety issue.
a6dc1d7
to
bfac5b2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
Not sure what's going on with the failure here - there was a failure trying to initialise a sub interpreter. The subsequent CI run passed without error. |
… build (pythongh-130281) This fixes a fairly subtle bug involving finalizers and resurrection in debug free threaded builds: if `_PyObject_ResurrectEnd` returns `1` (i.e., the object was resurrected by a finalizer), it's not safe to access the object because it might still be deallocated. For example: * The finalizer may have exposed the object to another thread. That thread may hold the last reference and concurrently deallocate it any time after `_PyObject_ResurrectEnd()` returns `1`. * `_PyObject_ResurrectEnd()` may call `_Py_brc_queue_object()`, which may internally deallocate the object immediately if the owning thread is dead. Therefore, it's important not to access the object after it's resurrected. We only violate this in two cases, and only in debug builds: * We assert that the object is tracked appropriately. This is now moved up betewen the finalizer and the `_PyObject_ResurrectEnd()` call. * The `--with-trace-refs` builds may need to remember the object if it's resurrected. This is now handled by `_PyObject_ResurrectStart()` and `_PyObject_ResurrectEnd()`. Note that `--with-trace-refs` is currently disabled in `--disable-gil` builds because the refchain hash table isn't thread-safe, but this refactoring avoids an additional thread-safety issue.
This fixes a fairly subtle bug involving finalizers and resurrection in debug free threaded builds: if
_PyObject_ResurrectEnd
returns1
(i.e., the object was resurrected by a finalizer), it's not safe to access the object because it might still be deallocated. For example:_PyObject_ResurrectEnd()
returns1
._PyObject_ResurrectEnd()
may call_Py_brc_queue_object()
, which may internally deallocate the object immediately if the owning thread is dead.Therefore, it's important not to access the object after it's resurrected. We only violate this in two cases, and only in debug builds:
We assert that the object is tracked appropriately. This is now moved up betewen the finalizer and the
_PyObject_ResurrectEnd()
call.The
--with-trace-refs
builds may need to remember the object if it's resurrected. This is now handled by_PyObject_ResurrectStart()
and_PyObject_ResurrectEnd()
.Note that
--with-trace-refs
is currently disabled in--disable-gil
builds because the refchain hash table isn't thread-safe, but this refactoring avoids an additional thread-safety issue._PyObject_ResurrectEnd
may deallocate object in the "resurrection" case #130202