mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-28 02:16:06 +00:00

If a SetDataBreakpointsRequest contains a list data breakpoints which have duplicate starting addresses, the current behaviour is returning `{verified: true}` to both watchpoints with duplicated starting addresses. This confuses the client and what actually happens in lldb is the second one overwrite the first one. This fixes it by letting the last watchpoint at given address have `{verified: true}` and all previous watchpoints at the same address should have `{verfied: false}` at response.
52 lines
1.7 KiB
C++
52 lines
1.7 KiB
C++
//===-- Watchpoint.cpp ------------------------------------------*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "Watchpoint.h"
|
|
#include "DAP.h"
|
|
#include "JSONUtils.h"
|
|
#include "llvm/ADT/StringExtras.h"
|
|
|
|
namespace lldb_dap {
|
|
Watchpoint::Watchpoint(const llvm::json::Object &obj) : BreakpointBase(obj) {
|
|
llvm::StringRef dataId = GetString(obj, "dataId");
|
|
std::string accessType = GetString(obj, "accessType").str();
|
|
auto [addr_str, size_str] = dataId.split('/');
|
|
llvm::to_integer(addr_str, addr, 16);
|
|
llvm::to_integer(size_str, size);
|
|
options.SetWatchpointTypeRead(accessType != "write");
|
|
if (accessType != "read")
|
|
options.SetWatchpointTypeWrite(lldb::eWatchpointWriteTypeOnModify);
|
|
}
|
|
|
|
void Watchpoint::SetCondition() { wp.SetCondition(condition.c_str()); }
|
|
|
|
void Watchpoint::SetHitCondition() {
|
|
uint64_t hitCount = 0;
|
|
if (llvm::to_integer(hitCondition, hitCount))
|
|
wp.SetIgnoreCount(hitCount - 1);
|
|
}
|
|
|
|
void Watchpoint::CreateJsonObject(llvm::json::Object &object) {
|
|
if (!error.IsValid() || error.Fail()) {
|
|
object.try_emplace("verified", false);
|
|
if (error.Fail())
|
|
EmplaceSafeString(object, "message", error.GetCString());
|
|
} else {
|
|
object.try_emplace("verified", true);
|
|
}
|
|
}
|
|
|
|
void Watchpoint::SetWatchpoint() {
|
|
wp = g_dap.target.WatchpointCreateByAddress(addr, size, options, error);
|
|
if (!condition.empty())
|
|
SetCondition();
|
|
if (!hitCondition.empty())
|
|
SetHitCondition();
|
|
}
|
|
} // namespace lldb_dap
|