You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.7 KiB
104 lines
2.7 KiB
# 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
|
|
"""Classes which are used to represent debugger steps."""
|
|
|
|
import json
|
|
|
|
from collections import OrderedDict
|
|
from typing import List
|
|
from enum import Enum
|
|
from dex.dextIR.FrameIR import FrameIR
|
|
from dex.dextIR.LocIR import LocIR
|
|
from dex.dextIR.ProgramState import ProgramState
|
|
|
|
|
|
class StopReason(Enum):
|
|
BREAKPOINT = 0
|
|
STEP = 1
|
|
PROGRAM_EXIT = 2
|
|
ERROR = 3
|
|
OTHER = 4
|
|
|
|
|
|
class StepKind(Enum):
|
|
FUNC = 0
|
|
FUNC_EXTERNAL = 1
|
|
FUNC_UNKNOWN = 2
|
|
VERTICAL_FORWARD = 3
|
|
SAME = 4
|
|
VERTICAL_BACKWARD = 5
|
|
UNKNOWN = 6
|
|
HORIZONTAL_FORWARD = 7
|
|
HORIZONTAL_BACKWARD = 8
|
|
|
|
|
|
class StepIR:
|
|
"""A debugger step.
|
|
|
|
Args:
|
|
watches (OrderedDict): { expression (str), result (ValueIR) }
|
|
"""
|
|
|
|
def __init__(self,
|
|
step_index: int,
|
|
stop_reason: StopReason,
|
|
frames: List[FrameIR],
|
|
step_kind: StepKind = None,
|
|
watches: OrderedDict = None,
|
|
program_state: ProgramState = None):
|
|
self.step_index = step_index
|
|
self.step_kind = step_kind
|
|
self.stop_reason = stop_reason
|
|
self.program_state = program_state
|
|
|
|
if frames is None:
|
|
frames = []
|
|
self.frames = frames
|
|
|
|
if watches is None:
|
|
watches = {}
|
|
self.watches = watches
|
|
|
|
def __str__(self):
|
|
try:
|
|
frame = self.current_frame
|
|
frame_info = (frame.function, frame.loc.path, frame.loc.lineno,
|
|
frame.loc.column)
|
|
except AttributeError:
|
|
frame_info = (None, None, None, None)
|
|
|
|
step_info = (self.step_index, ) + frame_info + (
|
|
str(self.stop_reason), str(self.step_kind),
|
|
[w for w in self.watches])
|
|
|
|
return '{}{}'.format('. ' * (self.num_frames - 1),
|
|
json.dumps(step_info))
|
|
|
|
@property
|
|
def num_frames(self):
|
|
return len(self.frames)
|
|
|
|
@property
|
|
def current_frame(self):
|
|
if not len(self.frames):
|
|
return None
|
|
return self.frames[0]
|
|
|
|
@property
|
|
def current_function(self):
|
|
try:
|
|
return self.current_frame.function
|
|
except AttributeError:
|
|
return None
|
|
|
|
@property
|
|
def current_location(self):
|
|
try:
|
|
return self.current_frame.loc
|
|
except AttributeError:
|
|
return LocIR(path=None, lineno=None, column=None)
|