[Python-checkins] gh-94215: Add reproducer for segfault in frame_setlineno() (GH-94563)
miss-islington
webhook-mailer at python.org
Thu Jul 7 07:17:52 EDT 2022
https://github.com/python/cpython/commit/421c4b025583df9396dbd6b1e0e90d4a8b6d083f
commit: 421c4b025583df9396dbd6b1e0e90d4a8b6d083f
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2022-07-07T04:17:47-07:00
summary:
gh-94215: Add reproducer for segfault in frame_setlineno() (GH-94563)
(cherry picked from commit de5884295ece094931413267973036ae8a0bca05)
Co-authored-by: Christian Heimes <christian at python.org>
files:
M Lib/test/test_pdb.py
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index f0c15e7b9c536..968a32fce47b6 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -1407,6 +1407,74 @@ def test_pdb_issue_gh_91742():
(Pdb) continue
Author: 'pi' Version: '3.14'
"""
+
+def test_pdb_issue_gh_94215():
+ """See GH-94215
+
+ Check that frame_setlineno() does not leak references.
+
+ >>> def test_function():
+ ... def func():
+ ... def inner(v): pass
+ ... inner(
+ ... 42
+ ... )
+ ...
+ ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
+ ... func()
+
+ >>> reset_Breakpoint()
+ >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE
+ ... 'step',
+ ... 'next',
+ ... 'next',
+ ... 'jump 3',
+ ... 'next',
+ ... 'next',
+ ... 'jump 3',
+ ... 'next',
+ ... 'next',
+ ... 'jump 3',
+ ... 'continue'
+ ... ]):
+ ... test_function()
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(9)test_function()
+ -> func()
+ (Pdb) step
+ --Call--
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(2)func()
+ -> def func():
+ (Pdb) next
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(3)func()
+ -> def inner(v): pass
+ (Pdb) next
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(4)func()
+ -> inner(
+ (Pdb) jump 3
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(3)func()
+ -> def inner(v): pass
+ (Pdb) next
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(4)func()
+ -> inner(
+ (Pdb) next
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(5)func()
+ -> 42
+ (Pdb) jump 3
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(3)func()
+ -> def inner(v): pass
+ (Pdb) next
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(4)func()
+ -> inner(
+ (Pdb) next
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(5)func()
+ -> 42
+ (Pdb) jump 3
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(3)func()
+ -> def inner(v): pass
+ (Pdb) continue
+ """
+
+
@support.requires_subprocess()
class PdbTestCase(unittest.TestCase):
def tearDown(self):
@@ -1414,7 +1482,7 @@ def tearDown(self):
@unittest.skipIf(sys.flags.safe_path,
'PYTHONSAFEPATH changes default sys.path')
- def _run_pdb(self, pdb_args, commands):
+ def _run_pdb(self, pdb_args, commands, expected_returncode=0):
self.addCleanup(os_helper.rmtree, '__pycache__')
cmd = [sys.executable, '-m', 'pdb'] + pdb_args
with subprocess.Popen(
@@ -1427,15 +1495,20 @@ def _run_pdb(self, pdb_args, commands):
stdout, stderr = proc.communicate(str.encode(commands))
stdout = stdout and bytes.decode(stdout)
stderr = stderr and bytes.decode(stderr)
+ self.assertEqual(
+ proc.returncode,
+ expected_returncode,
+ f"Unexpected return code\nstdout: {stdout}\nstderr: {stderr}"
+ )
return stdout, stderr
- def run_pdb_script(self, script, commands):
+ def run_pdb_script(self, script, commands, expected_returncode=0):
"""Run 'script' lines with pdb and the pdb 'commands'."""
filename = 'main.py'
with open(filename, 'w') as f:
f.write(textwrap.dedent(script))
self.addCleanup(os_helper.unlink, filename)
- return self._run_pdb([filename], commands)
+ return self._run_pdb([filename], commands, expected_returncode)
def run_pdb_module(self, script, commands):
"""Runs the script code as part of a module"""
@@ -1641,7 +1714,9 @@ def test_issue16180(self):
script = "def f: pass\n"
commands = ''
expected = "SyntaxError:"
- stdout, stderr = self.run_pdb_script(script, commands)
+ stdout, stderr = self.run_pdb_script(
+ script, commands, expected_returncode=1
+ )
self.assertIn(expected, stdout,
'\n\nExpected:\n{}\nGot:\n{}\n'
'Fail to handle a syntax error in the debuggee.'
@@ -1804,7 +1879,9 @@ def test_module_without_a_main(self):
with open(init_file, 'w'):
pass
self.addCleanup(os_helper.rmtree, module_name)
- stdout, stderr = self._run_pdb(['-m', module_name], "")
+ stdout, stderr = self._run_pdb(
+ ['-m', module_name], "", expected_returncode=1
+ )
self.assertIn("ImportError: No module named t_main.__main__",
stdout.splitlines())
@@ -1817,7 +1894,9 @@ def test_package_without_a_main(self):
with open(modpath + '/__init__.py', 'w'):
pass
self.addCleanup(os_helper.rmtree, pkg_name)
- stdout, stderr = self._run_pdb(['-m', modpath.replace('/', '.')], "")
+ stdout, stderr = self._run_pdb(
+ ['-m', modpath.replace('/', '.')], "", expected_returncode=1
+ )
self.assertIn(
"'t_pkg.t_main' is a package and cannot be directly executed",
stdout)
@@ -2006,6 +2085,25 @@ def test_issue42383(self):
expected = '(Pdb) The correct file was executed'
self.assertEqual(stdout.split('\n')[6].rstrip('\r'), expected)
+ @unittest.skip("test crashes, see gh-94215")
+ def test_gh_94215_crash(self):
+ script = """\
+ def func():
+ def inner(v): pass
+ inner(
+ 42
+ )
+ func()
+ """
+ commands = textwrap.dedent("""
+ break func
+ continue
+ next
+ next
+ jump 2
+ """)
+ stdout, stderr = self.run_pdb_script(script, commands)
+ self.assertFalse(stderr)
class ChecklineTests(unittest.TestCase):
def setUp(self):
More information about the Python-checkins
mailing list