[debuginfo-tests] 469833f - [dexter] Add hit_count keyword arg to DexLimitSteps

via llvm-commits llvm-commits at lists.llvm.org
Fri May 21 04:52:23 PDT 2021


Author: OCHyams
Date: 2021-05-21T12:45:02+01:00
New Revision: 469833f418e1704331f8dccb06ccd391f8d726e1

URL: https://github.com/llvm/llvm-project/commit/469833f418e1704331f8dccb06ccd391f8d726e1
DIFF: https://github.com/llvm/llvm-project/commit/469833f418e1704331f8dccb06ccd391f8d726e1.diff

LOG: [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

Added: 
    debuginfo-tests/dexter/feature_tests/commands/perfect/limit_steps/hit_count.cpp

Modified: 
    debuginfo-tests/dexter/Commands.md
    debuginfo-tests/dexter/dex/command/commands/DexLimitSteps.py
    debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ConditionalController.py

Removed: 
    


################################################################################
diff  --git a/debuginfo-tests/dexter/Commands.md b/debuginfo-tests/dexter/Commands.md
index f61418bbdeedd..5de685906c01a 100644
--- a/debuginfo-tests/dexter/Commands.md
+++ b/debuginfo-tests/dexter/Commands.md
@@ -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

diff  --git a/debuginfo-tests/dexter/dex/command/commands/DexLimitSteps.py b/debuginfo-tests/dexter/dex/command/commands/DexLimitSteps.py
index 5090ff40ccb4e..d779539e07fe4 100644
--- a/debuginfo-tests/dexter/dex/command/commands/DexLimitSteps.py
+++ b/debuginfo-tests/dexter/dex/command/commands/DexLimitSteps.py
@@ -27,6 +27,7 @@ def __init__(self, *args, **kwargs):
         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)))

diff  --git a/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ConditionalController.py b/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ConditionalController.py
index a910ac054dc59..0c20ecf6b2628 100644
--- a/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ConditionalController.py
+++ b/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ConditionalController.py
@@ -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 @@ def get_conditional_expression_list(self):
             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 @@ def _build_bp_ranges(self):
                   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 @@ def _run_debugger_custom(self):
                     # 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 @@ def _run_debugger_custom(self):
                 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)
 

diff  --git a/debuginfo-tests/dexter/feature_tests/commands/perfect/limit_steps/hit_count.cpp b/debuginfo-tests/dexter/feature_tests/commands/perfect/limit_steps/hit_count.cpp
new file mode 100644
index 0000000000000..e7cd903c756c0
--- /dev/null
+++ b/debuginfo-tests/dexter/feature_tests/commands/perfect/limit_steps/hit_count.cpp
@@ -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')


        


More information about the llvm-commits mailing list