summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2021-09-07-00-21-04.bpo-44348.f8w_Td.rst8
-rw-r--r--Objects/exceptions.c7
2 files changed, 14 insertions, 1 deletions
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-09-07-00-21-04.bpo-44348.f8w_Td.rst b/Misc/NEWS.d/next/Core and Builtins/2021-09-07-00-21-04.bpo-44348.f8w_Td.rst
new file mode 100644
index 0000000..c222a07
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2021-09-07-00-21-04.bpo-44348.f8w_Td.rst
@@ -0,0 +1,8 @@
+The deallocator function of the :exc:`BaseException` type now uses the
+trashcan mecanism to prevent stack overflow. For example, when a
+:exc:`RecursionError` instance is raised, it can be linked to another
+RecursionError through the ``__context__`` attribute or the
+``__traceback__`` attribute, and then a chain of exceptions is created. When
+the chain is destroyed, nested deallocator function calls can crash with a
+stack overflow if the chain is too long compared to the available stack
+memory. Patch by Victor Stinner.
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index c6a7aa4..714039e 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -89,9 +89,14 @@ BaseException_clear(PyBaseExceptionObject *self)
static void
BaseException_dealloc(PyBaseExceptionObject *self)
{
- _PyObject_GC_UNTRACK(self);
+ PyObject_GC_UnTrack(self);
+ // bpo-44348: The trashcan mecanism prevents stack overflow when deleting
+ // long chains of exceptions. For example, exceptions can be chained
+ // through the __context__ attributes or the __traceback__ attribute.
+ Py_TRASHCAN_BEGIN(self, BaseException_dealloc)
BaseException_clear(self);
Py_TYPE(self)->tp_free((PyObject *)self);
+ Py_TRASHCAN_END
}
static int