diff options
author | Stephen Tozer <Stephen.Tozer@Sony.com> | 2023-03-01 13:05:11 +0000 |
---|---|---|
committer | Stephen Tozer <Stephen.Tozer@Sony.com> | 2023-03-22 13:50:00 +0000 |
commit | ee5617dc71b311d69fc048d4a62f59c1e37d1434 (patch) | |
tree | 365a32eeff52d93b05c4d3c5a94d47e310ed32cb | |
parent | 893ce5759fe2e450dc637d4c76e779f883535882 (diff) | |
download | llvm-ee5617dc71b311d69fc048d4a62f59c1e37d1434.tar.gz |
[Dexter] Add timeout options
Adds a pair of options for Dexter that allow the user to specify a
timeout duration. These options are:
* --timeout-total: Times out if the total run-time of the debugger session
exceeds <timeout-total> seconds.
* --timeout-breakpoint: Times out if the time without hitting a
breakpoint exceeds <timeout-breakpoint> seconds.
Reviewed By: Orlando
Differential Revision: https://reviews.llvm.org/D145063
4 files changed, 82 insertions, 6 deletions
diff --git a/cross-project-tests/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ConditionalController.py b/cross-project-tests/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ConditionalController.py index ccff7419d682..c2e97e375d97 100644 --- a/cross-project-tests/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ConditionalController.py +++ b/cross-project-tests/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/ConditionalController.py @@ -16,6 +16,7 @@ from dex.debugger.DebuggerControllers.ControllerHelpers import in_source_file, u from dex.debugger.DebuggerControllers.DebuggerControllerBase import DebuggerControllerBase from dex.debugger.DebuggerBase import DebuggerBase from dex.utils.Exceptions import DebuggerException +from dex.utils.Timeout import Timeout class BreakpointRange: @@ -140,10 +141,26 @@ class ConditionalController(DebuggerControllerBase): time.sleep(self._pause_between_steps) exit_desired = False + timed_out = False + total_timeout = Timeout(self.context.options.timeout_total) while not self.debugger.is_finished: - while self.debugger.is_running: - pass + + breakpoint_timeout = Timeout(self.context.options.timeout_breakpoint) + while self.debugger.is_running and not timed_out: + # Check to see whether we've timed out while we're waiting. + if total_timeout.timed_out(): + self.context.logger.error('Debugger session has been ' + f'running for {total_timeout.elapsed}s, timeout reached!') + timed_out = True + if breakpoint_timeout.timed_out(): + self.context.logger.error(f'Debugger session has not ' + f'hit a breakpoint for {breakpoint_timeout.elapsed}s, timeout ' + 'reached!') + timed_out = True + + if timed_out: + break step_info = self.debugger.get_step_info(self._watches, self._step_index) if step_info.current_frame: diff --git a/cross-project-tests/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/DefaultController.py b/cross-project-tests/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/DefaultController.py index 8315bb64c04c..1cc2c4410768 100644 --- a/cross-project-tests/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/DefaultController.py +++ b/cross-project-tests/debuginfo-tests/dexter/dex/debugger/DebuggerControllers/DefaultController.py @@ -13,6 +13,7 @@ import time from dex.debugger.DebuggerControllers.DebuggerControllerBase import DebuggerControllerBase from dex.debugger.DebuggerControllers.ControllerHelpers import in_source_file, update_step_watches from dex.utils.Exceptions import DebuggerException, LoadDebuggerException +from dex.utils.Timeout import Timeout class EarlyExitCondition(object): def __init__(self, on_line, hit_count, expression, values): @@ -81,12 +82,25 @@ class DefaultController(DebuggerControllerBase): self.watches.update(command_obj.get_watches()) early_exit_conditions = self._get_early_exit_conditions() + timed_out = False + total_timeout = Timeout(self.context.options.timeout_total) max_steps = self.context.options.max_steps for _ in range(max_steps): - while self.debugger.is_running: - pass - if self.debugger.is_finished: + breakpoint_timeout = Timeout(self.context.options.timeout_breakpoint) + while self.debugger.is_running and not timed_out: + # Check to see whether we've timed out while we're waiting. + if total_timeout.timed_out(): + self.context.logger.error('Debugger session has been ' + f'running for {total_timeout.elapsed}s, timeout reached!') + timed_out = True + if breakpoint_timeout.timed_out(): + self.context.logger.error(f'Debugger session has not ' + f'hit a breakpoint for {breakpoint_timeout.elapsed}s, timeout ' + 'reached!') + timed_out = True + + if timed_out or self.debugger.is_finished: break self.step_index += 1 diff --git a/cross-project-tests/debuginfo-tests/dexter/dex/debugger/Debuggers.py b/cross-project-tests/debuginfo-tests/dexter/dex/debugger/Debuggers.py index 48cb7e1a0789..c85310b37a8f 100644 --- a/cross-project-tests/debuginfo-tests/dexter/dex/debugger/Debuggers.py +++ b/cross-project-tests/debuginfo-tests/dexter/dex/debugger/Debuggers.py @@ -121,7 +121,21 @@ def add_debugger_tool_arguments(parser, context, defaults): default='', help='command line arguments for the test program, in addition to any ' 'provided by DexCommandLine') - + parser.add_argument( + '--timeout-total', + metavar='<seconds>', + type=float, + default=0.0, + help='if >0, debugger session will automatically exit after ' + 'running for <timeout-total> seconds') + parser.add_argument( + '--timeout-breakpoint', + metavar='<seconds>', + type=float, + default=0.0, + help='if >0, debugger session will automatically exit after ' + 'waiting <timeout-breakpoint> seconds without hitting a ' + 'breakpoint') def handle_debugger_tool_base_options(context, defaults): # noqa options = context.options diff --git a/cross-project-tests/debuginfo-tests/dexter/dex/utils/Timeout.py b/cross-project-tests/debuginfo-tests/dexter/dex/utils/Timeout.py new file mode 100644 index 000000000000..d59d7d7693a6 --- /dev/null +++ b/cross-project-tests/debuginfo-tests/dexter/dex/utils/Timeout.py @@ -0,0 +1,31 @@ +# 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 +"""Utility class to check for timeouts. Timer starts when the object is initialized, +and can be checked by calling timed_out(). Passing a timeout value of 0.0 or less +means a timeout will never be triggered, i.e. timed_out() will always return False. +""" + +import time + +class Timeout(object): + + def __init__(self, duration: float): + self.start = self.now + self.duration = duration + + def timed_out(self): + if self.duration <= 0.0: + return False + return self.elapsed > self.duration + + @property + def elapsed(self): + return self.now - self.start + + @property + def now(self): + return time.time() |