Skip to content

Commit aa90036

Browse files
committed
Make breakpoint stop reason more accurate
1 parent 7af0265 commit aa90036

File tree

4 files changed

+36
-66
lines changed

4 files changed

+36
-66
lines changed

lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -174,17 +174,19 @@ def test_functionality(self):
174174

175175
@skipIfWindows
176176
def test_breakpoint_reason(self):
177-
"""Tests setting data breakpoints on variable. Verify that the breakpoint has the correct reason and description in the stopped event."""
177+
"""Tests setting data breakpoints on variable.
178+
Verify that the breakpoint has the correct reason
179+
and description in the stopped event."""
178180
program = self.getBuildArtifact("a.out")
179181
self.build_and_launch(program)
180182
source = "main.cpp"
181183
first_loop_break_line = line_number(source, "// first loop breakpoint")
182184
self.set_source_breakpoints(source, [first_loop_break_line])
183185
self.continue_to_next_stop()
184186
self.dap_server.get_local_variables()
185-
# Test write watchpoints on x, arr[2]
187+
# Test write watchpoints on x
186188
response_x = self.dap_server.request_dataBreakpointInfo(1, "x")
187-
# Test response from dataBreakpointInfo request.
189+
# Test response from dataBreakpointInfo request.
188190
self.assertEqual(response_x["body"]["dataId"].split("/")[1], "4")
189191
self.assertEqual(response_x["body"]["accessTypes"], self.accessTypes)
190192
dataBreakpoints = [

lldb/tools/lldb-dap/DAP.cpp

-28
Original file line numberDiff line numberDiff line change
@@ -1014,34 +1014,6 @@ void DAP::SetThreadFormat(llvm::StringRef format) {
10141014
}
10151015
}
10161016

