mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			188 lines
		
	
	
	
		
			7.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			188 lines
		
	
	
	
		
			7.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import re
 | |
| import unittest
 | |
| from test.support import python_is_optimized
 | |
| 
 | |
| from .util import run_gdb, setup_module, DebuggerTests, SAMPLE_SCRIPT
 | |
| 
 | |
| 
 | |
| def setUpModule():
 | |
|     setup_module()
 | |
| 
 | |
| 
 | |
| def gdb_has_frame_select():
 | |
|     # Does this build of gdb have gdb.Frame.select ?
 | |
|     stdout, stderr = run_gdb("--eval-command=python print(dir(gdb.Frame))")
 | |
|     m = re.match(r'.*\[(.*)\].*', stdout)
 | |
|     if not m:
 | |
|         raise unittest.SkipTest(
 | |
|             f"Unable to parse output from gdb.Frame.select test\n"
 | |
|             f"stdout={stdout!r}\n"
 | |
|             f"stderr={stderr!r}\n")
 | |
|     gdb_frame_dir = m.group(1).split(', ')
 | |
|     return "'select'" in gdb_frame_dir
 | |
| 
 | |
| HAS_PYUP_PYDOWN = gdb_has_frame_select()
 | |
| 
 | |
| 
 | |
| @unittest.skipIf(python_is_optimized(),
 | |
|                  "Python was compiled with optimizations")
 | |
| class PyListTests(DebuggerTests):
 | |
|     def assertListing(self, expected, actual):
 | |
|         self.assertEndsWith(actual, expected)
 | |
| 
 | |
|     def test_basic_command(self):
 | |
|         'Verify that the "py-list" command works'
 | |
|         bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
 | |
|                                   cmds_after_breakpoint=['py-list'])
 | |
| 
 | |
|         self.assertListing('   5    \n'
 | |
|                            '   6    def bar(a, b, c):\n'
 | |
|                            '   7        baz(a, b, c)\n'
 | |
|                            '   8    \n'
 | |
|                            '   9    def baz(*args):\n'
 | |
|                            ' >10        id(42)\n'
 | |
|                            '  11    \n'
 | |
|                            '  12    foo(1, 2, 3)\n',
 | |
|                            bt)
 | |
| 
 | |
|     def test_one_abs_arg(self):
 | |
|         'Verify the "py-list" command with one absolute argument'
 | |
|         bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
 | |
|                                   cmds_after_breakpoint=['py-list 9'])
 | |
| 
 | |
|         self.assertListing('   9    def baz(*args):\n'
 | |
|                            ' >10        id(42)\n'
 | |
|                            '  11    \n'
 | |
|                            '  12    foo(1, 2, 3)\n',
 | |
|                            bt)
 | |
| 
 | |
|     def test_two_abs_args(self):
 | |
|         'Verify the "py-list" command with two absolute arguments'
 | |
|         bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
 | |
|                                   cmds_after_breakpoint=['py-list 1,3'])
 | |
| 
 | |
|         self.assertListing('   1    # Sample script for use by test_gdb\n'
 | |
|                            '   2    \n'
 | |
|                            '   3    def foo(a, b, c):\n',
 | |
|                            bt)
 | |
| 
 | |
| SAMPLE_WITH_C_CALL = """
 | |
| 
 | |
| from _testcapi import pyobject_vectorcall
 | |
| 
 | |
| def foo(a, b, c):
 | |
|     bar(a, b, c)
 | |
| 
 | |
| def bar(a, b, c):
 | |
|     pyobject_vectorcall(baz, (a, b, c), None)
 | |
| 
 | |
| def baz(*args):
 | |
|     id(42)
 | |
| 
 | |
| foo(1, 2, 3)
 | |
| 
 | |
| """
 | |
| 
 | |
| 
 | |
| class StackNavigationTests(DebuggerTests):
 | |
|     @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
 | |
|     @unittest.skipIf(python_is_optimized(),
 | |
|                      "Python was compiled with optimizations")
 | |
|     def test_pyup_command(self):
 | |
|         'Verify that the "py-up" command works'
 | |
|         bt = self.get_stack_trace(source=SAMPLE_WITH_C_CALL,
 | |
|                                   cmds_after_breakpoint=['py-up', 'py-up'])
 | |
|         self.assertMultilineMatches(bt,
 | |
|                                     r'''^.*
 | |
| #[0-9]+ Frame 0x-?[0-9a-f]+, for file <string>, line 12, in baz \(args=\(1, 2, 3\)\)
 | |
| #[0-9]+ <built-in method pyobject_vectorcall of module object at remote 0x[0-9a-f]+>
 | |
| $''')
 | |
| 
 | |
|     @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
 | |
|     def test_down_at_bottom(self):
 | |
|         'Verify handling of "py-down" at the bottom of the stack'
 | |
