]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-44348: BaseException deallocator uses trashcan (GH-28190)
authorVictor Stinner <vstinner@python.org>
Tue, 7 Sep 2021 13:42:11 +0000 (15:42 +0200)
committerGitHub <noreply@github.com>
Tue, 7 Sep 2021 13:42:11 +0000 (15:42 +0200)
The deallocator function of the BaseException type now uses the
trashcan mecanism to prevent stack overflow. For example, when a
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.

Misc/NEWS.d/next/Core and Builtins/2021-09-07-00-21-04.bpo-44348.f8w_Td.rst [new file with mode: 0644]
Objects/exceptions.c

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 (file)
index 0000000..c222a07
--- /dev/null
@@ -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.
index c6a7aa4aeccf04bea54c15b4e2bb3efd9fbdc670..714039ee1abca1b594456621b2db58f189acbec8 100644 (file)
@@ -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