1017-
InstructionBreakpoint *
1018-
DAP::GetInstructionBreakpoint(const lldb::break_id_t bp_id) {
1019-
for (auto &bp : instruction_breakpoints) {
1020-
if (bp.second.bp.GetID() == bp_id)
1021-
return &bp.second;
1022-
}
1023-
return nullptr;
1024-
}
1025-
1026-
InstructionBreakpoint *
1027-
DAP::GetInstructionBPFromStopReason(lldb::SBThread &thread) {
1028-
const auto num = thread.GetStopReasonDataCount();
1029-
InstructionBreakpoint *inst_bp = nullptr;
1030-
for (size_t i = 0; i < num; i += 2) {
1031-
// thread.GetStopReasonDataAtIndex(i) will return the bp ID and
1032-
// thread.GetStopReasonDataAtIndex(i+1) will return the location
1033-
// within that breakpoint. We only care about the bp ID so we can
1034-
// see if this is an instruction breakpoint that is getting hit.
1035-
lldb::break_id_t bp_id = thread.GetStopReasonDataAtIndex(i);
1036-
inst_bp = GetInstructionBreakpoint(bp_id);
1037-
// If any breakpoint is not an instruction breakpoint, then stop and
1038-
// report this as a normal breakpoint
1039-
if (inst_bp == nullptr)
1040-
return nullptr;
1041-
}
1042-
return inst_bp;
1043-
}
1044-
10451017
lldb::SBValueList *Variables::GetTopLevelScope(int64_t variablesReference) {
10461018
switch (variablesReference) {
10471019
case VARREF_LOCALS:

lldb/tools/lldb-dap/DAP.h

+24-32
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,6 @@ struct DAP {
233233
/// @}
234234

235235
ExceptionBreakpoint *GetExceptionBreakpoint(const std::string &filter);
236-
ExceptionBreakpoint *GetExceptionBreakpoint(const lldb::break_id_t bp_id);
237236

238237
/// Redirect stdout and stderr fo the IDE's console output.
239238
///
@@ -392,11 +391,20 @@ struct DAP {
392391

393392
void SetThreadFormat(llvm::StringRef format);
394393

394+
// Check to see if we have hit the <BreakpointType> breakpoint and return the
395+
// last breakpoint. but only do so if all breakpoints that were hit are of
396+
// <BreakpointType>.
397+
// Caller uses this to set the reason accordingly. i.e. If all the breakpoints
398+
// are exception breakpoints then reason is 'exception'; if all the
399+
// breakpoints are function breakpoints then reason is 'function breakpoint';
400+
// if all the breakpoints are instruction breakpoints then reason =
401+
// 'instruction breakpoint'; if there are combination of one more breakpoints,
402+
// then the reason will be 'breakpoint'.
395403
template <typename BreakpointType>
396404
BreakpointType *GetBreakpointFromStopReason(lldb::SBThread &thread) {
397-
// Check to see if have hit the <BreakpointType> breakpoint and change the
398-
// reason accordingly, but only do so if all breakpoints that were
399-
// hit are of <BreakpointType>.
405+
// Check to see if we have hit the <BreakpointType> breakpoint and change
406+
// the reason accordingly, but only do so if all breakpoints that were hit
407+
// are of <BreakpointType>.
400408
const auto num = thread.GetStopReasonDataCount();
401409
BreakpointType *bp = nullptr;
402410
for (size_t i = 0; i < num; i += 2) {
@@ -416,47 +424,31 @@ struct DAP {
416424
template <>
417425
FunctionBreakpoint *
418426
GetBreakpoint<FunctionBreakpoint>(const lldb::break_id_t bp_id) {
419-
for (auto &bp : function_breakpoints) {
420-
if (bp.second.bp.GetID() == bp_id)
421-
return &bp.second;
422-
}
423-
return nullptr;
427+
auto it = std::find_if(
428+
function_breakpoints.begin(), function_breakpoints.end(),
429+
[bp_id](const auto &bp) { return bp.second.bp.GetID() == bp_id; });
430+
return it != function_breakpoints.end() ? &it->second : nullptr;
424431
}
425432

426433
template <>
427434
InstructionBreakpoint *
428435
GetBreakpoint<InstructionBreakpoint>(const lldb::break_id_t bp_id) {
429-
for (auto &bp : instruction_breakpoints) {
430-
if (bp.second.bp.GetID() == bp_id)
431-
return &bp.second;
432-
}
433-
return nullptr;
436+
auto it = std::find_if(
437+
instruction_breakpoints.begin(), instruction_breakpoints.end(),
438+
[bp_id](const auto &bp) { return bp.second.bp.GetID() == bp_id; });
439+
return it != instruction_breakpoints.end() ? &it->second : nullptr;
434440
}
435441

436442
template <>
437443
ExceptionBreakpoint *
438444
GetBreakpoint<ExceptionBreakpoint>(const lldb::break_id_t bp_id) {
439-
// See comment in the other GetExceptionBreakpoint().
440445
PopulateExceptionBreakpoints();
441446

442-
for (auto &bp : *exception_breakpoints) {
443-
if (bp.bp.GetID() == bp_id)
444-
return &bp;
445-
}
446-
return nullptr;
447+
auto it = std::find_if(
448+
exception_breakpoints->begin(), exception_breakpoints->end(),
449+
[bp_id](const auto &bp) { return bp.bp.GetID() == bp_id; });
450+
return it != exception_breakpoints->end() ? &*it : nullptr;
447451
}
448-
449-
FunctionBreakpoint *GetFunctionBPFromStopReason(lldb::SBThread &thread);
450-
451-
FunctionBreakpoint *GetFunctionBreakPoint(const lldb::break_id_t bp_id);
452-
453-
void WaitWorkerThreadsToExit();
454-
455-
private:
456-
// Send the JSON in "json_str" to the "out" stream. Correctly send the
457-
// "Content-Length:" field followed by the length, followed by the raw
458-
// JSON bytes.
459-
void SendJSON(const std::string &json_str);
460452
};
461453

462454
} // namespace lldb_dap

lldb/tools/lldb-dap/JSONUtils.cpp

+7-3
Original file line numberDiff line numberDiff line change
@@ -962,19 +962,21 @@ llvm::json::Value CreateThreadStopped(DAP &dap, lldb::SBThread &thread,
962962
body.try_emplace("reason", "step");
963963
break;
964964
case lldb::eStopReasonBreakpoint: {
965-
ExceptionBreakpoint *exc_bp =
965+
// Setting the reason as per DAP protocol spec.
966+
// https://microsoft.github.io/debug-adapter-protocol/specification#Events_Stopped
967+
const auto *exc_bp =
966968
dap.GetBreakpointFromStopReason<ExceptionBreakpoint>(thread);
967969
if (exc_bp) {
968970
body.try_emplace("reason", "exception");
969971
EmplaceSafeString(body, "description", exc_bp->label);
970972
} else {
971973
llvm::StringRef reason = "breakpoint";
972-
InstructionBreakpoint *inst_bp =
974+
const auto *inst_bp =
973975
dap.GetBreakpointFromStopReason<InstructionBreakpoint>(thread);
974976
if (inst_bp) {
975977
reason = "instruction breakpoint";
976978
} else {
977-
FunctionBreakpoint *function_bp =
979+
const auto *function_bp =
978980
dap.GetBreakpointFromStopReason<FunctionBreakpoint>(thread);
979981
if (function_bp) {
980982
reason = "function breakpoint";
@@ -992,6 +994,8 @@ llvm::json::Value CreateThreadStopped(DAP &dap, lldb::SBThread &thread,
992994
} break;
993995
case lldb::eStopReasonWatchpoint: {
994996
// Assuming that all watch points are data breakpoints.
997+
// data breakpoints are DAP terminology for watchpoints.
998+
// https://microsoft.github.io/debug-adapter-protocol/specification#Requests_SetDataBreakpoints
995999
body.try_emplace("reason", "data breakpoint");
9961000
lldb::break_id_t bp_id = thread.GetStopReasonDataAtIndex(0);
9971001
lldb::break_id_t bp_loc_id = thread.GetStopReasonDataAtIndex(1);

0 commit comments

Comments
 (0)