forked from qt-creator/qt-creator
Debugger: More flexibility for "ranged expressions"
The range boundary and stride can be integral expressions. Also ( ) are valid delimiters now, making descriptions like list.at(2.(4).100+2) acceptable. Change-Id: Ief68c0a1b0b0d3813b2939d60e0806f5cd3ff0b0 Reviewed-by: Christian Stenger <christian.stenger@digia.com> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@digia.com>
This commit is contained in:
@@ -452,6 +452,8 @@
|
||||
|
||||
\li To step into a function or a subfunction, press \key{F11}.
|
||||
|
||||
\li To leave the current function or subfunction, press \key{Shift+F11}.
|
||||
|
||||
\li To continue running the program, press \key{F5}.
|
||||
|
||||
\li To run to the selected function when you are stepping into a nested
|
||||
@@ -622,17 +624,53 @@
|
||||
|
||||
\section1 Locals and Expressions
|
||||
|
||||
Whenever a program stops under the control of the debugger, it retrieves
|
||||
information about the topmost stack frame and displays it in the
|
||||
\gui{Locals and Expressions} view. The \gui{Locals and Expressions} view
|
||||
typically includes information about parameters of the function in that
|
||||
frame as well as the local variables.
|
||||
The Locals and Expressions view consists of three parts: the
|
||||
\gui{Locals} pane at the top, the \gui{Return Value} pane in the middle,
|
||||
and the \gui{Expressions} pane at the bottom. The \gui{Return Value}
|
||||
and \gui{Expression} panes are only visible if they are not empty.
|
||||
|
||||
\image qtcreator-locals-expressions.png "Locals and Expressions view"
|
||||
|
||||
Whenever a program stops under the control of the debugger, it retrieves
|
||||
information about the topmost stack frame and displays it in the
|
||||
\gui{Locals and Expressions} view. The \gui{Locals} pane shows
|
||||
information about parameters of the function in that
|
||||
frame as well as the local variables. If the last operation in
|
||||
the debugger was returning from a function after pressing
|
||||
\key{Shift+F11}, the \gui{Return Value} pane displays the value
|
||||
returned by the function.
|
||||
|
||||
To compute values of arithmetic expressions or function
|
||||
calls, use expression evaluators in the \gui{Expressions} pane.
|
||||
To insert a new expression evaluator, either double-click on an
|
||||
empty part of the \gui{Locals and Expressions} view, or select
|
||||
\gui{Insert New Expression Evaluator} from the context menu, or
|
||||
drag and drop an expression from the code editor.
|
||||
|
||||
\note Expression evaluators are powerful, but slow down debugger
|
||||
operation significantly. It is advisable to not use them excessively,
|
||||
and to remove unneeded expression evaluators as soon as possible.
|
||||
|
||||
Expression evaluators are re-evaluated whenever the current
|
||||
frame changes. Note that functions used in the expressions are
|
||||
called each time, even if they have side-effects.
|
||||
|
||||
All backends support simple C and C++ expressions. Functions
|
||||
can be called only if they are actually compiled into the
|
||||
debugged executable or a library used by the executable.
|
||||
Most notably, inlined functions such as most \c{operator[]}
|
||||
implementations of standard containers are typically \e{not}
|
||||
available.
|
||||
|
||||
When using GDB or LLDB as backend, a special ranged
|
||||
syntax can be used to display multiple values with one
|
||||
expression. A sub-expression of form \c{foo[a..b]} is
|
||||
split into a sequence of individually evaluated expressions
|
||||
\c{foo[a], ..., foo[b]}.
|
||||
|
||||
Compound variables of struct or class type are displayed as
|
||||
expandable in the view. Expand entries to show
|
||||
all members. Together with the display of value and type, you can
|
||||
expandable in the view. Expand entries to show all members.
|
||||
Together with the display of value and type, you can
|
||||
examine and traverse the low-level layout of object data.
|
||||
|
||||
|
||||
|
||||
@@ -1332,15 +1332,50 @@ class DumperBase:
|
||||
|
||||
# Parses a..b and a.(s).b
|
||||
def parseRange(self, exp):
|
||||
match = re.search("\[(.+?)\.(\(.+?\))?\.(.+?)\]", exp)
|
||||
|
||||
# Search for the first unbalanced delimiter in s
|
||||
def searchUnbalanced(s, upwards):
|
||||
paran = 0
|
||||
bracket = 0
|
||||
if upwards:
|
||||
open_p, close_p, open_b, close_b = '(', ')', '[', ']'
|
||||
else:
|
||||
open_p, close_p, open_b, close_b = ')', '(', ']', '['
|
||||
for i in range(len(s)):
|
||||
c = s[i]
|
||||
if c == open_p:
|
||||
paran += 1
|
||||
elif c == open_b:
|
||||
bracket += 1
|
||||
elif c == close_p:
|
||||
paran -= 1
|
||||
if paran < 0:
|
||||
return i
|
||||
elif c == close_b:
|
||||
bracket -= 1
|
||||
if bracket < 0:
|
||||
return i
|
||||
return len(s)
|
||||
|
||||
match = re.search("(\.)(\(.+?\))?(\.)", exp)
|
||||
if match:
|
||||
a = match.group(1)
|
||||
s = match.group(2)
|
||||
b = match.group(3)
|
||||
left_e = match.start(1)
|
||||
left_s = 1 + left_e - searchUnbalanced(exp[left_e::-1], False)
|
||||
right_s = match.end(3)
|
||||
right_e = right_s + searchUnbalanced(exp[right_s:], True)
|
||||
template = exp[:left_s] + '%s' + exp[right_e:]
|
||||
|
||||
a = exp[left_s:left_e]
|
||||
b = exp[right_s:right_e]
|
||||
|
||||
try:
|
||||
step = toInteger(s[1:len(s)-1]) if s else 1
|
||||
template = exp[:match.start(1)] + '%s' + exp[match.end(3):]
|
||||
return True, toInteger(a), step, toInteger(b) + 1, template
|
||||
# Allow integral expressions.
|
||||
ss = toInteger(self.parseAndEvaluate(s[1:len(s)-1]) if s else 1)
|
||||
aa = toInteger(self.parseAndEvaluate(a))
|
||||
bb = toInteger(self.parseAndEvaluate(b))
|
||||
if aa < bb and ss > 0:
|
||||
return True, aa, ss, bb + 1, template
|
||||
except:
|
||||
pass
|
||||
return False, 0, 1, 1, exp
|
||||
|
||||
Reference in New Issue
Block a user