| # 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 |
| """This is an internal subtool used to sandbox the communication with a |
| debugger into a separate process so that any crashes inside the debugger will |
| not bring down the entire DExTer tool. |
| """ |
| |
| import pickle |
| |
| from dex.debugger import Debuggers |
| from dex.tools import ToolBase |
| from dex.utils import Timer |
| from dex.utils.Exceptions import DebuggerException, Error |
| from dex.utils.ReturnCode import ReturnCode |
| |
| class Tool(ToolBase): |
| def __init__(self, *args, **kwargs): |
| self.controller_path = None |
| self.debugger_controller = None |
| self.options = None |
| super(Tool, self).__init__(*args, **kwargs) |
| |
| @property |
| def name(self): |
| return 'DExTer run debugger internal' |
| |
| def add_tool_arguments(self, parser, defaults): |
| parser.add_argument( |
| 'controller_path', |
| type=str, |
| help='pickled debugger controller file') |
| |
| def handle_options(self, defaults): |
| with open(self.context.options.controller_path, 'rb') as fp: |
| self.debugger_controller = pickle.load(fp) |
| self.controller_path = self.context.options.controller_path |
| self.context = self.debugger_controller.context |
| self.options = self.context.options |
| Timer.display = self.options.time_report |
| |
| def go(self) -> ReturnCode: |
| with Timer('loading debugger'): |
| debugger = Debuggers(self.context).load(self.options.debugger) |
| |
| with Timer('running debugger'): |
| if not debugger.is_available: |
| msg = '<d>could not load {}</> ({})\n'.format( |
| debugger.name, debugger.loading_error) |
| if self.options.verbose: |
| msg = '{}\n {}'.format( |
| msg, ' '.join(debugger.loading_error_trace)) |
| raise Error(msg) |
| |
| self.debugger_controller.run_debugger(debugger) |
| |
| with open(self.controller_path, 'wb') as fp: |
| pickle.dump(self.debugger_controller, fp) |
| return ReturnCode.OK |