summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cross-project-tests/debuginfo-tests/dexter/Commands.md44
-rw-r--r--cross-project-tests/debuginfo-tests/dexter/dex/command/commands/DexContinue.py55
-rw-r--r--cross-project-tests/debuginfo-tests/dexter/dex/command/commands/DexStepFunction.py38
3 files changed, 136 insertions, 1 deletions
diff --git a/cross-project-tests/debuginfo-tests/dexter/Commands.md b/cross-project-tests/debuginfo-tests/dexter/Commands.md
index a98261a50009..afec3e6bbd00 100644
--- a/cross-project-tests/debuginfo-tests/dexter/Commands.md
+++ b/cross-project-tests/debuginfo-tests/dexter/Commands.md
@@ -13,7 +13,8 @@
* [DexDeclareFile](Commands.md#DexDeclareFile)
* [DexFinishTest](Commands.md#DexFinishTest)
* [DexCommandLine](Commands.md#DexCommandLine)
-
+* [DexStepFunction](Commands.md#DexStepFunction)
+* [DexContinue](Commands.md#DexContinue)
---
## DexExpectProgramState
DexExpectProgramState(state [,**times])
@@ -377,3 +378,44 @@ line this command is found on.
### Heuristic
[Deprecated]
+
+
+---
+## DexStepFunction
+ DexStepFunction(function_name[, **hit_count=0])
+
+ Arg list:
+ function_name (str): function to step through.
+ hit_count (int): If provided, limit the number of times the command
+ triggers.
+
+### Description
+NOTE: Only supported for DAP-based debuggers.
+
+This command controls stepping behaviour: Tell dexter to set a function
+breakpoint and step through the function after hitting it. Composes well with
+itself (you can may a callstack with multiple targets to step through) and
+`DexContinue`.
+
+---
+## DexContinue
+ DexContinue(*[expr, *values], **from_line[, **to_line, **hit_count])
+
+ Arg list:
+ function_name (str): function to step through.
+ hit_count (int): If provided, limit the number of times the command
+ triggers.
+
+### Description
+NOTE: Only supported for DAP-based debuggers.
+
+This command controls stepping behaviour: Tell dexter to set a breakpoint on
+`from_line`. When it is hit and optionally '(expr) == (values[n])' is true,
+optionally set a breakpoint on `to_line`. Then 'continue' (tell the debugger to
+run freely until a breakpoint is hit). Composed with `DexStepFunction` this
+lets you avoid stepping over certain regions (many loop iterations, for
+example). Continue-ing off the end of a `DexStepFunction` is well defined;
+stepping will resume in `DexStepFunction` targets deeper in the callstack.
+
+FIXME: hit_count should probably be inverted, like `DexLimitSteps`, to trigger
+AFTER that many hits?
diff --git a/cross-project-tests/debuginfo-tests/dexter/dex/command/commands/DexContinue.py b/cross-project-tests/debuginfo-tests/dexter/dex/command/commands/DexContinue.py
new file mode 100644
index 000000000000..113f34bedd13
--- /dev/null
+++ b/cross-project-tests/debuginfo-tests/dexter/dex/command/commands/DexContinue.py
@@ -0,0 +1,55 @@
+# DExTer : Debugging Experience Tester
+# ~~~~~~ ~ ~~ ~ ~~
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+"""A Command that tells dexter to set a breakpoint which, after hitting,
+signals that the debugger should 'continue' until another is hit. Continuing
+out of a function being stepped through with DexStepFunction is well defined:
+stepping will resume in other functions tracked further down the stacktrace.
+
+NOTE: Only supported for DAP-based debuggers.
+"""
+
+from dex.command.CommandBase import CommandBase
+
+
+class DexContinue(CommandBase):
+ def __init__(self, *args, **kwargs):
+ # DexContinue(*[expr, *values], **from_line[, **to_line, **hit_count])
+
+ # Optional positional args: expr, values.
+ if len(args) == 0:
+ self.expression = None
+ self.values = []
+ elif len(args) == 1:
+ raise TypeError("expected 0 or at least 2 positional arguments")
+ else:
+ self.expression = args[0]
+ self.values = [str(arg) for arg in args[1:]]
+
+ # Required keyword arg: from_line.
+ try:
+ self.from_line = kwargs.pop("from_line")
+ except:
+ raise TypeError("Missing from_line argument")
+
+ # Optional conditional args: to_line, hit_count.
+ self.to_line = kwargs.pop("to_line", None)
+ self.hit_count = kwargs.pop("hit_count", None)
+
+ if kwargs:
+ raise TypeError("unexpected named args: {}".format(", ".join(kwargs)))
+ super(DexContinue, self).__init__()
+
+ def eval(self):
+ raise NotImplementedError("DexContinue commands cannot be evaled.")
+
+ @staticmethod
+ def get_name():
+ return __class__.__name__
+
+ @staticmethod
+ def get_subcommands() -> dict:
+ return None
diff --git a/cross-project-tests/debuginfo-tests/dexter/dex/command/commands/DexStepFunction.py b/cross-project-tests/debuginfo-tests/dexter/dex/command/commands/DexStepFunction.py
new file mode 100644
index 000000000000..4b80de87a1bb
--- /dev/null
+++ b/cross-project-tests/debuginfo-tests/dexter/dex/command/commands/DexStepFunction.py
@@ -0,0 +1,38 @@
+# DExTer : Debugging Experience Tester
+# ~~~~~~ ~ ~~ ~ ~~
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+"""A Command that tells dexter to set a function breakpoint and step through
+the function after hitting it.
+
+NOTE: Only supported for DAP-based debuggers.
+"""
+
+from dex.command.CommandBase import CommandBase
+
+
+class DexStepFunction(CommandBase):
+ def __init__(self, *args, **kwargs):
+ if len(args) < 1:
+ raise TypeError("expected 1 positional argument")
+ self.function = str(args[0])
+ self.hit_count = kwargs.pop("hit_count", None)
+ if kwargs:
+ raise TypeError(f"unexpected named args: {', '.join(kwargs)}")
+ super(DexStepFunction, self).__init__()
+
+ def eval(self):
+ raise NotImplementedError("DexStepFunction commands cannot be evaled.")
+
+ def get_function(self):
+ return self.function
+
+ @staticmethod
+ def get_name():
+ return __class__.__name__
+
+ @staticmethod
+ def get_subcommands() -> dict:
+ return None