Skip to content

[lldb-dap][NFC] Add Breakpoint struct to share common logic. #80753

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

Merged
merged 3 commits into from
Feb 13, 2024
Merged
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
76 changes: 76 additions & 0 deletions lldb/tools/lldb-dap/Breakpoint.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//===-- Breakpoint.cpp ----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "Breakpoint.h"
#include "DAP.h"
#include "JSONUtils.h"
#include "llvm/ADT/StringExtras.h"

using namespace lldb_dap;

void Breakpoint::SetCondition() { bp.SetCondition(condition.c_str()); }

void Breakpoint::SetHitCondition() {
uint64_t hitCount = 0;
if (llvm::to_integer(hitCondition, hitCount))
bp.SetIgnoreCount(hitCount - 1);
}

void Breakpoint::CreateJsonObject(llvm::json::Object &object) {
// Each breakpoint location is treated as a separate breakpoint for VS code.
// They don't have the notion of a single breakpoint with multiple locations.
if (!bp.IsValid())
return;
object.try_emplace("verified", bp.GetNumResolvedLocations() > 0);
object.try_emplace("id", bp.GetID());
// VS Code DAP doesn't currently allow one breakpoint to have multiple
// locations so we just report the first one. If we report all locations
// then the IDE starts showing the wrong line numbers and locations for
// other source file and line breakpoints in the same file.

// Below we search for the first resolved location in a breakpoint and report
// this as the breakpoint location since it will have a complete location
// that is at least loaded in the current process.
lldb::SBBreakpointLocation bp_loc;
const auto num_locs = bp.GetNumLocations();
for (size_t i = 0; i < num_locs; ++i) {
bp_loc = bp.GetLocationAtIndex(i);
if (bp_loc.IsResolved())
break;
}
// If not locations are resolved, use the first location.
if (!bp_loc.IsResolved())
bp_loc = bp.GetLocationAtIndex(0);
auto bp_addr = bp_loc.GetAddress();

if (bp_addr.IsValid()) {
std::string formatted_addr =
"0x" + llvm::utohexstr(bp_addr.GetLoadAddress(g_dap.target));
object.try_emplace("instructionReference", formatted_addr);
auto line_entry = bp_addr.GetLineEntry();
const auto line = line_entry.GetLine();
if (line != UINT32_MAX)
object.try_emplace("line", line);
const auto column = line_entry.GetColumn();
if (column != 0)
object.try_emplace("column", column);
object.try_emplace("source", CreateSource(line_entry));
}
}

bool Breakpoint::MatchesName(const char *name) { return bp.MatchesName(name); }

void Breakpoint::SetBreakpoint() {
// See comments in BreakpointBase::GetBreakpointLabel() for details of why
// we add a label to our breakpoints.
bp.AddName(GetBreakpointLabel());
if (!condition.empty())
SetCondition();
if (!hitCondition.empty())
SetHitCondition();
}
33 changes: 33 additions & 0 deletions lldb/tools/lldb-dap/Breakpoint.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//===-- Breakpoint.h --------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_TOOLS_LLDB_DAP_BREAKPOINT_H
#define LLDB_TOOLS_LLDB_DAP_BREAKPOINT_H

#include "BreakpointBase.h"

namespace lldb_dap {

struct Breakpoint : public BreakpointBase {
// The LLDB breakpoint associated wit this source breakpoint
lldb::SBBreakpoint bp;

Breakpoint() = default;
Breakpoint(const llvm::json::Object &obj) : BreakpointBase(obj){};
Breakpoint(lldb::SBBreakpoint bp) : bp(bp) {}

void SetCondition() override;
void SetHitCondition() override;
void CreateJsonObject(llvm::json::Object &object) override;

bool MatchesName(const char *name);
void SetBreakpoint();
};
} // namespace lldb_dap

#endif
Loading