Skip to content

Commit f73eb33

Browse files
committed
[Dexter] Track DAP capabilities
1 parent 4e63f5e commit f73eb33

File tree

1 file changed

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

1 file changed

+41
-0
lines changed

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,35 @@ def write_message(self, message: dict, incoming: bool):
102102
)
103103

104104

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

176+
# DAP features supported by the debugger.
177+
self.capabilities = DAPDebuggerCapabilities()
178+
147179
def set_response(self, req_id: int, response: dict):
148180
if len(self.responses) > req_id:
149181
self.responses[req_id] = response
@@ -320,6 +352,9 @@ def _handle_message(
320352
and debugger_state.thread is None
321353
):
322354
debugger_state.thread = event_details["threadId"]
355+
case "capabilities":
356+
# Unchanged capabilites may not be included.
357+
debugger_state.capabilities.update(logger, event_details)
323358
# There are many events we do not care about, just skip processing them.
324359
case _:
325360
pass
@@ -343,6 +378,12 @@ def _handle_message(
343378
debugger_state.frame_map = [
344379
stackframe["id"] for stackframe in message["body"]["stackFrames"]
345380
]
381+
# The debugger communicates which optional DAP features are
382+
# supported in its initalize response.
383+
if message["command"] == "initialize" and message["success"] == True:
384+
body = message.get("body")
385+
if body:
386+
debugger_state.capabilities.update(logger, body)
346387

347388
def _colorize_dap_message(message: dict) -> dict:
348389
colorized_message = copy.deepcopy(message)

0 commit comments

Comments
 (0)