(root)/
Python-3.11.7/
Lib/
test/
test_gdb/
test_misc.py
       1  import re
       2  import unittest
       3  from test.support import python_is_optimized
       4  
       5  from .util import run_gdb, setup_module, DebuggerTests, SAMPLE_SCRIPT
       6  
       7  
       8  def setUpModule():
       9      setup_module()
      10  
      11  
      12  def gdb_has_frame_select():
      13      # Does this build of gdb have gdb.Frame.select ?
      14      stdout, stderr = run_gdb("--eval-command=python print(dir(gdb.Frame))")
      15      m = re.match(r'.*\[(.*)\].*', stdout)
      16      if not m:
      17          raise unittest.SkipTest(
      18              f"Unable to parse output from gdb.Frame.select test\n"
      19              f"stdout={stdout!r}\n"
      20              f"stderr={stderr!r}\n")
      21      gdb_frame_dir = m.group(1).split(', ')
      22      return "'select'" in gdb_frame_dir
      23  
      24  HAS_PYUP_PYDOWN = gdb_has_frame_select()
      25  
      26  
      27  @unittest.skipIf(python_is_optimized(),
      28                   "Python was compiled with optimizations")
      29  class ESC[4;38;5;81mPyListTests(ESC[4;38;5;149mDebuggerTests):
      30      def assertListing(self, expected, actual):
      31          self.assertEndsWith(actual, expected)
      32  
      33      def test_basic_command(self):
      34          'Verify that the "py-list" command works'
      35          bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
      36                                    cmds_after_breakpoint=['py-list'])
      37  
      38          self.assertListing('   5    \n'
      39                             '   6    def bar(a, b, c):\n'
      40                             '   7        baz(a, b, c)\n'
      41                             '   8    \n'
      42                             '   9    def baz(*args):\n'
      43                             ' >10        id(42)\n'
      44                             '  11    \n'
      45                             '  12    foo(1, 2, 3)\n',
      46                             bt)
      47  
      48      def test_one_abs_arg(self):
      49          'Verify the "py-list" command with one absolute argument'
      50          bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
      51                                    cmds_after_breakpoint=['py-list 9'])
      52  
      53          self.assertListing('   9    def baz(*args):\n'
      54                             ' >10        id(42)\n'
      55                             '  11    \n'
      56                             '  12    foo(1, 2, 3)\n',
      57                             bt)
      58  
      59      def test_two_abs_args(self):
      60          'Verify the "py-list" command with two absolute arguments'
      61          bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
      62                                    cmds_after_breakpoint=['py-list 1,3'])
      63  
      64          self.assertListing('   1    # Sample script for use by test_gdb\n'
      65                             '   2    \n'
      66                             '   3    def foo(a, b, c):\n',
      67                             bt)
      68  
      69  SAMPLE_WITH_C_CALL = """
      70  
      71  from _testcapi import pyobject_vectorcall
      72  
      73  def foo(a, b, c):
      74      bar(a, b, c)
      75  
      76  def bar(a, b, c):
      77      pyobject_vectorcall(baz, (a, b, c), None)
      78  
      79  def baz(*args):
      80      id(42)
      81  
      82  foo(1, 2, 3)
      83  
      84  """
      85  
      86  
      87  class ESC[4;38;5;81mStackNavigationTests(ESC[4;38;5;149mDebuggerTests):
      88      @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
      89      @unittest.skipIf(python_is_optimized(),
      90                       "Python was compiled with optimizations")
      91      def test_pyup_command(self):
      92          'Verify that the "py-up" command works'
      93          bt = self.get_stack_trace(source=SAMPLE_WITH_C_CALL,
      94                                    cmds_after_breakpoint=['py-up', 'py-up'])
      95          self.assertMultilineMatches(bt,
      96                                      r'''^.*
      97  #[0-9]+ Frame 0x-?[0-9a-f]+, for file <string>, line 12, in baz \(args=\(1, 2, 3\)\)
      98  #[0-9]+ <built-in method pyobject_vectorcall of module object at remote 0x[0-9a-f]+>
      99  $''')
     100  
     101      @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
     102      def test_down_at_bottom(self):
     103          'Verify handling of "py-down" at the bottom of the stack'
     104          bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
     105                                    cmds_after_breakpoint=['py-down'])
     106          self.assertEndsWith(bt,
     107                              'Unable to find a newer python frame\n')
     108  
     109      @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
     110      def test_up_at_top(self):
     111          'Verify handling of "py-up" at the top of the stack'
     112          bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
     113                                    cmds_after_breakpoint=['py-up'] * 5)
     114          self.assertEndsWith(bt,
     115                              'Unable to find an older python frame\n')
     116  
     117      @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
     118      @unittest.skipIf(python_is_optimized(),
     119                       "Python was compiled with optimizations")
     120      def test_up_then_down(self):
     121          'Verify "py-up" followed by "py-down"'
     122          bt = self.get_stack_trace(source=SAMPLE_WITH_C_CALL,
     123                                    cmds_after_breakpoint=['py-up', 'py-up', 'py-down'])
     124          self.assertMultilineMatches(bt,
     125                                      r'''^.*
     126  #[0-9]+ Frame 0x-?[0-9a-f]+, for file <string>, line 12, in baz \(args=\(1, 2, 3\)\)
     127  #[0-9]+ <built-in method pyobject_vectorcall of module object at remote 0x[0-9a-f]+>
     128  #[0-9]+ Frame 0x-?[0-9a-f]+, for file <string>, line 12, in baz \(args=\(1, 2, 3\)\)
     129  $''')
     130  
     131  class ESC[4;38;5;81mPyPrintTests(ESC[4;38;5;149mDebuggerTests):
     132      @unittest.skipIf(python_is_optimized(),
     133                       "Python was compiled with optimizations")
     134      def test_basic_command(self):
     135          'Verify that the "py-print" command works'
     136          bt = self.get_stack_trace(source=SAMPLE_WITH_C_CALL,
     137                                    cmds_after_breakpoint=['py-up', 'py-print args'])
     138          self.assertMultilineMatches(bt,
     139                                      r".*\nlocal 'args' = \(1, 2, 3\)\n.*")
     140  
     141      @unittest.skipIf(python_is_optimized(),
     142                       "Python was compiled with optimizations")
     143      @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
     144      def test_print_after_up(self):
     145          bt = self.get_stack_trace(source=SAMPLE_WITH_C_CALL,
     146                                    cmds_after_breakpoint=['py-up', 'py-up', 'py-print c', 'py-print b', 'py-print a'])
     147          self.assertMultilineMatches(bt,
     148                                      r".*\nlocal 'c' = 3\nlocal 'b' = 2\nlocal 'a' = 1\n.*")
     149  
     150      @unittest.skipIf(python_is_optimized(),
     151                       "Python was compiled with optimizations")
     152      def test_printing_global(self):
     153          bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
     154                                    cmds_after_breakpoint=['py-up', 'py-print __name__'])
     155          self.assertMultilineMatches(bt,
     156                                      r".*\nglobal '__name__' = '__main__'\n.*")
     157  
     158      @unittest.skipIf(python_is_optimized(),
     159                       "Python was compiled with optimizations")
     160      def test_printing_builtin(self):
     161          bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
     162                                    cmds_after_breakpoint=['py-up', 'py-print len'])
     163          self.assertMultilineMatches(bt,
     164                                      r".*\nbuiltin 'len' = <built-in method len of module object at remote 0x-?[0-9a-f]+>\n.*")
     165  
     166  class ESC[4;38;5;81mPyLocalsTests(ESC[4;38;5;149mDebuggerTests):
     167      @unittest.skipIf(python_is_optimized(),
     168                       "Python was compiled with optimizations")
     169      def test_basic_command(self):
     170          bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
     171                                    cmds_after_breakpoint=['py-up', 'py-locals'])
     172          self.assertMultilineMatches(bt,
     173                                      r".*\nargs = \(1, 2, 3\)\n.*")
     174  
     175      @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
     176      @unittest.skipIf(python_is_optimized(),
     177                       "Python was compiled with optimizations")
     178      def test_locals_after_up(self):
     179          bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
     180                                    cmds_after_breakpoint=['py-up', 'py-up', 'py-locals'])
     181          self.assertMultilineMatches(bt,
     182                                      r'''^.*
     183  Locals for foo
     184  a = 1
     185  b = 2
     186  c = 3
     187  Locals for <module>
     188  .*$''')