From d8f18d8f0c8130afc705cfb51cc398caa769ad12 Mon Sep 17 00:00:00 2001 From: Tomasz Pytel Date: Fri, 7 Feb 2025 07:54:40 -0500 Subject: [PATCH 1/4] gh-129289: fix subclass of asyncio.Task not propagating __del__() causes segfault --- Include/internal/pycore_object.h | 2 +- Lib/test/test_asyncio/test_tasks.py | 13 +++++++++++++ Modules/_asynciomodule.c | 10 ++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 0b1df7e68b8dfa..62f34bd79974ef 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -121,7 +121,7 @@ PyAPI_DATA(Py_ssize_t) _Py_RefTotal; extern void _Py_AddRefTotal(PyThreadState *, Py_ssize_t); extern PyAPI_FUNC(void) _Py_IncRefTotal(PyThreadState *); -extern void _Py_DecRefTotal(PyThreadState *); +extern PyAPI_FUNC(void) _Py_DecRefTotal(PyThreadState *); # define _Py_DEC_REFTOTAL(interp) \ interp->object_state.reftotal-- diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 7a052817766a07..e53cbf0036e265 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -2710,6 +2710,19 @@ def __str__(self): self.assertEqual(sys.getrefcount(obj), initial_refcount) + def test_subclass_fail_to_propagate_del(self): + # gh-129289: Fix subclass of asyncio.Task not propagating __del__() causes segfault. + class BadTask(self.Task): + def __del__(self): + pass + + async def func(): + return + + task = BadTask(func(), loop=self.loop) + + result = self.loop.run_until_complete(task) + def add_subclass_tests(cls): BaseTask = cls.Task diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 656c03a98d73b2..68d8294dbeaada 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -3075,6 +3075,16 @@ TaskObj_dealloc(PyObject *self) // resurrected. return; } + if (task->task_node.next != NULL) { + if (PyErr_WarnEx(PyExc_Warning, "subclasses of asyncio.Task must propagate __del__()", 1) < 0) { + PyErr_Clear(); + } + _PyObject_ResurrectStart(self); + TaskObj_finalize(task); + if (_PyObject_ResurrectEnd(self)) { + return; + } + } PyTypeObject *tp = Py_TYPE(task); PyObject_GC_UnTrack(self); From 347dcf7a7ac62f958fa9936946c18acb1b56185f Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 7 Feb 2025 12:58:23 +0000 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2025-02-07-12-58-23.gh-issue-129289.tHkEC-.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-02-07-12-58-23.gh-issue-129289.tHkEC-.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-07-12-58-23.gh-issue-129289.tHkEC-.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-07-12-58-23.gh-issue-129289.tHkEC-.rst new file mode 100644 index 00000000000000..c1f9977cca0b26 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-07-12-58-23.gh-issue-129289.tHkEC-.rst @@ -0,0 +1 @@ +Fix subclass of :class:`asyncio.Task` not propagating :func:`__del__()` causes segfault. From 0922a32c4f9fa4fae7b9925ae9d56b1f453eccbd Mon Sep 17 00:00:00 2001 From: Tomasz Pytel Date: Fri, 7 Feb 2025 08:05:45 -0500 Subject: [PATCH 3/4] fix news --- .../2025-02-07-12-58-23.gh-issue-129289.tHkEC-.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-07-12-58-23.gh-issue-129289.tHkEC-.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-07-12-58-23.gh-issue-129289.tHkEC-.rst index c1f9977cca0b26..e69839b82bd0d0 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-07-12-58-23.gh-issue-129289.tHkEC-.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-07-12-58-23.gh-issue-129289.tHkEC-.rst @@ -1 +1 @@ -Fix subclass of :class:`asyncio.Task` not propagating :func:`__del__()` causes segfault. +Fix subclass of :class:`asyncio.Task` not propagating :func:`Task.__del__` causes segfault. From 12e33023d222f4286687ae6cfe4dffb00e1b3069 Mon Sep 17 00:00:00 2001 From: Tomasz Pytel Date: Fri, 7 Feb 2025 08:17:52 -0500 Subject: [PATCH 4/4] export _PyObject_ResurrectEndSlow --- Include/internal/pycore_object.h | 2 +- .../2025-02-07-12-58-23.gh-issue-129289.tHkEC-.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 62f34bd79974ef..49ddfd5b43b00c 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -710,7 +710,7 @@ _PyObject_SetMaybeWeakref(PyObject *op) } } -extern int _PyObject_ResurrectEndSlow(PyObject *op); +extern PyAPI_FUNC(int) _PyObject_ResurrectEndSlow(PyObject *op); #endif // Temporarily resurrects an object during deallocation. The refcount is set diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-07-12-58-23.gh-issue-129289.tHkEC-.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-07-12-58-23.gh-issue-129289.tHkEC-.rst index e69839b82bd0d0..c790acfae91917 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-07-12-58-23.gh-issue-129289.tHkEC-.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-07-12-58-23.gh-issue-129289.tHkEC-.rst @@ -1 +1 @@ -Fix subclass of :class:`asyncio.Task` not propagating :func:`Task.__del__` causes segfault. +Fix subclass of :class:`asyncio.Task` not propagating finalizer causes segfault.