Merged revisions 70344 via svnmerge from · python/cpython@6bb7c01 · GitHub
Skip to content

Commit 6bb7c01

Browse files
committed
Merged revisions 70344 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r70344 | antoine.pitrou | 2009-03-13 20:25:20 +0100 (ven., 13 mars 2009) | 4 lines Issue #5392: when a very low recursion limit was set, the interpreter would abort with a fatal error after the recursion limit was hit twice. ........
1 parent 7c46534 commit 6bb7c01

3 files changed

Lines changed: 49 additions & 5 deletions

File tree

Include/ceval.h

Lines changed: 4 additions & 5 deletions

Lib/test/test_sys.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import unittest, test.support
33
import sys, io, os
44
import struct
5+
import subprocess
6+
import textwrap
57

68
class SysModuleTest(unittest.TestCase):
79

@@ -155,6 +157,46 @@ def test_recursionlimit(self):
155157
self.assertEqual(sys.getrecursionlimit(), 10000)
156158
sys.setrecursionlimit(oldlimit)
157159

160+
def test_recursionlimit_recovery(self):
161+
# NOTE: this test is slightly fragile in that it depends on the current
162+
# recursion count when executing the test being low enough so as to
163+
# trigger the recursion recovery detection in the _Py_MakeEndRecCheck
164+
# macro (see ceval.h).
165+
oldlimit = sys.getrecursionlimit()
166+
def f():
167+
f()
168+
try:
169+
for i in (50, 1000):
170+
# Issue #5392: stack overflow after hitting recursion limit twice
171+
sys.setrecursionlimit(i)
172+
self.assertRaises(RuntimeError, f)
173+
self.assertRaises(RuntimeError, f)
174+
finally:
175+
sys.setrecursionlimit(oldlimit)
176+
177+
def test_recursionlimit_fatalerror(self):
178+
# A fatal error occurs if a second recursion limit is hit when recovering
179+
# from a first one.
180+
code = textwrap.dedent("""
181+
import sys
182+
183+
def f():
184+
try:
185+
f()
186+
except RuntimeError:
187+
f()
188+
189+
sys.setrecursionlimit(%d)
190+
f()""")
191+
for i in (50, 1000):
192+
sub = subprocess.Popen([sys.executable, '-c', code % i],
193+
stderr=subprocess.PIPE)
194+
err = sub.communicate()[1]
195+
self.assertTrue(sub.returncode, sub.returncode)
196+
self.assertTrue(
197+
b"Fatal Python error: Cannot recover from stack overflow" in err,
198+
err)
199+
158200
def test_getwindowsversion(self):
159201
if hasattr(sys, "getwindowsversion"):
160202
v = sys.getwindowsversion()

Misc/NEWS

Lines changed: 3 additions & 0 deletions

0 commit comments

Comments
 (0)