• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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"""Classes which are used to represent debugger steps."""
8
9import json
10
11from collections import OrderedDict
12from typing import List
13from enum import Enum
14from dex.dextIR.FrameIR import FrameIR
15from dex.dextIR.LocIR import LocIR
16from dex.dextIR.ProgramState import ProgramState
17
18
19class StopReason(Enum):
20    BREAKPOINT = 0
21    STEP = 1
22    PROGRAM_EXIT = 2
23    ERROR = 3
24    OTHER = 4
25
26
27class StepKind(Enum):
28    FUNC = 0
29    FUNC_EXTERNAL = 1
30    FUNC_UNKNOWN = 2
31    VERTICAL_FORWARD = 3
32    SAME = 4
33    VERTICAL_BACKWARD = 5
34    UNKNOWN = 6
35    HORIZONTAL_FORWARD = 7
36    HORIZONTAL_BACKWARD = 8
37
38
39class StepIR:
40    """A debugger step.
41
42    Args:
43        watches (OrderedDict): { expression (str), result (ValueIR) }
44    """
45
46    def __init__(self,
47                 step_index: int,
48                 stop_reason: StopReason,
49                 frames: List[FrameIR],
50                 step_kind: StepKind = None,
51                 watches: OrderedDict = None,
52                 program_state: ProgramState = None):
53        self.step_index = step_index
54        self.step_kind = step_kind
55        self.stop_reason = stop_reason
56        self.program_state = program_state
57
58        if frames is None:
59            frames = []
60        self.frames = frames
61
62        if watches is None:
63            watches = {}
64        self.watches = watches
65
66    def __str__(self):
67        try:
68            frame = self.current_frame
69            frame_info = (frame.function, frame.loc.path, frame.loc.lineno,
70                          frame.loc.column)
71        except AttributeError:
72            frame_info = (None, None, None, None)
73
74        step_info = (self.step_index, ) + frame_info + (
75            str(self.stop_reason), str(self.step_kind),
76                                    [w for w in self.watches])
77
78        return '{}{}'.format('.   ' * (self.num_frames - 1),
79                             json.dumps(step_info))
80
81    @property
82    def num_frames(self):
83        return len(self.frames)
84
85    @property
86    def current_frame(self):
87        if not len(self.frames):
88            return None
89        return self.frames[0]
90
91    @property
92    def current_function(self):
93        try:
94            return self.current_frame.function
95        except AttributeError:
96            return None
97
98    @property
99    def current_location(self):
100        try:
101            return self.current_frame.loc
102        except AttributeError:
103            return LocIR(path=None, lineno=None, column=None)
104