From 5fc7431a3e0dff235631293620dae1c09a253cd9 Mon Sep 17 00:00:00 2001 From: Sergey Miryanov Date: Sat, 25 Jul 2026 08:31:06 +0500 Subject: [PATCH] GH-153809: Untrack TaskObj from GC before calling unregister_task (GH-154563) (cherry picked from commit 506242706e43af85f841027b7bd7f022f8acd939) Co-authored-by: Sergey Miryanov --- .../2026-07-24-13-15-31.gh-issue-153809.JFA6GT.rst | 2 ++ Modules/_asynciomodule.c | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-07-24-13-15-31.gh-issue-153809.JFA6GT.rst 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 index 000000000000000..d2d2c771a684325 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-24-13-15-31.gh-issue-153809.JFA6GT.rst @@ -0,0 +1,2 @@ +Fix interpreter crash while deallocating objects of :class:`asyncio.Task` on +free-threaded builds. Contributed by Sergey Miryanov. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 57c8d4a41a3a0df..a314723a46d94e8 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -2974,13 +2974,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);