Skip to content

[lldb-dap] Allow returning multiple breakpoints in "stopped" event #149133

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,28 @@ def verify_breakpoint_hit(self, breakpoint_ids, timeout=DEFAULT_TIMEOUT):
return
self.assertTrue(False, f"breakpoint not hit, stopped_events={stopped_events}")

def verify_all_breakpoints_hit(self, breakpoint_ids, timeout=DEFAULT_TIMEOUT):
"""Wait for the process we are debugging to stop, and verify we hit
all of the breakpoint locations in the "breakpoint_ids" array.
"breakpoint_ids" should be a list of int breakpoint IDs ([1, 2])."""
stopped_events = self.dap_server.wait_for_stopped(timeout)
for stopped_event in stopped_events:
if "body" in stopped_event:
body = stopped_event["body"]
if "reason" not in body:
continue
if (
body["reason"] != "breakpoint"
and body["reason"] != "instruction breakpoint"
):
continue
if "hitBreakpointIds" not in body:
continue
hit_bps = body["hitBreakpointIds"]
if all(breakpoint_id in hit_bps for breakpoint_id in breakpoint_ids):
return
self.assertTrue(False, f"breakpoints not hit, stopped_events={stopped_events}")

def verify_stop_exception_info(self, expected_description, timeout=DEFAULT_TIMEOUT):
"""Wait for the process we are debugging to stop, and verify the stop
reason is 'exception' and that the description matches
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -398,3 +398,26 @@ def test_column_breakpoints(self):
self.stepIn()
func_name = self.get_stackFrames()[0]["name"]
self.assertEqual(func_name, "a::fourteen(int)")

@skipIfWindows
def test_hit_multiple_breakpoints(self):
"""Test that if we hit multiple breakpoints at the same address, they
all appear in the stop reason."""
breakpoint_lines = [
line_number("main.cpp", "// break non-breakpointable line"),
line_number("main.cpp", "// before loop"),
]

program = self.getBuildArtifact("a.out")
self.build_and_launch(program)

# Set a pair of breakpoints that will both resolve to the same address.
breakpoint_ids = [
int(bp_id)
for bp_id in self.set_source_breakpoints(self.main_path, breakpoint_lines)
]
self.assertEqual(len(breakpoint_ids), 2, "expected two breakpoints")
self.dap_server.request_continue()
print(breakpoint_ids)
# Verify we hit both of the breakpoints we just set
self.verify_all_breakpoints_hit(breakpoint_ids)
2 changes: 1 addition & 1 deletion lldb/test/API/tools/lldb-dap/breakpoint/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ int main(int argc, char const *argv[]) {
if (foo == nullptr) {
fprintf(stderr, "%s\n", dlerror());
exit(2);
}
} // break non-breakpointable line
foo(12); // before loop

for (int i = 0; i < 10; ++i) {
Expand Down
17 changes: 11 additions & 6 deletions lldb/tools/lldb-dap/JSONUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -654,12 +654,17 @@ llvm::json::Value CreateThreadStopped(DAP &dap, lldb::SBThread &thread,
} else {
body.try_emplace("reason", "breakpoint");
}
lldb::break_id_t bp_id = thread.GetStopReasonDataAtIndex(0);
lldb::break_id_t bp_loc_id = thread.GetStopReasonDataAtIndex(1);
std::string desc_str =
llvm::formatv("breakpoint {0}.{1}", bp_id, bp_loc_id);
body.try_emplace("hitBreakpointIds",
llvm::json::Array{llvm::json::Value(bp_id)});
std::vector<lldb::break_id_t> bp_ids;
std::ostringstream desc_sstream;
desc_sstream << "breakpoint";
for (size_t idx = 0; idx < thread.GetStopReasonDataCount(); idx += 2) {
lldb::break_id_t bp_id = thread.GetStopReasonDataAtIndex(idx);
lldb::break_id_t bp_loc_id = thread.GetStopReasonDataAtIndex(idx + 1);
bp_ids.push_back(bp_id);
desc_sstream << " " << bp_id << "." << bp_loc_id;
}
std::string desc_str = desc_sstream.str();
body.try_emplace("hitBreakpointIds", llvm::json::Array(bp_ids));
EmplaceSafeString(body, "description", desc_str);
}
} break;
Expand Down
Loading