Skip to content

Commit

Permalink
bpo-33930: Fix segfault with deep recursion when cleaning method obje…
Browse files Browse the repository at this point in the history
  • Loading branch information
pablogsal committed Aug 10, 2021
1 parent c0ab59f commit bfc2d5a
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 1 deletion.
15 changes: 15 additions & 0 deletions Lib/test/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,21 @@ def g():
self.assertIsInstance(v, RecursionError, type(v))
self.assertIn("maximum recursion depth exceeded", str(v))


@cpython_only
def test_crashcan_recursion(self):
# See bpo-33930

def foo():
o = object()
for x in range(1_000_000):
# Create a big chain of method objects that will trigger
# a deep chain of calls when they need to be destructed.
o = o.__dir__

foo()
support.gc_collect()

@cpython_only
def test_recursion_normalizing_exception(self):
# Issue #22898.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix segmentation fault with deep recursion when cleaning method objects.
Patch by Augusto Goulart and Pablo Galindo.
6 changes: 5 additions & 1 deletion Objects/methodobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,10 @@ PyCMethod_GetClass(PyObject *op)
static void
meth_dealloc(PyCFunctionObject *m)
{
_PyObject_GC_UNTRACK(m);
// The Py_TRASHCAN mechanism requires that we be able to
// call PyObject_GC_UnTrack twice on an object.
PyObject_GC_UnTrack(m);
Py_TRASHCAN_BEGIN(m, meth_dealloc);
if (m->m_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject*) m);
}
Expand All @@ -170,6 +173,7 @@ meth_dealloc(PyCFunctionObject *m)
Py_XDECREF(m->m_self);
Py_XDECREF(m->m_module);
PyObject_GC_Del(m);
Py_TRASHCAN_END;
}

static PyObject *
Expand Down

0 comments on commit bfc2d5a

Please sign in to comment.