]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-153809: Untrack TaskObj from GC before calling unregister_task (#154563)
authorSergey Miryanov <sergey.miryanov@gmail.com>
Sat, 25 Jul 2026 03:31:06 +0000 (08:31 +0500)
committerGitHub <noreply@github.com>
Sat, 25 Jul 2026 03:31:06 +0000 (09:01 +0530)
Misc/NEWS.d/next/Core_and_Builtins/2026-07-24-13-15-31.gh-issue-153809.JFA6GT.rst [new file with mode: 0644]
Modules/_asynciomodule.c

diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-24-13-15-31.gh-issue-153809.JFA6GT.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-24-13-15-31.gh-issue-153809.JFA6GT.rst
new file mode 100644 (file)
index 0000000..d2d2c77
--- /dev/null
@@ -0,0 +1,2 @@
+Fix interpreter crash while deallocating objects of :class:`asyncio.Task` on
+free-threaded builds. Contributed by Sergey Miryanov.
index bc0f7f3901e0edae9ae03d4e000c0824d4f7ecd8..9c29eb8232ed3f927be18ad5e17f783bcf52e541 100644 (file)
@@ -2966,13 +2966,17 @@ TaskObj_dealloc(PyObject *self)
     if (PyObject_CallFinalizerFromDealloc(self) < 0) {
         return; // resurrected
     }
+    // Untrack the object before unregistering the task, since the
+    // latter can cause a stop-the-world pause, after which another
+    // thread might call the GC and reach the object while it is
+    // semi-deallocated but still tracked
+    PyObject_GC_UnTrack(self);
+
     // unregister the task after finalization so that
     // if the task gets resurrected, it remains registered
     unregister_task((TaskObj *)self);
 
     PyTypeObject *tp = Py_TYPE(self);
-    PyObject_GC_UnTrack(self);
-
     PyObject_ClearWeakRefs(self);
 
     (void)TaskObj_clear(self);