summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2009-03-13 19:25:20 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2009-03-13 19:25:20 (GMT)
commit652e7076fee59d92d19a0d6e326b9069a2aa09e4 (patch)
tree5287ec21422abfbe642d9ff2138cebac2ac04a00 /Lib
parentae2dbe2543859f9ad0ff0a2e84b33421c8fd5406 (diff)
downloadcpython-652e7076fee59d92d19a0d6e326b9069a2aa09e4.zip
cpython-652e7076fee59d92d19a0d6e326b9069a2aa09e4.tar.gz
cpython-652e7076fee59d92d19a0d6e326b9069a2aa09e4.tar.bz2
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.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_sys.py42
1 files changed, 42 insertions, 0 deletions
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index fad9939..9f0c139 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -2,6 +2,8 @@
import unittest, test.support
import sys, io, os
import struct
+import subprocess
+import textwrap
class SysModuleTest(unittest.TestCase):
@@ -155,6 +157,46 @@ class SysModuleTest(unittest.TestCase):
self.assertEqual(sys.getrecursionlimit(), 10000)
sys.setrecursionlimit(oldlimit)
+ def test_recursionlimit_recovery(self):
+ # NOTE: this test is slightly fragile in that it depends on the current
+ # recursion count when executing the test being low enough so as to
+ # trigger the recursion recovery detection in the _Py_MakeEndRecCheck
+ # macro (see ceval.h).
+ oldlimit = sys.getrecursionlimit()
+ def f():
+ f()
+ try:
+ for i in (50, 1000):
+ # Issue #5392: stack overflow after hitting recursion limit twice
+ sys.setrecursionlimit(i)
+ self.assertRaises(RuntimeError, f)
+ self.assertRaises(RuntimeError, f)
+ finally:
+ sys.setrecursionlimit(oldlimit)
+
+ def test_recursionlimit_fatalerror(self):
+ # A fatal error occurs if a second recursion limit is hit when recovering
+ # from a first one.
+ code = textwrap.dedent("""
+ import sys
+
+ def f():
+ try:
+ f()
+ except RuntimeError:
+ f()
+
+ sys.setrecursionlimit(%d)
+ f()""")
+ for i in (50, 1000):
+ sub = subprocess.Popen([sys.executable, '-c', code % i],
+ stderr=subprocess.PIPE)
+ err = sub.communicate()[1]
+ self.assertTrue(sub.returncode, sub.returncode)
+ self.assertTrue(
+ b"Fatal Python error: Cannot recover from stack overflow" in err,
+ err)
+
def test_getwindowsversion(self):
if hasattr(sys, "getwindowsversion"):
v = sys.getwindowsversion()