mirror of
https://github.com/python/cpython.git
synced 2025-07-19 01:05: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
25
Python/gc.c
25
Python/gc.c
|
@ -870,7 +870,7 @@ move_legacy_finalizer_reachable(PyGC_Head *finalizers)
|
|||
* no object in `unreachable` is weakly referenced anymore.
|
||||
*/
|
||||
static int
|
||||
handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
|
||||
handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old, bool allow_callbacks)
|
||||
{
|
||||
PyGC_Head *gc;
|
||||
PyObject *op; /* generally FROM_GC(gc) */
|
||||
|
@ -879,7 +879,9 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
|
|||
PyGC_Head *next;
|
||||
int num_freed = 0;
|
||||
|
||||
gc_list_init(&wrcb_to_call);
|
||||
if (allow_callbacks) {
|
||||
gc_list_init(&wrcb_to_call);
|
||||
}
|
||||
|
||||
/* Clear all weakrefs to the objects in unreachable. If such a weakref
|
||||
* also has a callback, move it into `wrcb_to_call` if the callback
|
||||
|
@ -935,6 +937,11 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
|
|||
_PyObject_ASSERT((PyObject *)wr, wr->wr_object == op);
|
||||
_PyWeakref_ClearRef(wr);
|
||||
_PyObject_ASSERT((PyObject *)wr, wr->wr_object == Py_None);
|
||||
|
||||
if (!allow_callbacks) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wr->wr_callback == NULL) {
|
||||
/* no callback */
|
||||
continue;
|
||||
|
@ -987,6 +994,10 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
|
|||
}
|
||||
}
|
||||
|
||||
if (!allow_callbacks) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Invoke the callbacks we decided to honor. It's safe to invoke them
|
||||
* because they can't reference unreachable objects.
|
||||
*/
|
||||
|
@ -1737,7 +1748,7 @@ gc_collect_region(PyThreadState *tstate,
|
|||
}
|
||||
|
||||
/* Clear weakrefs and invoke callbacks as necessary. */
|
||||
stats->collected += handle_weakrefs(&unreachable, to);
|
||||
stats->collected += handle_weakrefs(&unreachable, to, true);
|
||||
gc_list_validate_space(to, gcstate->visited_space);
|
||||
validate_list(to, collecting_clear_unreachable_clear);
|
||||
validate_list(&unreachable, collecting_set_unreachable_clear);
|
||||
|
@ -1751,6 +1762,14 @@ gc_collect_region(PyThreadState *tstate,
|
|||
gc_list_init(&final_unreachable);
|
||||
handle_resurrected_objects(&unreachable, &final_unreachable, to);
|
||||
|
||||
/* 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. Callbacks are not executed.
|
||||
*/
|
||||
handle_weakrefs(&final_unreachable, NULL, false);
|
||||
|
||||
/* Call tp_clear on objects in the final_unreachable set. This will cause
|
||||
* the reference cycles to be broken. It may also cause some objects
|
||||
* in finalizers to be freed.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue