1# DExTer : Debugging Experience Tester 2# ~~~~~~ ~ ~~ ~ ~~ 3# 4# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5# See https://llvm.org/LICENSE.txt for license information. 6# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7"""This is an internal subtool used to sandbox the communication with a 8debugger into a separate process so that any crashes inside the debugger will 9not bring down the entire DExTer tool. 10""" 11 12import pickle 13 14from dex.debugger import Debuggers 15from dex.tools import ToolBase 16from dex.utils import Timer 17from dex.utils.Exceptions import DebuggerException, Error 18from dex.utils.ReturnCode import ReturnCode 19 20 21class Tool(ToolBase): 22 def __init__(self, *args, **kwargs): 23 self.controller_path = None 24 self.debugger_controller = None 25 self.options = None 26 super(Tool, self).__init__(*args, **kwargs) 27 28 @property 29 def name(self): 30 return "DExTer run debugger internal" 31 32 def add_tool_arguments(self, parser, defaults): 33 parser.add_argument( 34 "controller_path", type=str, help="pickled debugger controller file" 35 ) 36 37 def handle_options(self, defaults): 38 with open(self.context.options.controller_path, "rb") as fp: 39 self.debugger_controller = pickle.load(fp) 40 self.controller_path = self.context.options.controller_path 41 self.context = self.debugger_controller.context 42 self.options = self.context.options 43 Timer.display = self.options.time_report 44 45 def raise_debugger_error(self, action, debugger): 46 msg = "<d>could not {} {}</> ({})\n".format( 47 action, debugger.name, debugger.loading_error 48 ) 49 if self.options.verbose: 50 msg = "{}\n {}".format(msg, " ".join(debugger.loading_error_trace)) 51 raise Error(msg) 52 53 def go(self) -> ReturnCode: 54 with Timer("loading debugger"): 55 debugger = Debuggers(self.context).load(self.options.debugger) 56 57 with Timer("running debugger"): 58 if not debugger.is_available: 59 self.raise_debugger_error("load", debugger) 60 61 self.debugger_controller.run_debugger(debugger) 62 63 if debugger.loading_error: 64 self.raise_debugger_error("run", debugger) 65 66 with open(self.controller_path, "wb") as fp: 67 pickle.dump(self.debugger_controller, fp) 68 return ReturnCode.OK 69