[llvm] [Dexter] Add DAP instruction and function breakpoint handling (PR #152718)
Stephen Tozer via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 27 03:07:09 PDT 2025
================
@@ -524,45 +550,98 @@ def clear_breakpoints(self):
def _add_breakpoint(self, file, line):
return self._add_conditional_breakpoint(file, line, None)
+ def add_function_breakpoint(self, name: str):
+ if not self._debugger_state.capabilities.supportsFunctionBreakpoints:
+ raise DebuggerException("Debugger does not support function breakpoints")
+ new_id = self.get_next_bp_id()
+ self.function_bp_info[new_id] = name
+ self.pending_function_breakpoints = True
+ return new_id
+
+ def add_instruction_breakpoint(self, addr: str):
+ if not self._debugger_state.capabilities.supportsInstructionBreakpoints:
+ raise DebuggerException("Debugger does not support instruction breakpoints")
+ new_id = self.get_next_bp_id()
+ self.instruction_bp_info[new_id] = addr
+ self.pending_instruction_breakpoints = True
+ return new_id
+
def _add_conditional_breakpoint(self, file, line, condition):
new_id = self.get_next_bp_id()
self.file_to_bp[file].append(new_id)
self.bp_info[new_id] = (file, line, condition)
self.pending_breakpoints = True
return new_id
+ def _update_breakpoint_ids_after_request(
+ self, dex_bp_ids: list, response: dict
+ ):
+ dap_bp_ids = [bp["id"] for bp in response["body"]["breakpoints"]]
+ if len(dex_bp_ids) != len(dap_bp_ids):
+ self.context.logger.error(
+ f"Sent request to set {len(dex_bp_ids)} breakpoints, but received {len(dap_bp_ids)} in response."
+ )
+ visited_dap_ids = set()
+ for i, dex_bp_id in enumerate(dex_bp_ids):
+ dap_bp_id = dap_bp_ids[i]
+ self.dex_id_to_dap_id[dex_bp_id] = dap_bp_id
+ # We take the mappings in the response as the canonical mapping, meaning that if the debug server has
+ # simply *changed* the DAP ID for a breakpoint we overwrite the existing mapping rather than adding to
+ # it, but if we receive the same DAP ID for multiple Dex IDs *then* we store a one-to-many mapping.
+ if dap_bp_id in visited_dap_ids:
+ self.dap_id_to_dex_ids[dap_bp_id].append(dex_bp_id)
+ else:
+ self.dap_id_to_dex_ids[dap_bp_id] = [dex_bp_id]
+ visited_dap_ids.add(dap_bp_id)
+
def _flush_breakpoints(self):
- if not self.pending_breakpoints:
- return
- for file in self.file_to_bp.keys():
- desired_bps = self._get_desired_bps(file)
+ # Normal and conditional breakpoints.
+ if self.pending_breakpoints:
+ self.pending_breakpoints = False
+ for file in self.file_to_bp.keys():
+ desired_bps = self._get_desired_bps(file)
+ request_id = self.send_message(
+ self.make_set_breakpoint_request(file, desired_bps)
+ )
+ result = self._await_response(request_id, 10)
+ if not result["success"]:
+ raise DebuggerException(f"could not set breakpoints for '{file}'")
+ # The debug adapter may have chosen to merge our breakpoints. From here we need to identify such cases and
+ # handle them so that our internal bookkeeping is correct.
+ dex_bp_ids = self.get_current_bps(file)
+ self._update_breakpoint_ids_after_request(dex_bp_ids, result)
+
+ # Funciton breakpoints.
----------------
SLTozer wrote:
```suggestion
# Function breakpoints.
```
https://github.com/llvm/llvm-project/pull/152718
More information about the llvm-commits
mailing list