mirror of
https://github.com/intel/llvm.git
synced 2026-01-27 14:50:42 +08:00
[dexter] Add hit_count keyword arg to DexLimitSteps
The DexLimitSteps command leading breakpoint will be deleted after triggering 'hit_count' number of times if the argument is provided. All the lit tests pass on linux (with lldb), and I've tested this on windows (with vs2017) manually as the lit tests for DexLimitSteps are currently unsupported on windows. Reviewed By: StephenTozer, chrisjackson Differential Revision: https://reviews.llvm.org/D101527
This commit is contained in:
@@ -178,7 +178,7 @@ Expect the source line this is found on will never be stepped on to.
|
||||
----
|
||||
## DexLimitSteps
|
||||
DexLimitSteps([expr, *values][, **from_line=1][,**to_line=Max]
|
||||
[,**on_line])
|
||||
[,**on_line][,**hit_count])
|
||||
|
||||
Args:
|
||||
expr (str): variable or value to compare.
|
||||
@@ -191,12 +191,15 @@ Expect the source line this is found on will never be stepped on to.
|
||||
to_line (int): Define the end of the limited step range.
|
||||
on_line (int): Define a range with length 1 starting and ending on the
|
||||
same line.
|
||||
hit_count (int): If provided, limit the number of times the command
|
||||
triggers.
|
||||
|
||||
### Description
|
||||
Define a limited stepping range that may be predicated on a condition. When the
|
||||
leading line is stepped on and any condition '(expr) == (values[n])' is true or
|
||||
there are no conditions, set a range of temporary breakpoints within the test
|
||||
file defined by the range 'from_line' and 'to_line' or 'on_line'.
|
||||
file defined by the range 'from_line' and 'to_line' or 'on_line'. This only
|
||||
happens 'hit_count' number of times if the argument is provided.
|
||||
|
||||
The condition is only evaluated on the line 'from_line' or 'on_line'. If the
|
||||
condition is not true at the start of the range, or that line is never stepped
|
||||
|
||||
@@ -27,6 +27,7 @@ class DexLimitSteps(CommandBase):
|
||||
except KeyError:
|
||||
self.from_line = kwargs.pop('from_line', 1)
|
||||
self.to_line = kwargs.pop('to_line', 999999)
|
||||
self.hit_count = kwargs.pop('hit_count', None)
|
||||
if kwargs:
|
||||
raise TypeError('unexpected named args: {}'.format(
|
||||
', '.join(kwargs)))
|
||||
|
||||
@@ -31,14 +31,20 @@ class BreakpointRange:
|
||||
Args:
|
||||
expression: None for no conditions, or a str expression to compare
|
||||
against `values`.
|
||||
|
||||
hit_count: None for no limit, or int to set the number of times the
|
||||
leading breakpoint is triggered before it is removed.
|
||||
"""
|
||||
|
||||
def __init__(self, expression: str, path: str, range_from: int, range_to: int, values: list):
|
||||
def __init__(self, expression: str, path: str, range_from: int, range_to: int,
|
||||
values: list, hit_count: int):
|
||||
self.expression = expression
|
||||
self.path = path
|
||||
self.range_from = range_from
|
||||
self.range_to = range_to
|
||||
self.conditional_values = values
|
||||
self.max_hit_count = hit_count
|
||||
self.current_hit_count = 0
|
||||
|
||||
def has_conditions(self):
|
||||
return self.expression != None
|
||||
@@ -51,6 +57,14 @@ class BreakpointRange:
|
||||
conditional_list.append(conditional_expression)
|
||||
return conditional_list
|
||||
|
||||
def add_hit(self):
|
||||
self.current_hit_count += 1
|
||||
|
||||
def should_be_removed(self):
|
||||
if self.max_hit_count == None:
|
||||
return False
|
||||
return self.current_hit_count >= self.max_hit_count
|
||||
|
||||
|
||||
class ConditionalController(DebuggerControllerBase):
|
||||
def __init__(self, context, step_collection):
|
||||
@@ -76,7 +90,8 @@ class ConditionalController(DebuggerControllerBase):
|
||||
lc.path,
|
||||
lc.from_line,
|
||||
lc.to_line,
|
||||
lc.values)
|
||||
lc.values,
|
||||
lc.hit_count)
|
||||
self._bp_ranges.append(bpr)
|
||||
except KeyError:
|
||||
raise DebuggerException('Missing DexLimitSteps commands, cannot conditionally step.')
|
||||
@@ -129,6 +144,11 @@ class ConditionalController(DebuggerControllerBase):
|
||||
# This is a trailing bp. Mark it for removal.
|
||||
bp_to_delete.append(bp_id)
|
||||
continue
|
||||
|
||||
bpr.add_hit()
|
||||
if bpr.should_be_removed():
|
||||
bp_to_delete.append(bp_id)
|
||||
del self._leading_bp_handles[bp_id]
|
||||
# Add a range of trailing breakpoints covering the lines
|
||||
# requested in the DexLimitSteps command. Ignore first line as
|
||||
# that's covered by the leading bp we just hit and include the
|
||||
@@ -136,7 +156,7 @@ class ConditionalController(DebuggerControllerBase):
|
||||
for line in range(bpr.range_from + 1, bpr.range_to + 1):
|
||||
self.debugger.add_breakpoint(bpr.path, line)
|
||||
|
||||
# Remove any trailing breakpoints we just hit.
|
||||
# Remove any trailing or expired leading breakpoints we just hit.
|
||||
for bp_id in bp_to_delete:
|
||||
self.debugger.delete_breakpoint(bp_id)
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// Purpose:
|
||||
// Test that \DexLimitSteps keyword argument hit_count correctly limits
|
||||
// the number of times the command can trigger.
|
||||
//
|
||||
// REQUIRES: system-linux
|
||||
//
|
||||
// RUN: %dexter_regression_test -- %s | FileCheck %s
|
||||
// CHECK: hit_count.cpp
|
||||
|
||||
int a;
|
||||
int main() {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
a = i; // DexLabel('check')
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//// Unconditionally limit dexter's view of the program to 'on_line' and check
|
||||
//// for i=0, i=1. The test will fail if dexter sees any other value for test.
|
||||
// DexLimitSteps(hit_count=2, on_line=ref('check'))
|
||||
// DexExpectWatchValue('i', '0', '1')
|
||||
Reference in New Issue
Block a user