Skip to content

Commit ba5ff57

Browse files
authored
[Dexter] Track DAP capabilities (llvm#152715)
1 parent 2a49719 commit ba5ff57

File tree

1 file changed

+42
-0
lines changed
  • cross-project-tests/debuginfo-tests/dexter/dex/debugger

1 file changed

+42
-0
lines changed

cross-project-tests/debuginfo-tests/dexter/dex/debugger/DAP.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,36 @@ def write_message(self, message: dict, incoming: bool):
100100
)
101101

102102

103+
# Debuggers communicate optional feature support.
104+
class DAPDebuggerCapabilities:
105+
def __init__(self):
106+
self.supportsConfigurationDoneRequest: bool = False
107+
self.supportsFunctionBreakpoints: bool = False
108+
self.supportsConditionalBreakpoints: bool = False
109+
self.supportsHitConditionalBreakpoints: bool = False
110+
self.supportsEvaluateForHovers: bool = False
111+
self.supportsSetVariable: bool = False
112+
self.supportsStepInTargetsRequest: bool = False
113+
self.supportsModulesRequest: bool = False
114+
self.supportsValueFormattingOptions: bool = False
115+
self.supportsLogPoints: bool = False
116+
self.supportsSetExpression: bool = False
117+
self.supportsDataBreakpoints: bool = False
118+
self.supportsReadMemoryRequest: bool = False
119+
self.supportsWriteMemoryRequest: bool = False
120+
self.supportsDisassembleRequest: bool = False
121+
self.supportsCancelRequest: bool = False
122+
self.supportsSteppingGranularity: bool = False
123+
self.supportsInstructionBreakpoints: bool = False
124+
125+
def update(self, logger: Logger, feature_dict: dict):
126+
for k, v in feature_dict.items():
127+
if hasattr(self, k):
128+
setattr(self, k, v)
129+
else:
130+
logger.warning(f"DAP: Unknown support flag: {k}")
131+
132+
103133
# As DAP does not give us a trivially query-able process, we are responsible for maintaining our own state information,
104134
# including what breakpoints are currently set, and whether the debugger is running or stopped.
105135
# This class holds all state that is set based on events sent by the debug adapter; most responses are forwarded through
@@ -142,6 +172,9 @@ def __init__(self):
142172
# Map of DAP breakpoint IDs to resolved instruction addresses.
143173
self.bp_addr_map = {}
144174

175+
# DAP features supported by the debugger.
176+
self.capabilities = DAPDebuggerCapabilities()
177+
145178
def set_response(self, req_id: int, response: dict):
146179
if len(self.responses) > req_id:
147180
self.responses[req_id] = response
@@ -315,6 +348,9 @@ def _handle_message(
315348
and debugger_state.thread is None
316349
):
317350
debugger_state.thread = event_details["threadId"]
351+
elif event_type == "capabilities":
352+
# Unchanged capabilites may not be included.
353+
debugger_state.capabilities.update(logger, event_details)
318354
# There are many events we do not care about, just skip processing them.
319355
else:
320356
pass
@@ -338,6 +374,12 @@ def _handle_message(
338374
debugger_state.frame_map = [
339375
stackframe["id"] for stackframe in message["body"]["stackFrames"]
340376
]
377+
# The debugger communicates which optional DAP features are
378+
# supported in its initalize response.
379+
if message["command"] == "initialize" and message["success"] == True:
380+
body = message.get("body")
381+
if body:
382+
debugger_state.capabilities.update(logger, body)
341383

342384
def _colorize_dap_message(message: dict) -> dict:
343385
colorized_message = copy.deepcopy(message)

0 commit comments

Comments
 (0)