Issue #11996: libpython (gdb), replace "py-bt" command by "py-bt-full" and add

a smarter "py-bt" command printing a classic Python traceback.
This commit is contained in:
Victor Stinner 2011-05-13 17:40:15 +02:00
parent 23157e5ddc
commit e670c889cc
3 changed files with 61 additions and 2 deletions

View file

@ -611,12 +611,29 @@ $''')
$''') $''')
class PyBtTests(DebuggerTests): class PyBtTests(DebuggerTests):
def test_basic_command(self): def test_bt(self):
'Verify that the "py-bt" command works' 'Verify that the "py-bt" command works'
bt = self.get_stack_trace(script=self.get_sample_script(), bt = self.get_stack_trace(script=self.get_sample_script(),
cmds_after_breakpoint=['py-bt']) cmds_after_breakpoint=['py-bt'])
self.assertMultilineMatches(bt, self.assertMultilineMatches(bt,
r'''^.* r'''^.*
Traceback \(most recent call first\):
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\)
''')
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\) #[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\) 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\) #[0-9]+ Frame 0x[0-9a-f]+, for file .*gdb_sample.py, line 4, in foo \(a=1, b=2, c=3\)

View file

@ -359,6 +359,9 @@ IDLE
Tools/Demos Tools/Demos
----------- -----------
- Issue #11996: libpython (gdb), replace "py-bt" command by "py-bt-full" and
add a smarter "py-bt" command printing a classic Python traceback.
- Issue #11179: Make ccbench work under Python 3.1 and 2.7 again. - Issue #11179: Make ccbench work under Python 3.1 and 2.7 again.
Extension Modules Extension Modules

View file

@ -931,6 +931,15 @@ class PyFrameObjectPtr(PyObjectPtr):
out.write(')') out.write(')')
def print_traceback(self):
if self.is_optimized_out():
sys.stdout.write(' (frame information optimized out)\n')
visited = set()
sys.stdout.write(' File "%s", line %i, in %s\n'
% (self.co_filename.proxyval(visited),
self.current_line_num(),
self.co_name.proxyval(visited)))
class PySetObjectPtr(PyObjectPtr): class PySetObjectPtr(PyObjectPtr):
_typename = 'PySetObject' _typename = 'PySetObject'
@ -1427,6 +1436,17 @@ class Frame(object):
else: else:
sys.stdout.write('#%i\n' % self.get_index()) sys.stdout.write('#%i\n' % self.get_index())
def print_traceback(self):
if self.is_evalframeex():
pyop = self.get_pyop()
if pyop:
pyop.print_traceback()
sys.stdout.write(' %s\n' % pyop.current_line().strip())
else:
sys.stdout.write(' (unable to read python frame information)\n')
else:
sys.stdout.write(' (not a python frame)\n')
class PyList(gdb.Command): class PyList(gdb.Command):
'''List the current Python source code, if any '''List the current Python source code, if any
@ -1551,6 +1571,24 @@ if hasattr(gdb.Frame, 'select'):
PyUp() PyUp()
PyDown() PyDown()
class PyBacktraceFull(gdb.Command):
'Display the current python frame and all the frames within its call stack (if any)'
def __init__(self):
gdb.Command.__init__ (self,
"py-bt-full",
gdb.COMMAND_STACK,
gdb.COMPLETE_NONE)
def invoke(self, args, from_tty):
frame = Frame.get_selected_python_frame()
while frame:
if frame.is_evalframeex():
frame.print_summary()
frame = frame.older()
PyBacktraceFull()
class PyBacktrace(gdb.Command): class PyBacktrace(gdb.Command):
'Display the current python frame and all the frames within its call stack (if any)' 'Display the current python frame and all the frames within its call stack (if any)'
def __init__(self): def __init__(self):
@ -1561,10 +1599,11 @@ class PyBacktrace(gdb.Command):
def invoke(self, args, from_tty): def invoke(self, args, from_tty):
sys.stdout.write('Traceback (most recent call first):\n')
frame = Frame.get_selected_python_frame() frame = Frame.get_selected_python_frame()
while frame: while frame:
if frame.is_evalframeex(): if frame.is_evalframeex():
frame.print_summary() frame.print_traceback()
frame = frame.older() frame = frame.older()
PyBacktrace() PyBacktrace()