mirror of
https://github.com/python/cpython.git
synced 2025-07-09 20:35:26 +00:00
GH-91636: Clear weakrefs created by finalizers. (GH-136401)
Some checks are pending
Tests / (push) Blocked by required conditions
Tests / Windows MSI (push) Blocked by required conditions
Tests / Change detection (push) Waiting to run
Tests / Docs (push) Blocked by required conditions
Tests / Check if Autoconf files are up to date (push) Blocked by required conditions
Tests / Check if generated files are up to date (push) Blocked by required conditions
Tests / Ubuntu SSL tests with OpenSSL (push) Blocked by required conditions
Tests / WASI (push) Blocked by required conditions
Tests / Hypothesis tests on Ubuntu (push) Blocked by required conditions
Tests / Address sanitizer (push) Blocked by required conditions
Tests / Undefined behavior sanitizer (push) Blocked by required conditions
Tests / Cross build Linux (push) Blocked by required conditions
Tests / CIFuzz (push) Blocked by required conditions
Tests / All required checks pass (push) Blocked by required conditions
Lint / lint (push) Waiting to run
mypy / Run mypy on Lib/_pyrepl (push) Waiting to run
mypy / Run mypy on Lib/test/libregrtest (push) Waiting to run
mypy / Run mypy on Lib/tomllib (push) Waiting to run
mypy / Run mypy on Tools/build (push) Waiting to run
mypy / Run mypy on Tools/cases_generator (push) Waiting to run
mypy / Run mypy on Tools/clinic (push) Waiting to run
mypy / Run mypy on Tools/jit (push) Waiting to run
mypy / Run mypy on Tools/peg_generator (push) Waiting to run
Some checks are pending
Tests / (push) Blocked by required conditions
Tests / Windows MSI (push) Blocked by required conditions
Tests / Change detection (push) Waiting to run
Tests / Docs (push) Blocked by required conditions
Tests / Check if Autoconf files are up to date (push) Blocked by required conditions
Tests / Check if generated files are up to date (push) Blocked by required conditions
Tests / Ubuntu SSL tests with OpenSSL (push) Blocked by required conditions
Tests / WASI (push) Blocked by required conditions
Tests / Hypothesis tests on Ubuntu (push) Blocked by required conditions
Tests / Address sanitizer (push) Blocked by required conditions
Tests / Undefined behavior sanitizer (push) Blocked by required conditions
Tests / Cross build Linux (push) Blocked by required conditions
Tests / CIFuzz (push) Blocked by required conditions
Tests / All required checks pass (push) Blocked by required conditions
Lint / lint (push) Waiting to run
mypy / Run mypy on Lib/_pyrepl (push) Waiting to run
mypy / Run mypy on Lib/test/libregrtest (push) Waiting to run
mypy / Run mypy on Lib/tomllib (push) Waiting to run
mypy / Run mypy on Tools/build (push) Waiting to run
mypy / Run mypy on Tools/cases_generator (push) Waiting to run
mypy / Run mypy on Tools/clinic (push) Waiting to run
mypy / Run mypy on Tools/jit (push) Waiting to run
mypy / Run mypy on Tools/peg_generator (push) Waiting to run
Weakrefs to unreachable garbage that are created during running of finalizers need to be cleared. This avoids exposing objects that have `tp_clear` called on them to Python-level code.
This commit is contained in:
parent
bc9bc078df
commit
b6b99bf7f1
4 changed files with 54 additions and 14 deletions
|
@ -1492,9 +1492,9 @@ move_legacy_finalizer_reachable(struct collection_state *state)
|
|||
}
|
||||
|
||||
// Clear all weakrefs to unreachable objects. Weakrefs with callbacks are
|
||||
// enqueued in `wrcb_to_call`, but not invoked yet.
|
||||
// optionally enqueued in `wrcb_to_call`, but not invoked yet.
|
||||
static void
|
||||
clear_weakrefs(struct collection_state *state)
|
||||
clear_weakrefs(struct collection_state *state, bool enqueue_callbacks)
|
||||
{
|
||||
PyObject *op;
|
||||
WORKSTACK_FOR_EACH(&state->unreachable, op) {
|
||||
|
@ -1526,6 +1526,10 @@ clear_weakrefs(struct collection_state *state)
|
|||
_PyWeakref_ClearRef(wr);
|
||||
_PyObject_ASSERT((PyObject *)wr, wr->wr_object == Py_None);
|
||||
|
||||
if (!enqueue_callbacks) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We do not invoke callbacks for weakrefs that are themselves
|
||||
// unreachable. This is partly for historical reasons: weakrefs
|
||||
// predate safe object finalization, and a weakref that is itself
|
||||
|
@ -2211,7 +2215,7 @@ gc_collect_internal(PyInterpreterState *interp, struct collection_state *state,
|
|||
interp->gc.long_lived_total = state->long_lived_total;
|
||||
|
||||
// Clear weakrefs and enqueue callbacks (but do not call them).
|
||||
clear_weakrefs(state);
|
||||
clear_weakrefs(state, true);
|
||||
_PyEval_StartTheWorld(interp);
|
||||
|
||||
// Deallocate any object from the refcount merge step
|
||||
|
@ -2222,11 +2226,19 @@ gc_collect_internal(PyInterpreterState *interp, struct collection_state *state,
|
|||
call_weakref_callbacks(state);
|
||||
finalize_garbage(state);
|
||||
|
||||
// Handle any objects that may have resurrected after the finalization.
|
||||
_PyEval_StopTheWorld(interp);
|
||||
// Handle any objects that may have resurrected after the finalization.
|
||||
err = handle_resurrected_objects(state);
|
||||
// Clear free lists in all threads
|
||||
_PyGC_ClearAllFreeLists(interp);
|
||||
if (err == 0) {
|
||||
// Clear weakrefs to objects in the unreachable set. No Python-level
|
||||
// code must be allowed to access those unreachable objects. During
|
||||
// delete_garbage(), finalizers outside the unreachable set might
|
||||
// run and create new weakrefs. If those weakrefs were not cleared,
|
||||
// they could reveal unreachable objects.
|
||||
clear_weakrefs(state, false);
|
||||
}
|
||||
_PyEval_StartTheWorld(interp);
|
||||
|
||||
if (err < 0) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue