1//===-- Breakpoint.cpp ----------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "Breakpoint.h"
10#include "DAP.h"
11#include "JSONUtils.h"
12#include "llvm/ADT/StringExtras.h"
13
14using namespace lldb_dap;
15
16void Breakpoint::SetCondition() { bp.SetCondition(condition.c_str()); }
17
18void Breakpoint::SetHitCondition() {
19 uint64_t hitCount = 0;
20 if (llvm::to_integer(S: hitCondition, Num&: hitCount))
21 bp.SetIgnoreCount(hitCount - 1);
22}
23
24void Breakpoint::CreateJsonObject(llvm::json::Object &object) {
25 // Each breakpoint location is treated as a separate breakpoint for VS code.
26 // They don't have the notion of a single breakpoint with multiple locations.
27 if (!bp.IsValid())
28 return;
29 object.try_emplace(K: "verified", Args: bp.GetNumResolvedLocations() > 0);
30 object.try_emplace(K: "id", Args: bp.GetID());
31 // VS Code DAP doesn't currently allow one breakpoint to have multiple
32 // locations so we just report the first one. If we report all locations
33 // then the IDE starts showing the wrong line numbers and locations for
34 // other source file and line breakpoints in the same file.
35
36 // Below we search for the first resolved location in a breakpoint and report
37 // this as the breakpoint location since it will have a complete location
38 // that is at least loaded in the current process.
39 lldb::SBBreakpointLocation bp_loc;
40 const auto num_locs = bp.GetNumLocations();
41 for (size_t i = 0; i < num_locs; ++i) {
42 bp_loc = bp.GetLocationAtIndex(index: i);
43 if (bp_loc.IsResolved())
44 break;
45 }
46 // If not locations are resolved, use the first location.
47 if (!bp_loc.IsResolved())
48 bp_loc = bp.GetLocationAtIndex(index: 0);
49 auto bp_addr = bp_loc.GetAddress();
50
51 if (bp_addr.IsValid()) {
52 std::string formatted_addr =
53 "0x" + llvm::utohexstr(X: bp_addr.GetLoadAddress(target: g_dap.target));
54 object.try_emplace(K: "instructionReference", Args&: formatted_addr);
55 auto line_entry = bp_addr.GetLineEntry();
56 const auto line = line_entry.GetLine();
57 if (line != UINT32_MAX)
58 object.try_emplace(K: "line", Args: line);
59 const auto column = line_entry.GetColumn();
60 if (column != 0)
61 object.try_emplace(K: "column", Args: column);
62 object.try_emplace(K: "source", Args: CreateSource(line_entry));
63 }
64}
65
66bool Breakpoint::MatchesName(const char *name) { return bp.MatchesName(name); }
67
68void Breakpoint::SetBreakpoint() {
69 // See comments in BreakpointBase::GetBreakpointLabel() for details of why
70 // we add a label to our breakpoints.
71 bp.AddName(new_name: GetBreakpointLabel());
72 if (!condition.empty())
73 SetCondition();
74 if (!hitCondition.empty())
75 SetHitCondition();
76}
77

source code of lldb/tools/lldb-dap/Breakpoint.cpp