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 00000000000000..d2d2c771a68432 --- /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 bc0f7f3901e0ed..9c29eb8232ed3f 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -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);