From: Sergey Miryanov Date: Sat, 25 Jul 2026 03:31:06 +0000 (+0500) Subject: GH-153809: Untrack TaskObj from GC before calling unregister_task (#154563) X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=506242706e43af85f841027b7bd7f022f8acd939;p=thirdparty%2FPython%2Fcpython.git GH-153809: Untrack TaskObj from GC before calling unregister_task (#154563) --- 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 000000000000..d2d2c771a684 --- /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 bc0f7f3901e0..9c29eb8232ed 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);