cpython: b0efa88c4cf4 (original) (raw)
--- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -679,7 +679,7 @@ class StackNavigationTests(DebuggerTests 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'])[](#l1.7)
cmds_after_breakpoint=['py-up', 'py-up'])[](#l1.8) self.assertMultilineMatches(bt,[](#l1.9) r'''^.*[](#l1.10)
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar (a=1, b=2, c=3) @@ -698,7 +698,7 @@ class StackNavigationTests(DebuggerTests 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'] * 4)[](#l1.16)
cmds_after_breakpoint=['py-up'] * 5)[](#l1.17) self.assertEndsWith(bt,[](#l1.18) 'Unable to find an older python frame\n')[](#l1.19)
@@ -708,7 +708,7 @@ class StackNavigationTests(DebuggerTests 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-down'])[](#l1.25)
cmds_after_breakpoint=['py-up', 'py-up', 'py-down'])[](#l1.26) self.assertMultilineMatches(bt,[](#l1.27) r'''^.*[](#l1.28)
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .gdb_sample.py, line 7, in bar (a=1, b=2, c=3) @@ -727,6 +727,7 @@ class PyBtTests(DebuggerTests): 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 @@ -815,7 +816,6 @@ id(42) ) self.assertIn('Garbage-collecting', gdb_output)
- @unittest.skip("FIXME: builtin method is not shown in py-bt and py-bt-full")
@unittest.skipIf(python_is_optimized(),
"Python was compiled with optimizations")
Some older versions of gdb will fail with
@@ -854,7 +854,7 @@ class PyPrintTests(DebuggerTests): 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-print args'])[](#l1.50)
cmds_after_breakpoint=['py-up', 'py-print args'])[](#l1.51) self.assertMultilineMatches(bt,[](#l1.52) r".*\nlocal 'args' = \(1, 2, 3\)\n.*")[](#l1.53)
@@ -863,7 +863,7 @@ class PyPrintTests(DebuggerTests): @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-print c', 'py-print b', 'py-print a'])[](#l1.59)
cmds_after_breakpoint=['py-up', 'py-up', 'py-print c', 'py-print b', 'py-print a'])[](#l1.60) self.assertMultilineMatches(bt,[](#l1.61) r".*\nlocal 'c' = 3\nlocal 'b' = 2\nlocal 'a' = 1\n.*")[](#l1.62)
@@ -871,7 +871,7 @@ class PyPrintTests(DebuggerTests): "Python was compiled with optimizations") def test_printing_global(self): bt = self.get_stack_trace(script=self.get_sample_script(),
cmds_after_breakpoint=['py-print __name__'])[](#l1.68)
cmds_after_breakpoint=['py-up', 'py-print __name__'])[](#l1.69) self.assertMultilineMatches(bt,[](#l1.70) r".*\nglobal '__name__' = '__main__'\n.*")[](#l1.71)
@@ -879,7 +879,7 @@ class PyPrintTests(DebuggerTests): "Python was compiled with optimizations") def test_printing_builtin(self): bt = self.get_stack_trace(script=self.get_sample_script(),
cmds_after_breakpoint=['py-print len'])[](#l1.77)
cmds_after_breakpoint=['py-up', 'py-print len'])[](#l1.78) self.assertMultilineMatches(bt,[](#l1.79) r".*\nbuiltin 'len' = <built-in method len of module object at remote 0x-?[0-9a-f]+>\n.*")[](#l1.80)
@@ -888,7 +888,7 @@ class PyLocalsTests(DebuggerTests): "Python was compiled with optimizations") def test_basic_command(self): bt = self.get_stack_trace(script=self.get_sample_script(),
cmds_after_breakpoint=['py-locals'])[](#l1.86)
cmds_after_breakpoint=['py-up', 'py-locals'])[](#l1.87) self.assertMultilineMatches(bt,[](#l1.88) r".*\nargs = \(1, 2, 3\)\n.*")[](#l1.89)
@@ -897,7 +897,7 @@ class PyLocalsTests(DebuggerTests): "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-locals'])[](#l1.95)
cmds_after_breakpoint=['py-up', 'py-up', 'py-locals'])[](#l1.96) self.assertMultilineMatches(bt,[](#l1.97) r".*\na = 1\nb = 2\nc = 3\n.*")[](#l1.98)
--- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1492,23 +1492,38 @@ class Frame(object): ''' if self.is_waiting_for_gil(): return 'Waiting for the GIL'
elif self.is_gc_collect():[](#l2.7)
if self.is_gc_collect():[](#l2.9) return 'Garbage-collecting'[](#l2.10)
else:[](#l2.11)
# Detect invocations of PyCFunction instances:[](#l2.12)
older = self.older()[](#l2.13)
if older and older._gdbframe.name() == 'PyCFunction_Call':[](#l2.14)
# Within that frame:[](#l2.15)
# "func" is the local containing the PyObject* of the[](#l2.16)
# PyCFunctionObject instance[](#l2.17)
# "f" is the same value, but cast to (PyCFunctionObject*)[](#l2.18)
# "self" is the (PyObject*) of the 'self'[](#l2.19)
try:[](#l2.20)
# Use the prettyprinter for the func:[](#l2.21)
func = older._gdbframe.read_var('func')[](#l2.22)
return str(func)[](#l2.23)
except RuntimeError:[](#l2.24)
return 'PyCFunction invocation (unable to read "func")'[](#l2.25)
# Detect invocations of PyCFunction instances:[](#l2.27)
older = self.older()[](#l2.28)
if not older:[](#l2.29)
return False[](#l2.30)
caller = older._gdbframe.name()[](#l2.32)
if not caller:[](#l2.33)
return False[](#l2.34)
if caller == 'PyCFunction_Call':[](#l2.36)
# Within that frame:[](#l2.37)
# "func" is the local containing the PyObject* of the[](#l2.38)
# PyCFunctionObject instance[](#l2.39)
# "f" is the same value, but cast to (PyCFunctionObject*)[](#l2.40)
# "self" is the (PyObject*) of the 'self'[](#l2.41)
try:[](#l2.42)
# Use the prettyprinter for the func:[](#l2.43)
func = older._gdbframe.read_var('func')[](#l2.44)
return str(func)[](#l2.45)
except RuntimeError:[](#l2.46)
return 'PyCFunction invocation (unable to read "func")'[](#l2.47)
elif caller == '_PyCFunction_FastCallDict':[](#l2.49)
try:[](#l2.50)
func = older._gdbframe.read_var('func_obj')[](#l2.51)
return str(func)[](#l2.52)
except RuntimeError:[](#l2.53)
return 'PyCFunction invocation (unable to read "func_obj")'[](#l2.54)