149 lines · python
1# DExTer : Debugging Experience Tester2# ~~~~~~ ~ ~~ ~ ~~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-exception7from collections import OrderedDict8import os9from typing import List10 11from dex.dextIR.DebuggerIR import DebuggerIR12from dex.dextIR.StepIR import StepIR, StepKind13 14 15def _step_kind_func(context, step):16 if step.current_location.path is None or not os.path.exists(17 step.current_location.path18 ):19 return StepKind.FUNC_UNKNOWN20 21 if any(22 os.path.samefile(step.current_location.path, f)23 for f in context.options.source_files24 ):25 return StepKind.FUNC26 27 return StepKind.FUNC_EXTERNAL28 29 30class DextIR:31 """A full Dexter test report.32 33 This is composed of all the other *IR classes. They are used together to34 record Dexter inputs and the resultant debugger steps, providing a single35 high level access container.36 37 The Heuristic class works with dexter commands and the generated DextIR to38 determine the debugging score for a given test.39 40 Args:41 commands: { name (str), commands (list[CommandIR])42 """43 44 def __init__(45 self,46 dexter_version: str,47 executable_path: str,48 source_paths: List[str],49 debugger: DebuggerIR = None,50 commands: OrderedDict = None,51 ):52 self.dexter_version = dexter_version53 self.executable_path = executable_path54 self.source_paths = source_paths55 self.debugger = debugger56 self.commands = commands57 self.steps: List[StepIR] = []58 59 def __str__(self):60 colors = "rgby"61 st = "## BEGIN ##\n"62 color_idx = 063 for step in self.steps:64 if step.step_kind in (65 StepKind.FUNC,66 StepKind.FUNC_EXTERNAL,67 StepKind.FUNC_UNKNOWN,68 ):69 color_idx += 170 71 color = colors[color_idx % len(colors)]72 st += "<{}>{}</>\n".format(color, step)73 st += "## END ({} step{}) ##\n".format(74 self.num_steps, "" if self.num_steps == 1 else "s"75 )76 return st77 78 @property79 def num_steps(self):80 return len(self.steps)81 82 def _get_prev_step_in_this_frame(self, step):83 """Find the most recent step in the same frame as `step`.84 85 Returns:86 StepIR or None if there is no previous step in this frame.87 """88 return next(89 (90 s91 for s in reversed(self.steps)92 if s.current_function == step.current_function93 and s.num_frames == step.num_frames94 ),95 None,96 )97 98 def _get_new_step_kind(self, context, step):99 if step.current_function is None:100 return StepKind.UNKNOWN101 102 if len(self.steps) == 0:103 return _step_kind_func(context, step)104 105 prev_step = self.steps[-1]106 107 if prev_step.current_function is None:108 return StepKind.UNKNOWN109 110 if prev_step.num_frames < step.num_frames:111 return _step_kind_func(context, step)112 113 if prev_step.num_frames > step.num_frames:114 frame_step = self._get_prev_step_in_this_frame(step)115 prev_step = frame_step if frame_step is not None else prev_step116 117 # If we're missing line numbers to compare then the step kind has to be UNKNOWN.118 if (119 prev_step.current_location.lineno is None120 or step.current_location.lineno is None121 ):122 return StepKind.UNKNOWN123 124 # We're in the same func as prev step, check lineo.125 if prev_step.current_location.lineno > step.current_location.lineno:126 return StepKind.VERTICAL_BACKWARD127 128 if prev_step.current_location.lineno < step.current_location.lineno:129 return StepKind.VERTICAL_FORWARD130 131 # We're on the same line as prev step, check column.132 if prev_step.current_location.column > step.current_location.column:133 return StepKind.HORIZONTAL_BACKWARD134 135 if prev_step.current_location.column < step.current_location.column:136 return StepKind.HORIZONTAL_FORWARD137 138 # This step is in exactly the same location as the prev step.139 return StepKind.SAME140 141 def new_step(self, context, step):142 assert isinstance(step, StepIR), type(step)143 step.step_kind = self._get_new_step_kind(context, step)144 self.steps.append(step)145 return step146 147 def clear_steps(self):148 self.steps.clear()149