|         bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
 | |
|                                   cmds_after_breakpoint=['py-down'])
 | |
|         self.assertEndsWith(bt,
 | |
|                             'Unable to find a newer python frame\n')
 | |
| 
 | |
|     @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
 | |
|     def test_up_at_top(self):
 | |
|         'Verify handling of "py-up" at the top of the stack'
 | |
|         bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
 | |
|                                   cmds_after_breakpoint=['py-up'] * 5)
 | |
|         self.assertEndsWith(bt,
 | |
|                             'Unable to find an older python frame\n')
 | |
| 
 | |
|     @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
 | |
|     @unittest.skipIf(python_is_optimized(),
 | |
|                      "Python was compiled with optimizations")
 | |
|     def test_up_then_down(self):
 | |
|         'Verify "py-up" followed by "py-down"'
 | |
|         bt = self.get_stack_trace(source=SAMPLE_WITH_C_CALL,
 | |
|                                   cmds_after_breakpoint=['py-up', 'py-up', 'py-down'])
 | |
|         self.assertMultilineMatches(bt,
 | |
|                                     r'''^.*
 | |
| #[0-9]+ Frame 0x-?[0-9a-f]+, for file <string>, line 12, in baz \(args=\(1, 2, 3\)\)
 | |
| #[0-9]+ <built-in method pyobject_vectorcall of module object at remote 0x[0-9a-f]+>
 | |
| #[0-9]+ Frame 0x-?[0-9a-f]+, for file <string>, line 12, in baz \(args=\(1, 2, 3\)\)
 | |
| $''')
 | |
| 
 | |
| class PyPrintTests(DebuggerTests):
 | |
|     @unittest.skipIf(python_is_optimized(),
 | |
|                      "Python was compiled with optimizations")
 | |
|     def test_basic_command(self):
 | |
|         'Verify that the "py-print" command works'
 | |
|         bt = self.get_stack_trace(source=SAMPLE_WITH_C_CALL,
 | |
|                                   cmds_after_breakpoint=['py-up', 'py-print args'])
 | |
|         self.assertMultilineMatches(bt,
 | |
|                                     r".*\nlocal 'args' = \(1, 2, 3\)\n.*")
 | |
| 
 | |
|     @unittest.skipIf(python_is_optimized(),
 | |
|                      "Python was compiled with optimizations")
 | |
|     @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
 | |
|     def test_print_after_up(self):
 | |
|         bt = self.get_stack_trace(source=SAMPLE_WITH_C_CALL,
 | |
|                                   cmds_after_breakpoint=['py-up', 'py-up', 'py-print c', 'py-print b', 'py-print a'])
 | |
|         self.assertMultilineMatches(bt,
 | |
|                                     r".*\nlocal 'c' = 3\nlocal 'b' = 2\nlocal 'a' = 1\n.*")
 | |
| 
 | |
|     @unittest.skipIf(python_is_optimized(),
 | |
|                      "Python was compiled with optimizations")
 | |
|     def test_printing_global(self):
 | |
|         bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
 | |
|                                   cmds_after_breakpoint=['py-up', 'py-print __name__'])
 | |
|         self.assertMultilineMatches(bt,
 | |
|                                     r".*\nglobal '__name__' = '__main__'\n.*")
 | |
| 
 | |
|     @unittest.skipIf(python_is_optimized(),
 | |
|                      "Python was compiled with optimizations")
 | |
|     def test_printing_builtin(self):
 | |
|         bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
 | |
|                                   cmds_after_breakpoint=['py-up', 'py-print len'])
 | |
|         self.assertMultilineMatches(bt,
 | |
|                                     r".*\nbuiltin 'len' = <built-in method len of module object at remote 0x-?[0-9a-f]+>\n.*")
 | |
| 
 | |
| class PyLocalsTests(DebuggerTests):
 | |
|     @unittest.skipIf(python_is_optimized(),
 | |
|                      "Python was compiled with optimizations")
 | |
|     def test_basic_command(self):
 | |
|         bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
 | |
|                                   cmds_after_breakpoint=['py-up', 'py-locals'])
 | |
|         self.assertMultilineMatches(bt,
 | |
|                                     r".*\nargs = \(1, 2, 3\)\n.*")
 | |
| 
 | |
|     @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
 | |
|     @unittest.skipIf(python_is_optimized(),
 | |
|                      "Python was compiled with optimizations")
 | |
|     def test_locals_after_up(self):
 | |
|         bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
 | |
|                                   cmds_after_breakpoint=['py-up', 'py-up', 'py-locals'])
 | |
|         self.assertMultilineMatches(bt,
 | |
|                                     r'''^.*
 | |
| Locals for foo
 | |
| a = 1
 | |
| b = 2
 | |
| c = 3
 | |
| Locals for <module>
 | |
| .*$''')
 | 
