[Python-checkins] (no subject)
Łukasz Langa
webhook-mailer at python.org
Mon Sep 30 13:27:51 EDT 2019
To: python-checkins at python.org
Subject: Clear weakrefs in garbage found by the GC (GH-16495) (#16499)
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
https://github.com/python/cpython/commit/92ca515ee1efbdc51678e12d105ad642c9b9=
cc13
commit: 92ca515ee1efbdc51678e12d105ad642c9b9cc13
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.co=
m>
committer: =C5=81ukasz Langa <lukasz at langa.pl>
date: 2019-09-30T19:27:46+02:00
summary:
Clear weakrefs in garbage found by the GC (GH-16495) (#16499)
Fix a bug due to the interaction of weakrefs and the cyclic garbage
collector. We must clear any weakrefs in garbage in order to prevent
their callbacks from executing and causing a crash.
(cherry picked from commit bcda460baf25062ab68622b3f043f52b9db4d21d)
Co-authored-by: Neil Schemenauer <nas-github at arctrix.com>
files:
A Misc/NEWS.d/next/Core and Builtins/2019-09-30-09-33-21.bpo-38006.UYlJum.rst
M Modules/gcmodule.c
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-30-09-33-21.bpo-38006=
.UYlJum.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-30-09-33-21.bpo-3800=
6.UYlJum.rst
new file mode 100644
index 000000000000..c2dafae0afab
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-09-30-09-33-21.bpo-38006.UYlJum=
.rst=09
@@ -0,0 +1,3 @@
+Fix a bug due to the interaction of weakrefs and the cyclic garbage
+collector. We must clear any weakrefs in garbage in order to prevent their
+callbacks from executing and causing a crash.
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index b2ee56623cd4..8bdbafef167e 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -678,6 +678,21 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
op =3D FROM_GC(gc);
next =3D GC_NEXT(gc);
=20
+ if (PyWeakref_Check(op)) {
+ /* A weakref inside the unreachable set must be cleared. If we
+ * allow its callback to execute inside delete_garbage(), it
+ * could expose objects that have tp_clear already called on
+ * them. Or, it could resurrect unreachable objects. One way
+ * this can happen is if some container objects do not implement
+ * tp_traverse. Then, wr_object can be outside the unreachable
+ * set but can be deallocated as a result of breaking the
+ * reference cycle. If we don't clear the weakref, the callback
+ * will run and potentially cause a crash. See bpo-38006 for
+ * one example.
+ */
+ _PyWeakref_ClearRef((PyWeakReference *)op);
+ }
+
if (! PyType_SUPPORTS_WEAKREFS(Py_TYPE(op)))
continue;
=20
@@ -733,6 +748,8 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
* is moved to wrcb_to_call in this case.
*/
if (gc_is_collecting(AS_GC(wr))) {
+ /* it should already have been cleared above */
+ assert(wr->wr_object =3D=3D Py_None);
continue;
}
=20
More information about the Python-checkins
mailing list