Ejemplo n.º 1
0
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(script=self.get_sample_script(),
                                  cmds_after_breakpoint=['py-up', 'py-up'])
        self.assertMultilineMatches(
            bt, r'''^.*
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\)
    baz\(a, b, c\)
$''')

    @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=self.get_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=self.get_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(
            script=self.get_sample_script(),
            cmds_after_breakpoint=['py-up', 'py-up', 'py-down'])
        self.assertMultilineMatches(
            bt, r'''^.*
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\)
    baz\(a, b, c\)
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 10, in baz \(args=\(1, 2, 3\)\)
    id\(42\)
$''')
Ejemplo n.º 2
0
class PyLocalsTests(DebuggerTests):
    @unittest.skipIf(python_is_optimized(),
                     "Python was compiled with optimizations")
    def test_basic_command(self):
        bt = self.get_stack_trace(script=self.get_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=self.get_sample_script(),
            cmds_after_breakpoint=['py-up', 'py-up', 'py-locals'])
        self.assertMultilineMatches(bt, r".*\na = 1\nb = 2\nc = 3\n.*")
Ejemplo n.º 3
0
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(
            script=self.get_sample_script(),
            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(script=self.get_sample_script(),
                                  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=self.get_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=self.get_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.*"
        )
Ejemplo n.º 4
0
class PyBtTests(DebuggerTests):
    @unittest.skipIf(python_is_optimized(),
                     "Python was compiled with optimizations")
    def test_bt(self):
        'Verify that the "py-bt" command works'
        bt = self.get_stack_trace(script=self.get_sample_script(),
                                  cmds_after_breakpoint=['py-bt'])
        self.assertMultilineMatches(
            bt, r'''^.*
Traceback \(most recent call first\):
  <built-in method id of module object .*>
  File ".*gdb_sample.py", line 10, in baz
    id\(42\)
  File ".*gdb_sample.py", line 7, in bar
    baz\(a, b, c\)
  File ".*gdb_sample.py", line 4, in foo
    bar\(a, b, c\)
  File ".*gdb_sample.py", line 12, in <module>
    foo\(1, 2, 3\)
''')

    @unittest.skipIf(python_is_optimized(),
                     "Python was compiled with optimizations")
    def test_bt_full(self):
        'Verify that the "py-bt-full" command works'
        bt = self.get_stack_trace(script=self.get_sample_script(),
                                  cmds_after_breakpoint=['py-bt-full'])
        self.assertMultilineMatches(
            bt, r'''^.*
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\)
    baz\(a, b, c\)
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 4, in foo \(a=1, b=2, c=3\)
    bar\(a, b, c\)
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 12, in <module> \(\)
    foo\(1, 2, 3\)
''')

    @unittest.skipUnless(_thread, "Python was compiled without thread support")
    def test_threads(self):
        'Verify that "py-bt" indicates threads that are waiting for the GIL'
        cmd = '''
from threading import Thread

class TestThread(Thread):
    # These threads would run forever, but we'll interrupt things with the
    # debugger
    def run(self):
        i = 0
        while 1:
             i += 1

t = {}
for i in range(4):
   t[i] = TestThread()
   t[i].start()

# Trigger a breakpoint on the main thread
id(42)

'''
        # Verify with "py-bt":
        gdb_output = self.get_stack_trace(
            cmd, cmds_after_breakpoint=['thread apply all py-bt'])
        self.assertIn('Waiting for the GIL', gdb_output)

        # Verify with "py-bt-full":
        gdb_output = self.get_stack_trace(
            cmd, cmds_after_breakpoint=['thread apply all py-bt-full'])
        self.assertIn('Waiting for the GIL', gdb_output)

    @unittest.skipIf(python_is_optimized(),
                     "Python was compiled with optimizations")
    # Some older versions of gdb will fail with
    #  "Cannot find new threads: generic error"
    # unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround
    @unittest.skipUnless(_thread, "Python was compiled without thread support")
    def test_gc(self):
        'Verify that "py-bt" indicates if a thread is garbage-collecting'
        cmd = ('from gc import collect\n'
               'id(42)\n'
               'def foo():\n'
               '    collect()\n'
               'def bar():\n'
               '    foo()\n'
               'bar()\n')
        # Verify with "py-bt":
        gdb_output = self.get_stack_trace(
            cmd,
            cmds_after_breakpoint=['break update_refs', 'continue', 'py-bt'],
        )
        self.assertIn('Garbage-collecting', gdb_output)

        # Verify with "py-bt-full":
        gdb_output = self.get_stack_trace(
            cmd,
            cmds_after_breakpoint=[
                'break update_refs', 'continue', 'py-bt-full'
            ],
        )
        self.assertIn('Garbage-collecting', gdb_output)

    @unittest.skipIf(python_is_optimized(),
                     "Python was compiled with optimizations")
    # Some older versions of gdb will fail with
    #  "Cannot find new threads: generic error"
    # unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround
    @unittest.skipUnless(_thread, "Python was compiled without thread support")
    def test_pycfunction(self):
        'Verify that "py-bt" displays invocations of PyCFunction instances'
        # Tested function must not be defined with METH_NOARGS or METH_O,
        # otherwise call_function() doesn't call PyCFunction_Call()
        cmd = ('from time import gmtime\n'
               'def foo():\n'
               '    gmtime(1)\n'
               'def bar():\n'
               '    foo()\n'
               'bar()\n')
        # Verify with "py-bt":
        gdb_output = self.get_stack_trace(
            cmd,
            breakpoint='time_gmtime',
            cmds_after_breakpoint=['bt', 'py-bt'],
        )
        self.assertIn('<built-in method gmtime', gdb_output)

        # Verify with "py-bt-full":
        gdb_output = self.get_stack_trace(
            cmd,
            breakpoint='time_gmtime',
            cmds_after_breakpoint=['py-bt-full'],
        )
        self.assertIn('#1 <built-in method gmtime', gdb_output)

    @unittest.skipIf(python_is_optimized(),
                     "Python was compiled with optimizations")
    def test_wrapper_call(self):
        cmd = textwrap.dedent('''
            class MyList(list):
                def __init__(self):
                    super().__init__()   # wrapper_call()

            id("first break point")
            l = MyList()
        ''')
        # Verify with "py-bt":
        gdb_output = self.get_stack_trace(
            cmd,
            cmds_after_breakpoint=['break wrapper_call', 'continue', 'py-bt'])
        self.assertRegex(gdb_output,
                         r"<method-wrapper u?'__init__' of MyList object at ")
Ejemplo n.º 5
0
    pass

foo(3, 4, 5)
id(foo.__code__)''',
            breakpoint='builtin_id',
            cmds_after_breakpoint=[
                'print (PyFrameObject*)(((PyCodeObject*)v)->co_zombieframe)'
            ])
        self.assertTrue(
            re.match(
                r'.*\s+\$1 =\s+Frame 0x-?[0-9a-f]+, for file <string>, line 3, in foo \(\)\s+.*',
                gdb_output, re.DOTALL),
            'Unexpected gdb representation: %r\n%s' % (gdb_output, gdb_output))


@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=self.get_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'
Ejemplo n.º 6
0
 def test_python_is_optimized(self):
     self.assertIsInstance(support.python_is_optimized(), bool)