From b9147fb6e47277b23e089fb2b0de39f9b363f683 Mon Sep 17 00:00:00 2001 From: Sergey Miryanov Date: Fri, 24 Jul 2026 01:32:05 +0500 Subject: [PATCH 1/4] Untrack TaskObj from GC before calling unregister_task --- Modules/_asynciomodule.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index bc0f7f3901e0eda..32629e6d3b438ed 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -2966,13 +2966,12 @@ TaskObj_dealloc(PyObject *self) if (PyObject_CallFinalizerFromDealloc(self) < 0) { return; // resurrected } + 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); From b2bb7f7491cb6124f3907b115fed65ba989a9edd Mon Sep 17 00:00:00 2001 From: Sergey Miryanov Date: Fri, 24 Jul 2026 13:15:48 +0500 Subject: [PATCH 2/4] Add news entry --- .../2026-07-24-13-15-31.gh-issue-153809.JFA6GT.rst | 2 ++ 1 file changed, 2 insertions(+) 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. From 523212340859fdb063780cd4110f01be7af51611 Mon Sep 17 00:00:00 2001 From: Sergey Miryanov Date: Sat, 25 Jul 2026 02:02:38 +0500 Subject: [PATCH 3/4] Add comment --- Modules/_asynciomodule.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 32629e6d3b438ed..26b0d2bfee1c34c 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -2966,7 +2966,12 @@ 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); From f612b1af821b94bc8eb085bb932a1788227ee5b9 Mon Sep 17 00:00:00 2001 From: Sergey Miryanov Date: Sat, 25 Jul 2026 02:11:19 +0500 Subject: [PATCH 4/4] Make linter happy --- Modules/_asynciomodule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 26b0d2bfee1c34c..9c29eb8232ed3f9 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -2966,9 +2966,9 @@ TaskObj_dealloc(PyObject *self) if (PyObject_CallFinalizerFromDealloc(self) < 0) { return; // resurrected } - // Untrack the object before unregistering the task, since the + // 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 + // thread might call the GC and reach the object while it is // semi-deallocated but still tracked PyObject_GC_UnTrack(self);