forked from qt-creator/qt-creator
Debugger: Remove unused code from pdbbridge.py
Starting from unused command line commands like 'up' and 'down' up to the (Pdb) prompt handling. Change-Id: I93ab5025a52b259e3f9d80f3251e88bdb18a3467 Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
@@ -182,15 +182,8 @@ class _rstr(str):
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
class Dumper:
|
class Dumper:
|
||||||
|
|
||||||
prompt = '(Cmd) '
|
|
||||||
identchars = string.ascii_letters + string.digits + '_'
|
identchars = string.ascii_letters + string.digits + '_'
|
||||||
lastcmd = ''
|
lastcmd = ''
|
||||||
doc_leader = ""
|
|
||||||
doc_header = "Documented commands (type help <topic>):"
|
|
||||||
misc_header = "Miscellaneous help topics:"
|
|
||||||
undoc_header = "Undocumented commands:"
|
|
||||||
nohelp = "*** No help on %s"
|
|
||||||
use_rawinput = 1
|
use_rawinput = 1
|
||||||
|
|
||||||
def __init__(self, stdin=None, stdout=None):
|
def __init__(self, stdin=None, stdout=None):
|
||||||
@@ -213,9 +206,7 @@ class Dumper:
|
|||||||
|
|
||||||
if stdout:
|
if stdout:
|
||||||
self.use_rawinput = 0
|
self.use_rawinput = 0
|
||||||
self.prompt = '(Pdb) '
|
|
||||||
self.aliases = {}
|
self.aliases = {}
|
||||||
self.displaying = {}
|
|
||||||
self.mainpyfile = ''
|
self.mainpyfile = ''
|
||||||
self._wait_for_mainpyfile = False
|
self._wait_for_mainpyfile = False
|
||||||
self.tb_lineno = {}
|
self.tb_lineno = {}
|
||||||
@@ -230,12 +221,6 @@ class Dumper:
|
|||||||
self.nosigint = nosigint
|
self.nosigint = nosigint
|
||||||
|
|
||||||
self.commands = {} # associates a command list to breakpoint numbers
|
self.commands = {} # associates a command list to breakpoint numbers
|
||||||
self.commands_doprompt = {} # for each bp num, tells if the prompt
|
|
||||||
# must be disp. after execing the cmd list
|
|
||||||
self.commands_silent = {} # for each bp num, tells if the stack trace
|
|
||||||
# must be disp. after execing the cmd list
|
|
||||||
self.commands_bnum = None # The breakpoint number for which we are
|
|
||||||
# defining a list
|
|
||||||
|
|
||||||
def canonic(self, filename):
|
def canonic(self, filename):
|
||||||
if filename == "<" + filename[1:-1] + ">":
|
if filename == "<" + filename[1:-1] + ">":
|
||||||
@@ -260,7 +245,7 @@ class Dumper:
|
|||||||
if event == 'line':
|
if event == 'line':
|
||||||
return self.dispatch_line(frame)
|
return self.dispatch_line(frame)
|
||||||
if event == 'call':
|
if event == 'call':
|
||||||
return self.dispatch_call(frame, arg)
|
return self.dispatch_call(frame)
|
||||||
if event == 'return':
|
if event == 'return':
|
||||||
return self.dispatch_return(frame, arg)
|
return self.dispatch_return(frame, arg)
|
||||||
if event == 'exception':
|
if event == 'exception':
|
||||||
@@ -280,8 +265,7 @@ class Dumper:
|
|||||||
if self.quitting: raise QuitException
|
if self.quitting: raise QuitException
|
||||||
return self.trace_dispatch
|
return self.trace_dispatch
|
||||||
|
|
||||||
def dispatch_call(self, frame, arg):
|
def dispatch_call(self, frame):
|
||||||
# XXX 'arg' is no longer used
|
|
||||||
if self.botframe is None:
|
if self.botframe is None:
|
||||||
# First call of dispatch since reset()
|
# First call of dispatch since reset()
|
||||||
self.botframe = frame.f_back # (CT) Note that this may also be None!
|
self.botframe = frame.f_back # (CT) Note that this may also be None!
|
||||||
@@ -292,7 +276,7 @@ class Dumper:
|
|||||||
# Ignore call events in generator except when stepping.
|
# Ignore call events in generator except when stepping.
|
||||||
if self.stopframe and frame.f_code.co_flags & inspect.CO_GENERATOR:
|
if self.stopframe and frame.f_code.co_flags & inspect.CO_GENERATOR:
|
||||||
return self.trace_dispatch
|
return self.trace_dispatch
|
||||||
self.user_call(frame, arg)
|
self.user_call(frame)
|
||||||
if self.quitting: raise QuitException
|
if self.quitting: raise QuitException
|
||||||
return self.trace_dispatch
|
return self.trace_dispatch
|
||||||
|
|
||||||
@@ -393,14 +377,6 @@ class Dumper:
|
|||||||
# Derived classes and clients can call the following methods
|
# Derived classes and clients can call the following methods
|
||||||
# to affect the stepping state.
|
# to affect the stepping state.
|
||||||
|
|
||||||
def set_until(self, frame, lineno=None):
|
|
||||||
"""Stop when the line with the line no greater than the current one is
|
|
||||||
reached or when returning from current frame"""
|
|
||||||
# the name "until" is borrowed from gdb
|
|
||||||
if lineno is None:
|
|
||||||
lineno = frame.f_lineno + 1
|
|
||||||
self._set_stopinfo(frame, frame, lineno)
|
|
||||||
|
|
||||||
def set_step(self):
|
def set_step(self):
|
||||||
"""Stop after one line of code."""
|
"""Stop after one line of code."""
|
||||||
# Issue #13183: pdb skips frames after hitting a breakpoint and running
|
# Issue #13183: pdb skips frames after hitting a breakpoint and running
|
||||||
@@ -413,17 +389,6 @@ class Dumper:
|
|||||||
caller_frame.f_trace = self.trace_dispatch
|
caller_frame.f_trace = self.trace_dispatch
|
||||||
self._set_stopinfo(None, None)
|
self._set_stopinfo(None, None)
|
||||||
|
|
||||||
def set_next(self, frame):
|
|
||||||
"""Stop on the next line in or below the given frame."""
|
|
||||||
self._set_stopinfo(frame, None)
|
|
||||||
|
|
||||||
def set_return(self, frame):
|
|
||||||
"""Stop when returning from the given frame."""
|
|
||||||
if frame.f_code.co_flags & inspect.CO_GENERATOR:
|
|
||||||
self._set_stopinfo(frame, None, -1)
|
|
||||||
else:
|
|
||||||
self._set_stopinfo(frame.f_back, frame)
|
|
||||||
|
|
||||||
def set_trace(self, frame=None):
|
def set_trace(self, frame=None):
|
||||||
"""Start debugging from `frame`.
|
"""Start debugging from `frame`.
|
||||||
|
|
||||||
@@ -576,33 +541,6 @@ class Dumper:
|
|||||||
i = max(0, len(stack) - 1)
|
i = max(0, len(stack) - 1)
|
||||||
return stack, i
|
return stack, i
|
||||||
|
|
||||||
def format_stack_entry(self, frame_lineno, lprefix=': '):
|
|
||||||
import linecache
|
|
||||||
#import reprlib
|
|
||||||
frame, lineno = frame_lineno
|
|
||||||
filename = self.canonic(frame.f_code.co_filename)
|
|
||||||
s = '%s(%r)' % (filename, lineno)
|
|
||||||
if frame.f_code.co_name:
|
|
||||||
s += frame.f_code.co_name
|
|
||||||
else:
|
|
||||||
s += "<lambda>"
|
|
||||||
if '__args__' in frame.f_locals:
|
|
||||||
args = frame.f_locals['__args__']
|
|
||||||
else:
|
|
||||||
args = None
|
|
||||||
#if args:
|
|
||||||
# s += reprlib.repr(args)
|
|
||||||
#else:
|
|
||||||
s += '(...)'
|
|
||||||
#if '__return__' in frame.f_locals:
|
|
||||||
# rv = frame.f_locals['__return__']
|
|
||||||
# s += '->'
|
|
||||||
# s += reprlib.repr(rv)
|
|
||||||
line = linecache.getline(filename, lineno, frame.f_globals)
|
|
||||||
if line:
|
|
||||||
s += lprefix + line.strip()
|
|
||||||
return s
|
|
||||||
|
|
||||||
# The following methods can be called by clients to use
|
# The following methods can be called by clients to use
|
||||||
# a debugger to debug a statement or an expression.
|
# a debugger to debug a statement or an expression.
|
||||||
# Both can be given as a string, or a code object.
|
# Both can be given as a string, or a code object.
|
||||||
@@ -641,12 +579,8 @@ class Dumper:
|
|||||||
self.quitting = True
|
self.quitting = True
|
||||||
sys.settrace(None)
|
sys.settrace(None)
|
||||||
|
|
||||||
def runctx(self, cmd, globals, locals):
|
|
||||||
# B/W compatibility
|
|
||||||
self.run(cmd, globals, locals)
|
|
||||||
|
|
||||||
# This method is more useful to debug a single function call.
|
# This method is more useful to debug a single function call.
|
||||||
|
|
||||||
def runcall(self, func, *args, **kwds):
|
def runcall(self, func, *args, **kwds):
|
||||||
self.reset()
|
self.reset()
|
||||||
sys.settrace(self.trace_dispatch)
|
sys.settrace(self.trace_dispatch)
|
||||||
@@ -662,25 +596,10 @@ class Dumper:
|
|||||||
|
|
||||||
|
|
||||||
def cmdloop(self):
|
def cmdloop(self):
|
||||||
"""Repeatedly issue a prompt, accept input, parse an initial prefix
|
"""Repeatedly accept input, parse an initial prefix
|
||||||
off the received input, and dispatch to action methods, passing them
|
off the received input, and dispatch to action methods, passing them
|
||||||
the remainder of the line as argument.
|
the remainder of the line as argument.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Handle display expressions
|
|
||||||
displaying = self.displaying.get(self.curframe)
|
|
||||||
if displaying:
|
|
||||||
for expr, oldvalue in displaying.items():
|
|
||||||
newvalue = self._getval_except(expr)
|
|
||||||
# check for identity first; this prevents custom __eq__ to
|
|
||||||
# be called at every loop, and also prevents instances whose
|
|
||||||
# fields are changed to be displayed
|
|
||||||
if newvalue is not oldvalue and newvalue != oldvalue:
|
|
||||||
displaying[expr] = newvalue
|
|
||||||
self.message('display %s: %r [old: %r]' %
|
|
||||||
(expr, newvalue, oldvalue))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
stop = None
|
stop = None
|
||||||
while not stop:
|
while not stop:
|
||||||
@@ -690,13 +609,13 @@ class Dumper:
|
|||||||
if self.use_rawinput:
|
if self.use_rawinput:
|
||||||
try:
|
try:
|
||||||
if sys.version_info[0] == 2:
|
if sys.version_info[0] == 2:
|
||||||
line = raw_input(self.prompt)
|
line = raw_input('')
|
||||||
else:
|
else:
|
||||||
line = input(self.prompt)
|
line = input('')
|
||||||
except EOFError:
|
except EOFError:
|
||||||
line = 'EOF'
|
line = 'EOF'
|
||||||
else:
|
else:
|
||||||
self.stdout.write(self.prompt)
|
self.stdout.write('')
|
||||||
self.stdout.flush()
|
self.stdout.flush()
|
||||||
line = self.stdin.readline()
|
line = self.stdin.readline()
|
||||||
if not len(line):
|
if not len(line):
|
||||||
@@ -704,24 +623,10 @@ class Dumper:
|
|||||||
else:
|
else:
|
||||||
line = line.rstrip('\r\n')
|
line = line.rstrip('\r\n')
|
||||||
print("LINE: %s" % line)
|
print("LINE: %s" % line)
|
||||||
#line = self.precmd(line)
|
|
||||||
stop = self.onecmd(line)
|
stop = self.onecmd(line)
|
||||||
#stop = self.postcmd(stop, line)
|
|
||||||
finally:
|
finally:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def precmd(self, line):
|
|
||||||
"""Hook method executed just before the command line is
|
|
||||||
interpreted, but after the input prompt is generated and issued.
|
|
||||||
|
|
||||||
"""
|
|
||||||
return line
|
|
||||||
|
|
||||||
def postcmd(self, stop, line):
|
|
||||||
"""Hook method executed just after a command dispatch is finished."""
|
|
||||||
return stop
|
|
||||||
|
|
||||||
def parseline(self, line):
|
def parseline(self, line):
|
||||||
"""Parse the line into a command name and a string containing
|
"""Parse the line into a command name and a string containing
|
||||||
the arguments. Returns a tuple containing (command, args, line).
|
the arguments. Returns a tuple containing (command, args, line).
|
||||||
@@ -746,11 +651,8 @@ class Dumper:
|
|||||||
"""Interpret the argument as though it had been typed in response
|
"""Interpret the argument as though it had been typed in response
|
||||||
to the prompt.
|
to the prompt.
|
||||||
|
|
||||||
This may be overridden, but should not normally need to be;
|
|
||||||
see the precmd() and postcmd() methods for useful execution hooks.
|
|
||||||
The return value is a flag indicating whether interpretation of
|
The return value is a flag indicating whether interpretation of
|
||||||
commands by the interpreter should stop.
|
commands by the interpreter should stop.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
line = str(line)
|
line = str(line)
|
||||||
print("LINE 0: %s" % line)
|
print("LINE 0: %s" % line)
|
||||||
@@ -856,7 +758,7 @@ class Dumper:
|
|||||||
# cache it here to ensure that modifications are not overwritten.
|
# cache it here to ensure that modifications are not overwritten.
|
||||||
self.curframe_locals = self.curframe.f_locals
|
self.curframe_locals = self.curframe.f_locals
|
||||||
|
|
||||||
def user_call(self, frame, argument_list):
|
def user_call(self, frame):
|
||||||
"""This method is called when there is the remote possibility
|
"""This method is called when there is the remote possibility
|
||||||
that we ever need to stop in this function."""
|
that we ever need to stop in this function."""
|
||||||
if self._wait_for_mainpyfile:
|
if self._wait_for_mainpyfile:
|
||||||
@@ -881,9 +783,8 @@ class Dumper:
|
|||||||
|
|
||||||
Returns True if the normal interaction function must be called,
|
Returns True if the normal interaction function must be called,
|
||||||
False otherwise."""
|
False otherwise."""
|
||||||
# self.currentbp is set in bdb in Bdb.break_here if a breakpoint was hit
|
# self.currentbp is set in break_here if a breakpoint was hit
|
||||||
if getattr(self, "currentbp", False) and \
|
if getattr(self, "currentbp", False) and self.currentbp in self.commands:
|
||||||
self.currentbp in self.commands:
|
|
||||||
currentbp = self.currentbp
|
currentbp = self.currentbp
|
||||||
self.currentbp = 0
|
self.currentbp = 0
|
||||||
lastcmd_back = self.lastcmd
|
lastcmd_back = self.lastcmd
|
||||||
@@ -891,10 +792,6 @@ class Dumper:
|
|||||||
for line in self.commands[currentbp]:
|
for line in self.commands[currentbp]:
|
||||||
self.onecmd(line)
|
self.onecmd(line)
|
||||||
self.lastcmd = lastcmd_back
|
self.lastcmd = lastcmd_back
|
||||||
if not self.commands_silent[currentbp]:
|
|
||||||
self.print_stack_entry(self.stack[self.curindex])
|
|
||||||
if self.commands_doprompt[currentbp]:
|
|
||||||
self._cmdloop()
|
|
||||||
self.forget()
|
self.forget()
|
||||||
return
|
return
|
||||||
return 1
|
return 1
|
||||||
@@ -926,8 +823,17 @@ class Dumper:
|
|||||||
traceback.format_exception_only(exc_type, exc_value)[-1].strip()))
|
traceback.format_exception_only(exc_type, exc_value)[-1].strip()))
|
||||||
self.interaction(frame, exc_traceback)
|
self.interaction(frame, exc_traceback)
|
||||||
|
|
||||||
# General interaction function
|
def interaction(self, frame, traceback):
|
||||||
def _cmdloop(self):
|
if self.setup(frame, traceback):
|
||||||
|
# no interaction desired at this time (happens if .pdbrc contains
|
||||||
|
# a command like "continue")
|
||||||
|
self.forget()
|
||||||
|
return
|
||||||
|
|
||||||
|
frame, lineNumber = self.stack[self.curindex]
|
||||||
|
fileName = self.canonic(frame.f_code.co_filename)
|
||||||
|
self.report('location={file="%s",line="%s"}' % (fileName, lineNumber))
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
# keyboard interrupts allow for an easy way to cancel
|
# keyboard interrupts allow for an easy way to cancel
|
||||||
@@ -938,15 +844,6 @@ class Dumper:
|
|||||||
break
|
break
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
self.message('--KeyboardInterrupt--')
|
self.message('--KeyboardInterrupt--')
|
||||||
|
|
||||||
def interaction(self, frame, traceback):
|
|
||||||
if self.setup(frame, traceback):
|
|
||||||
# no interaction desired at this time (happens if .pdbrc contains
|
|
||||||
# a command like "continue")
|
|
||||||
self.forget()
|
|
||||||
return
|
|
||||||
self.print_stack_entry(self.stack[self.curindex])
|
|
||||||
self._cmdloop()
|
|
||||||
self.forget()
|
self.forget()
|
||||||
|
|
||||||
def displayhook(self, obj):
|
def displayhook(self, obj):
|
||||||
@@ -979,33 +876,6 @@ class Dumper:
|
|||||||
exc_info = sys.exc_info()[:2]
|
exc_info = sys.exc_info()[:2]
|
||||||
self.error(traceback.format_exception_only(*exc_info)[-1].strip())
|
self.error(traceback.format_exception_only(*exc_info)[-1].strip())
|
||||||
|
|
||||||
def precmd(self, line):
|
|
||||||
"""Handle alias expansion and ';;' separator."""
|
|
||||||
line = str(line)
|
|
||||||
if not line.strip():
|
|
||||||
return line
|
|
||||||
args = line.split()
|
|
||||||
while args[0] in self.aliases:
|
|
||||||
line = self.aliases[args[0]]
|
|
||||||
ii = 1
|
|
||||||
for tmpArg in args[1:]:
|
|
||||||
line = line.replace("%" + str(ii), tmpArg)
|
|
||||||
ii += 1
|
|
||||||
line = line.replace("%*", ' '.join(args[1:]))
|
|
||||||
args = line.split()
|
|
||||||
# split into ';;' separated commands
|
|
||||||
# unless it's an alias command
|
|
||||||
if args[0] != 'alias':
|
|
||||||
marker = line.find(';;')
|
|
||||||
if marker >= 0:
|
|
||||||
# queue up everything after marker
|
|
||||||
next = line[marker+2:].lstrip()
|
|
||||||
self.cmdqueue.append(next)
|
|
||||||
line = line[:marker].rstrip()
|
|
||||||
return line
|
|
||||||
|
|
||||||
# interface abstraction functions
|
|
||||||
|
|
||||||
def message(self, msg):
|
def message(self, msg):
|
||||||
print(msg)
|
print(msg)
|
||||||
pass
|
pass
|
||||||
@@ -1014,114 +884,6 @@ class Dumper:
|
|||||||
#print('***'+ msg)
|
#print('***'+ msg)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Generic completion functions. Individual complete_foo methods can be
|
|
||||||
# assigned below to one of these functions.
|
|
||||||
|
|
||||||
def _complete_expression(self, text, line, begidx, endidx):
|
|
||||||
# Complete an arbitrary expression.
|
|
||||||
if not self.curframe:
|
|
||||||
return []
|
|
||||||
# Collect globals and locals. It is usually not really sensible to also
|
|
||||||
# complete builtins, and they clutter the namespace quite heavily, so we
|
|
||||||
# leave them out.
|
|
||||||
ns = self.curframe.f_globals.copy()
|
|
||||||
ns.update(self.curframe_locals)
|
|
||||||
if '.' in text:
|
|
||||||
# Walk an attribute chain up to the last part, similar to what
|
|
||||||
# rlcompleter does. This will bail if any of the parts are not
|
|
||||||
# simple attribute access, which is what we want.
|
|
||||||
dotted = text.split('.')
|
|
||||||
try:
|
|
||||||
obj = ns[dotted[0]]
|
|
||||||
for part in dotted[1:-1]:
|
|
||||||
obj = getattr(obj, part)
|
|
||||||
except (KeyError, AttributeError):
|
|
||||||
return []
|
|
||||||
prefix = '.'.join(dotted[:-1]) + '.'
|
|
||||||
return [prefix + n for n in dir(obj) if n.startswith(dotted[-1])]
|
|
||||||
else:
|
|
||||||
# Complete a simple name.
|
|
||||||
return [n for n in ns.keys() if n.startswith(text)]
|
|
||||||
|
|
||||||
# Command definitions, called by cmdloop()
|
|
||||||
# The argument is the remaining string on the command line
|
|
||||||
# Return true to exit from the command loop
|
|
||||||
|
|
||||||
def do_commands(self, arg):
|
|
||||||
"""commands [bpnumber]
|
|
||||||
(com) ...
|
|
||||||
(com) end
|
|
||||||
(Pdb)
|
|
||||||
|
|
||||||
Specify a list of commands for breakpoint number bpnumber.
|
|
||||||
The commands themselves are entered on the following lines.
|
|
||||||
Type a line containing just 'end' to terminate the commands.
|
|
||||||
The commands are executed when the breakpoint is hit.
|
|
||||||
|
|
||||||
To remove all commands from a breakpoint, type commands and
|
|
||||||
follow it immediately with end; that is, give no commands.
|
|
||||||
|
|
||||||
With no bpnumber argument, commands refers to the last
|
|
||||||
breakpoint set.
|
|
||||||
|
|
||||||
You can use breakpoint commands to start your program up
|
|
||||||
again. Simply use the continue command, or step, or any other
|
|
||||||
command that resumes execution.
|
|
||||||
|
|
||||||
Specifying any command resuming execution (currently continue,
|
|
||||||
step, next, return, jump, quit and their abbreviations)
|
|
||||||
terminates the command list (as if that command was
|
|
||||||
immediately followed by end). This is because any time you
|
|
||||||
resume execution (even with a simple next or step), you may
|
|
||||||
encounter another breakpoint -- which could have its own
|
|
||||||
command list, leading to ambiguities about which list to
|
|
||||||
execute.
|
|
||||||
|
|
||||||
If you use the 'silent' command in the command list, the usual
|
|
||||||
message about stopping at a breakpoint is not printed. This
|
|
||||||
may be desirable for breakpoints that are to print a specific
|
|
||||||
message and then continue. If none of the other commands
|
|
||||||
print anything, you will see no sign that the breakpoint was
|
|
||||||
reached.
|
|
||||||
"""
|
|
||||||
if not arg:
|
|
||||||
bnum = len(Breakpoint.bpbynumber) - 1
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
bnum = int(arg)
|
|
||||||
except:
|
|
||||||
self.error("Usage: commands [bnum]\n ...\n end")
|
|
||||||
return
|
|
||||||
self.commands_bnum = bnum
|
|
||||||
# Save old definitions for the case of a keyboard interrupt.
|
|
||||||
if bnum in self.commands:
|
|
||||||
old_command_defs = (self.commands[bnum],
|
|
||||||
self.commands_doprompt[bnum],
|
|
||||||
self.commands_silent[bnum])
|
|
||||||
else:
|
|
||||||
old_command_defs = None
|
|
||||||
self.commands[bnum] = []
|
|
||||||
self.commands_doprompt[bnum] = True
|
|
||||||
self.commands_silent[bnum] = False
|
|
||||||
|
|
||||||
prompt_back = self.prompt
|
|
||||||
self.prompt = '(com) '
|
|
||||||
try:
|
|
||||||
self.cmdloop()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
# Restore old definitions.
|
|
||||||
if old_command_defs:
|
|
||||||
self.commands[bnum] = old_command_defs[0]
|
|
||||||
self.commands_doprompt[bnum] = old_command_defs[1]
|
|
||||||
self.commands_silent[bnum] = old_command_defs[2]
|
|
||||||
else:
|
|
||||||
del self.commands[bnum]
|
|
||||||
del self.commands_doprompt[bnum]
|
|
||||||
del self.commands_silent[bnum]
|
|
||||||
self.error('command definition aborted, old commands restored')
|
|
||||||
finally:
|
|
||||||
self.prompt = prompt_back
|
|
||||||
|
|
||||||
def do_break(self, arg, temporary = 0):
|
def do_break(self, arg, temporary = 0):
|
||||||
"""b(reak) [ ([filename:]lineno | function) [, condition] ]
|
"""b(reak) [ ([filename:]lineno | function) [, condition] ]
|
||||||
Without argument, list all breaks.
|
Without argument, list all breaks.
|
||||||
@@ -1421,54 +1183,8 @@ class Dumper:
|
|||||||
self.clear_bpbynumber(i)
|
self.clear_bpbynumber(i)
|
||||||
self.message('Deleted %s' % bp)
|
self.message('Deleted %s' % bp)
|
||||||
|
|
||||||
def _select_frame(self, number):
|
|
||||||
assert 0 <= number < len(self.stack)
|
|
||||||
self.curindex = number
|
|
||||||
self.curframe = self.stack[self.curindex][0]
|
|
||||||
self.curframe_locals = self.curframe.f_locals
|
|
||||||
self.print_stack_entry(self.stack[self.curindex])
|
|
||||||
self.lineno = None
|
|
||||||
|
|
||||||
def do_up(self, arg):
|
|
||||||
"""u(p) [count]
|
|
||||||
Move the current frame count (default one) levels up in the
|
|
||||||
stack trace (to an older frame).
|
|
||||||
"""
|
|
||||||
if self.curindex == 0:
|
|
||||||
self.error('Oldest frame')
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
count = int(arg or 1)
|
|
||||||
except ValueError:
|
|
||||||
self.error('Invalid frame count (%s)' % arg)
|
|
||||||
return
|
|
||||||
if count < 0:
|
|
||||||
newframe = 0
|
|
||||||
else:
|
|
||||||
newframe = max(0, self.curindex - count)
|
|
||||||
self._select_frame(newframe)
|
|
||||||
|
|
||||||
def do_down(self, arg):
|
|
||||||
"""d(own) [count]
|
|
||||||
Move the current frame count (default one) levels down in the
|
|
||||||
stack trace (to a newer frame).
|
|
||||||
"""
|
|
||||||
if self.curindex + 1 == len(self.stack):
|
|
||||||
self.error('Newest frame')
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
count = int(arg or 1)
|
|
||||||
except ValueError:
|
|
||||||
self.error('Invalid frame count (%s)' % arg)
|
|
||||||
return
|
|
||||||
if count < 0:
|
|
||||||
newframe = len(self.stack) - 1
|
|
||||||
else:
|
|
||||||
newframe = min(len(self.stack) - 1, self.curindex + count)
|
|
||||||
self._select_frame(newframe)
|
|
||||||
|
|
||||||
def do_until(self, arg):
|
def do_until(self, arg):
|
||||||
"""unt(il) [lineno]
|
"""until [lineno]
|
||||||
Without argument, continue execution until the line with a
|
Without argument, continue execution until the line with a
|
||||||
number greater than the current one is reached. With a line
|
number greater than the current one is reached. With a line
|
||||||
number, continue execution until a line with a number greater
|
number, continue execution until a line with a number greater
|
||||||
@@ -1487,35 +1203,28 @@ class Dumper:
|
|||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
lineno = None
|
lineno = None
|
||||||
self.set_until(self.curframe, lineno)
|
lineno = self.curframe.f_lineno + 1
|
||||||
|
self._set_stopinfo(self.curframe, self.curframe, lineno)
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def do_step(self, arg):
|
def do_step(self, arg):
|
||||||
"""s(tep)
|
|
||||||
Execute the current line, stop at the first possible occasion
|
|
||||||
(either in a function that is called or in the current
|
|
||||||
function).
|
|
||||||
"""
|
|
||||||
self.set_step()
|
self.set_step()
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def do_next(self, arg):
|
def do_next(self, arg):
|
||||||
"""n(ext)
|
self._set_stopinfo(self.curframe, None)
|
||||||
Continue execution until the next line in the current function
|
|
||||||
is reached or it returns.
|
|
||||||
"""
|
|
||||||
self.set_next(self.curframe)
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def do_return(self, arg):
|
def do_return(self, arg):
|
||||||
"""r(eturn)
|
if self.curframe.f_code.co_flags & inspect.CO_GENERATOR:
|
||||||
Continue execution until the current function returns.
|
self._set_stopinfo(self.curframe, None, -1)
|
||||||
"""
|
else:
|
||||||
self.set_return(self.curframe)
|
self._set_stopinfo(self.curframe.f_back, self.curframe)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def do_continue(self, arg):
|
def do_continue(self, arg):
|
||||||
"""c(ont(inue))
|
"""continue
|
||||||
Continue execution, only stop when a breakpoint is encountered.
|
Continue execution, only stop when a breakpoint is encountered.
|
||||||
"""
|
"""
|
||||||
if not self.nosigint:
|
if not self.nosigint:
|
||||||
@@ -1532,7 +1241,7 @@ class Dumper:
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
def do_jump(self, arg):
|
def do_jump(self, arg):
|
||||||
"""j(ump) lineno
|
"""jump lineno
|
||||||
Set the next line that will be executed. Only available in
|
Set the next line that will be executed. Only available in
|
||||||
the bottom-most frame. This lets you jump back and execute
|
the bottom-most frame. This lets you jump back and execute
|
||||||
code again, or jump forward to skip code that you don't want
|
code again, or jump forward to skip code that you don't want
|
||||||
@@ -1555,7 +1264,6 @@ class Dumper:
|
|||||||
# new position
|
# new position
|
||||||
self.curframe.f_lineno = arg
|
self.curframe.f_lineno = arg
|
||||||
self.stack[self.curindex] = self.stack[self.curindex][0], arg
|
self.stack[self.curindex] = self.stack[self.curindex][0], arg
|
||||||
self.print_stack_entry(self.stack[self.curindex])
|
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
self.error('Jump failed: %s' % e)
|
self.error('Jump failed: %s' % e)
|
||||||
|
|
||||||
@@ -1569,7 +1277,6 @@ class Dumper:
|
|||||||
globals = self.curframe.f_globals
|
globals = self.curframe.f_globals
|
||||||
locals = self.curframe_locals
|
locals = self.curframe_locals
|
||||||
p = Dumper(self.stdin, self.stdout)
|
p = Dumper(self.stdin, self.stdout)
|
||||||
p.prompt = "(%s) " % self.prompt.strip()
|
|
||||||
self.message("ENTERING RECURSIVE DEBUGGER")
|
self.message("ENTERING RECURSIVE DEBUGGER")
|
||||||
sys.call_tracing(p.run, (arg, globals, locals))
|
sys.call_tracing(p.run, (arg, globals, locals))
|
||||||
self.message("LEAVING RECURSIVE DEBUGGER")
|
self.message("LEAVING RECURSIVE DEBUGGER")
|
||||||
@@ -1706,42 +1413,6 @@ class Dumper:
|
|||||||
# None of the above...
|
# None of the above...
|
||||||
self.message(type(value))
|
self.message(type(value))
|
||||||
|
|
||||||
def do_display(self, arg):
|
|
||||||
"""display [expression]
|
|
||||||
|
|
||||||
Display the value of the expression if it changed, each time execution
|
|
||||||
stops in the current frame.
|
|
||||||
|
|
||||||
Without expression, list all display expressions for the current frame.
|
|
||||||
"""
|
|
||||||
if not arg:
|
|
||||||
self.message('Currently displaying:')
|
|
||||||
for item in self.displaying.get(self.curframe, {}).items():
|
|
||||||
self.message('%s: %r' % item)
|
|
||||||
else:
|
|
||||||
val = self._getval_except(arg)
|
|
||||||
self.displaying.setdefault(self.curframe, {})[arg] = val
|
|
||||||
self.message('display %s: %r' % (arg, val))
|
|
||||||
|
|
||||||
def do_undisplay(self, arg):
|
|
||||||
"""undisplay [expression]
|
|
||||||
|
|
||||||
Do not display the expression any more in the current frame.
|
|
||||||
|
|
||||||
Without expression, clear all display expressions for the current frame.
|
|
||||||
"""
|
|
||||||
if arg:
|
|
||||||
try:
|
|
||||||
del self.displaying.get(self.curframe, {})[arg]
|
|
||||||
except KeyError:
|
|
||||||
self.error('not displaying %s' % arg)
|
|
||||||
else:
|
|
||||||
self.displaying.pop(self.curframe, None)
|
|
||||||
|
|
||||||
def complete_undisplay(self, text, line, begidx, endidx):
|
|
||||||
return [e for e in self.displaying.get(self.curframe, {})
|
|
||||||
if e.startswith(text)]
|
|
||||||
|
|
||||||
def do_interact(self, arg):
|
def do_interact(self, arg):
|
||||||
"""interact
|
"""interact
|
||||||
|
|
||||||
@@ -1752,21 +1423,6 @@ class Dumper:
|
|||||||
ns.update(self.curframe_locals)
|
ns.update(self.curframe_locals)
|
||||||
code.interact("*interactive*", local=ns)
|
code.interact("*interactive*", local=ns)
|
||||||
|
|
||||||
# List of all the commands making the program resume execution.
|
|
||||||
commands_resuming = ['do_continue', 'do_step', 'do_next', 'do_return',
|
|
||||||
'do_quit', 'do_jump']
|
|
||||||
|
|
||||||
def print_stack_entry(self, frame_lineno):
|
|
||||||
frame, lineno = frame_lineno
|
|
||||||
if frame is self.curframe:
|
|
||||||
prefix = '> '
|
|
||||||
else:
|
|
||||||
prefix = ' '
|
|
||||||
prompt_prefix = '\n-> '
|
|
||||||
self.message(prefix + self.format_stack_entry(frame_lineno, prompt_prefix))
|
|
||||||
|
|
||||||
# other helper functions
|
|
||||||
|
|
||||||
def lookupmodule(self, filename):
|
def lookupmodule(self, filename):
|
||||||
"""Helper function for break/clear parsing -- may be overridden.
|
"""Helper function for break/clear parsing -- may be overridden.
|
||||||
|
|
||||||
|
|||||||
@@ -345,6 +345,19 @@ void PdbEngine::requestModuleSymbols(const QString &moduleName)
|
|||||||
runCommand(cmd);
|
runCommand(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PdbEngine::refreshLocation(const GdbMi &reportedLocation)
|
||||||
|
{
|
||||||
|
StackFrame frame;
|
||||||
|
frame.file = reportedLocation["file"].toUtf8();
|
||||||
|
frame.line = reportedLocation["line"].toInt();
|
||||||
|
if (state() == InferiorRunOk) {
|
||||||
|
showMessage(QString::fromLatin1("STOPPED AT: %1:%2").arg(frame.file).arg(frame.line));
|
||||||
|
gotoLocation(frame);
|
||||||
|
notifyInferiorSpontaneousStop();
|
||||||
|
updateAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PdbEngine::refreshSymbols(const GdbMi &symbols)
|
void PdbEngine::refreshSymbols(const GdbMi &symbols)
|
||||||
{
|
{
|
||||||
QString moduleName = symbols["module"].toUtf8();
|
QString moduleName = symbols["module"].toUtf8();
|
||||||
@@ -448,13 +461,11 @@ void PdbEngine::handleOutput(const QByteArray &data)
|
|||||||
{
|
{
|
||||||
m_inbuffer.append(data);
|
m_inbuffer.append(data);
|
||||||
while (true) {
|
while (true) {
|
||||||
int pos = m_inbuffer.indexOf("(Pdb)");
|
int pos = m_inbuffer.indexOf('\n');
|
||||||
if (pos == -1)
|
|
||||||
pos = m_inbuffer.indexOf(">>>");
|
|
||||||
if (pos == -1)
|
if (pos == -1)
|
||||||
break;
|
break;
|
||||||
QByteArray response = m_inbuffer.left(pos).trimmed();
|
QByteArray response = m_inbuffer.left(pos).trimmed();
|
||||||
m_inbuffer = m_inbuffer.mid(pos + 6);
|
m_inbuffer = m_inbuffer.mid(pos + 1);
|
||||||
handleOutput2(response);
|
handleOutput2(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -477,6 +488,8 @@ void PdbEngine::handleOutput2(const QByteArray &data)
|
|||||||
refreshModules(item);
|
refreshModules(item);
|
||||||
} else if (line.startsWith("symbols={")) {
|
} else if (line.startsWith("symbols={")) {
|
||||||
refreshSymbols(item);
|
refreshSymbols(item);
|
||||||
|
} else if (line.startsWith("location={")) {
|
||||||
|
refreshLocation(item);
|
||||||
} else if (line.startsWith("Breakpoint")) {
|
} else if (line.startsWith("Breakpoint")) {
|
||||||
int pos1 = line.indexOf(" at ");
|
int pos1 = line.indexOf(" at ");
|
||||||
QTC_ASSERT(pos1 != -1, continue);
|
QTC_ASSERT(pos1 != -1, continue);
|
||||||
@@ -495,26 +508,6 @@ void PdbEngine::handleOutput2(const QByteArray &data)
|
|||||||
QTC_CHECK(!bp.needsChange());
|
QTC_CHECK(!bp.needsChange());
|
||||||
bp.notifyBreakpointInsertOk();
|
bp.notifyBreakpointInsertOk();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (line.startsWith("> /")) {
|
|
||||||
lineContext = line;
|
|
||||||
int pos1 = line.indexOf('(');
|
|
||||||
int pos2 = line.indexOf(')', pos1);
|
|
||||||
if (pos1 != -1 && pos2 != -1) {
|
|
||||||
int lineNumber = line.mid(pos1 + 1, pos2 - pos1 - 1).toInt();
|
|
||||||
QByteArray fileName = line.mid(2, pos1 - 2);
|
|
||||||
StackFrame frame;
|
|
||||||
frame.file = _(fileName);
|
|
||||||
frame.line = lineNumber;
|
|
||||||
if (state() == InferiorRunOk) {
|
|
||||||
showMessage(QString::fromLatin1("STOPPED AT: %1:%2").arg(frame.file).arg(frame.line));
|
|
||||||
gotoLocation(frame);
|
|
||||||
notifyInferiorSpontaneousStop();
|
|
||||||
updateAll();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ private:
|
|||||||
void runCommand(const DebuggerCommand &cmd);
|
void runCommand(const DebuggerCommand &cmd);
|
||||||
void postDirectCommand(const QByteArray &command);
|
void postDirectCommand(const QByteArray &command);
|
||||||
|
|
||||||
|
void refreshLocation(const GdbMi &reportedLocation);
|
||||||
void refreshStack(const GdbMi &stack);
|
void refreshStack(const GdbMi &stack);
|
||||||
void refreshLocals(const GdbMi &vars);
|
void refreshLocals(const GdbMi &vars);
|
||||||
void refreshModules(const GdbMi &modules);
|
void refreshModules(const GdbMi &modules);
|
||||||
|
|||||||
Reference in New Issue
Block a user