aboutsummaryrefslogtreecommitdiff
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/API/SBThread.cpp4
-rw-r--r--lldb/source/API/SBWatchpoint.cpp4
-rw-r--r--lldb/source/Breakpoint/BreakpointLocation.cpp6
-rw-r--r--lldb/source/Breakpoint/BreakpointSite.cpp84
-rw-r--r--lldb/source/Breakpoint/BreakpointSiteList.cpp193
-rw-r--r--lldb/source/Breakpoint/CMakeLists.txt4
-rw-r--r--lldb/source/Breakpoint/StopPointSiteList.cpp37
-rw-r--r--lldb/source/Breakpoint/Watchpoint.cpp76
-rw-r--r--lldb/source/Breakpoint/WatchpointResource.cpp122
-rw-r--r--lldb/source/Breakpoint/WatchpointResourceList.cpp114
-rw-r--r--lldb/source/Commands/CommandObjectProcess.cpp4
-rw-r--r--lldb/source/Commands/CommandObjectWatchpoint.cpp8
-rw-r--r--lldb/source/Interpreter/OptionGroupWatchpoint.cpp43
-rw-r--r--lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp2
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp2
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp2
-rw-r--r--lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp2
-rw-r--r--lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp14
-rw-r--r--lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h7
-rw-r--r--lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp9
-rw-r--r--lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp38
-rw-r--r--lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h6
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp270
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h6
-rw-r--r--lldb/source/Target/Platform.cpp2
-rw-r--r--lldb/source/Target/Process.cpp60
-rw-r--r--lldb/source/Target/StackFrameList.cpp5
-rw-r--r--lldb/source/Target/StopInfo.cpp68
-rw-r--r--lldb/source/Target/Target.cpp31
-rw-r--r--lldb/source/Target/ThreadPlanCallFunction.cpp4
-rw-r--r--lldb/source/Target/ThreadPlanStepOut.cpp2
-rw-r--r--lldb/source/Target/ThreadPlanStepRange.cpp14
-rw-r--r--lldb/source/Target/ThreadPlanStepUntil.cpp4
33 files changed, 714 insertions, 533 deletions
diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp
index 18c086b..fa4c80e 100644
--- a/lldb/source/API/SBThread.cpp
+++ b/lldb/source/API/SBThread.cpp
@@ -181,7 +181,7 @@ size_t SBThread::GetStopReasonDataCount() {
exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
site_id));
if (bp_site_sp)
- return bp_site_sp->GetNumberOfOwners() * 2;
+ return bp_site_sp->GetNumberOfConstituents() * 2;
else
return 0; // Breakpoint must have cleared itself...
} break;
@@ -241,7 +241,7 @@ uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
if (bp_site_sp) {
uint32_t bp_index = idx / 2;
BreakpointLocationSP bp_loc_sp(
- bp_site_sp->GetOwnerAtIndex(bp_index));
+ bp_site_sp->GetConstituentAtIndex(bp_index));
if (bp_loc_sp) {
if (idx & 1) {
// Odd idx, return the breakpoint location ID
diff --git a/lldb/source/API/SBWatchpoint.cpp b/lldb/source/API/SBWatchpoint.cpp
index 8e60e6d..9664bbe 100644
--- a/lldb/source/API/SBWatchpoint.cpp
+++ b/lldb/source/API/SBWatchpoint.cpp
@@ -142,9 +142,9 @@ void SBWatchpoint::SetEnabled(bool enabled) {
const bool notify = true;
if (process_sp) {
if (enabled)
- process_sp->EnableWatchpoint(watchpoint_sp.get(), notify);
+ process_sp->EnableWatchpoint(watchpoint_sp, notify);
else
- process_sp->DisableWatchpoint(watchpoint_sp.get(), notify);
+ process_sp->DisableWatchpoint(watchpoint_sp, notify);
} else {
watchpoint_sp->SetEnabled(enabled, notify);
}
diff --git a/lldb/source/Breakpoint/BreakpointLocation.cpp b/lldb/source/Breakpoint/BreakpointLocation.cpp
index 931e1ad..99f94d0 100644
--- a/lldb/source/Breakpoint/BreakpointLocation.cpp
+++ b/lldb/source/Breakpoint/BreakpointLocation.cpp
@@ -473,10 +473,10 @@ bool BreakpointLocation::ClearBreakpointSite() {
// physical implementation of the breakpoint as well if there are no more
// owners. Otherwise just remove this owner.
if (process_sp)
- process_sp->RemoveOwnerFromBreakpointSite(GetBreakpoint().GetID(),
- GetID(), m_bp_site_sp);
+ process_sp->RemoveConstituentFromBreakpointSite(GetBreakpoint().GetID(),
+ GetID(), m_bp_site_sp);
else
- m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
+ m_bp_site_sp->RemoveConstituent(GetBreakpoint().GetID(), GetID());
m_bp_site_sp.reset();
return true;
diff --git a/lldb/source/Breakpoint/BreakpointSite.cpp b/lldb/source/Breakpoint/BreakpointSite.cpp
index 5187bc5..3ca93f9 100644
--- a/lldb/source/Breakpoint/BreakpointSite.cpp
+++ b/lldb/source/Breakpoint/BreakpointSite.cpp
@@ -12,14 +12,12 @@
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Breakpoint/BreakpointSiteList.h"
#include "lldb/Utility/Stream.h"
using namespace lldb;
using namespace lldb_private;
-BreakpointSite::BreakpointSite(BreakpointSiteList *list,
- const BreakpointLocationSP &owner,
+BreakpointSite::BreakpointSite(const BreakpointLocationSP &constituent,
lldb::addr_t addr, bool use_hardware)
: StoppointSite(GetNextID(), addr, 0, use_hardware),
m_type(eSoftware), // Process subclasses need to set this correctly using
@@ -28,14 +26,14 @@ BreakpointSite::BreakpointSite(BreakpointSiteList *list,
m_enabled(false) // Need to create it disabled, so the first enable turns
// it on.
{
- m_owners.Add(owner);
+ m_constituents.Add(constituent);
}
BreakpointSite::~BreakpointSite() {
BreakpointLocationSP bp_loc_sp;
- const size_t owner_count = m_owners.GetSize();
- for (size_t i = 0; i < owner_count; i++) {
- m_owners.GetByIndex(i)->ClearBreakpointSite();
+ const size_t constituent_count = m_constituents.GetSize();
+ for (size_t i = 0; i < constituent_count; i++) {
+ m_constituents.GetByIndex(i)->ClearBreakpointSite();
}
}
@@ -50,22 +48,22 @@ break_id_t BreakpointSite::GetNextID() {
bool BreakpointSite::ShouldStop(StoppointCallbackContext *context) {
m_hit_counter.Increment();
// ShouldStop can do a lot of work, and might even come back and hit
- // this breakpoint site again. So don't hold the m_owners_mutex the whole
- // while. Instead make a local copy of the collection and call ShouldStop on
- // the copy.
- BreakpointLocationCollection owners_copy;
+ // this breakpoint site again. So don't hold the m_constituents_mutex the
+ // whole while. Instead make a local copy of the collection and call
+ // ShouldStop on the copy.
+ BreakpointLocationCollection constituents_copy;
{
- std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
- owners_copy = m_owners;
+ std::lock_guard<std::recursive_mutex> guard(m_constituents_mutex);
+ constituents_copy = m_constituents;
}
- return owners_copy.ShouldStop(context);
+ return constituents_copy.ShouldStop(context);
}
bool BreakpointSite::IsBreakpointAtThisSite(lldb::break_id_t bp_id) {
- std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
- const size_t owner_count = m_owners.GetSize();
- for (size_t i = 0; i < owner_count; i++) {
- if (m_owners.GetByIndex(i)->GetBreakpoint().GetID() == bp_id)
+ std::lock_guard<std::recursive_mutex> guard(m_constituents_mutex);
+ const size_t constituent_count = m_constituents.GetSize();
+ for (size_t i = 0; i < constituent_count; i++) {
+ if (m_constituents.GetByIndex(i)->GetBreakpoint().GetID() == bp_id)
return true;
}
return false;
@@ -82,14 +80,14 @@ void BreakpointSite::Dump(Stream *s) const {
}
void BreakpointSite::GetDescription(Stream *s, lldb::DescriptionLevel level) {
- std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_constituents_mutex);
if (level != lldb::eDescriptionLevelBrief)
s->Printf("breakpoint site: %d at 0x%8.8" PRIx64, GetID(),
GetLoadAddress());
- m_owners.GetDescription(s, level);
+ m_constituents.GetDescription(s, level);
}
-bool BreakpointSite::IsInternal() const { return m_owners.IsInternal(); }
+bool BreakpointSite::IsInternal() const { return m_constituents.IsInternal(); }
uint8_t *BreakpointSite::GetTrapOpcodeBytes() { return &m_trap_opcode[0]; }
@@ -122,36 +120,36 @@ bool BreakpointSite::IsEnabled() const { return m_enabled; }
void BreakpointSite::SetEnabled(bool enabled) { m_enabled = enabled; }
-void BreakpointSite::AddOwner(const BreakpointLocationSP &owner) {
- std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
- m_owners.Add(owner);
+void BreakpointSite::AddConstituent(const BreakpointLocationSP &constituent) {
+ std::lock_guard<std::recursive_mutex> guard(m_constituents_mutex);
+ m_constituents.Add(constituent);
}
-size_t BreakpointSite::RemoveOwner(lldb::break_id_t break_id,
- lldb::break_id_t break_loc_id) {
- std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
- m_owners.Remove(break_id, break_loc_id);
- return m_owners.GetSize();
+size_t BreakpointSite::RemoveConstituent(lldb::break_id_t break_id,
+ lldb::break_id_t break_loc_id) {
+ std::lock_guard<std::recursive_mutex> guard(m_constituents_mutex);
+ m_constituents.Remove(break_id, break_loc_id);
+ return m_constituents.GetSize();
}
-size_t BreakpointSite::GetNumberOfOwners() {
- std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
- return m_owners.GetSize();
+size_t BreakpointSite::GetNumberOfConstituents() {
+ std::lock_guard<std::recursive_mutex> guard(m_constituents_mutex);
+ return m_constituents.GetSize();
}
-BreakpointLocationSP BreakpointSite::GetOwnerAtIndex(size_t index) {
- std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
- return m_owners.GetByIndex(index);
+BreakpointLocationSP BreakpointSite::GetConstituentAtIndex(size_t index) {
+ std::lock_guard<std::recursive_mutex> guard(m_constituents_mutex);
+ return m_constituents.GetByIndex(index);
}
bool BreakpointSite::ValidForThisThread(Thread &thread) {
- std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
- return m_owners.ValidForThisThread(thread);
+ std::lock_guard<std::recursive_mutex> guard(m_constituents_mutex);
+ return m_constituents.ValidForThisThread(thread);
}
void BreakpointSite::BumpHitCounts() {
- std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
- for (BreakpointLocationSP loc_sp : m_owners.BreakpointLocations()) {
+ std::lock_guard<std::recursive_mutex> guard(m_constituents_mutex);
+ for (BreakpointLocationSP loc_sp : m_constituents.BreakpointLocations()) {
loc_sp->BumpHitCount();
}
}
@@ -198,10 +196,10 @@ bool BreakpointSite::IntersectsRange(lldb::addr_t addr, size_t size,
return true;
}
-size_t
-BreakpointSite::CopyOwnersList(BreakpointLocationCollection &out_collection) {
- std::lock_guard<std::recursive_mutex> guard(m_owners_mutex);
- for (BreakpointLocationSP loc_sp : m_owners.BreakpointLocations()) {
+size_t BreakpointSite::CopyConstituentsList(
+ BreakpointLocationCollection &out_collection) {
+ std::lock_guard<std::recursive_mutex> guard(m_constituents_mutex);
+ for (BreakpointLocationSP loc_sp : m_constituents.BreakpointLocations()) {
out_collection.Add(loc_sp);
}
return out_collection.GetSize();
diff --git a/lldb/source/Breakpoint/BreakpointSiteList.cpp b/lldb/source/Breakpoint/BreakpointSiteList.cpp
deleted file mode 100644
index ab15da8..0000000
--- a/lldb/source/Breakpoint/BreakpointSiteList.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-//===-- BreakpointSiteList.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 "lldb/Breakpoint/BreakpointSiteList.h"
-
-#include "lldb/Utility/Stream.h"
-#include <algorithm>
-
-using namespace lldb;
-using namespace lldb_private;
-
-BreakpointSiteList::BreakpointSiteList() = default;
-
-BreakpointSiteList::~BreakpointSiteList() = default;
-
-// Add breakpoint site to the list. However, if the element already exists in
-// the list, then we don't add it, and return LLDB_INVALID_BREAK_ID.
-
-lldb::break_id_t BreakpointSiteList::Add(const BreakpointSiteSP &bp) {
- lldb::addr_t bp_site_load_addr = bp->GetLoadAddress();
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- collection::iterator iter = m_bp_site_list.find(bp_site_load_addr);
-
- if (iter == m_bp_site_list.end()) {
- m_bp_site_list.insert(iter, collection::value_type(bp_site_load_addr, bp));
- return bp->GetID();
- } else {
- return LLDB_INVALID_BREAK_ID;
- }
-}
-
-bool BreakpointSiteList::ShouldStop(StoppointCallbackContext *context,
- lldb::break_id_t site_id) {
- BreakpointSiteSP site_sp(FindByID(site_id));
- if (site_sp) {
- // Let the BreakpointSite decide if it should stop here (could not have
- // reached it's target hit count yet, or it could have a callback that
- // decided it shouldn't stop (shared library loads/unloads).
- return site_sp->ShouldStop(context);
- }
- // We should stop here since this BreakpointSite isn't valid anymore or it
- // doesn't exist.
- return true;
-}
-lldb::break_id_t BreakpointSiteList::FindIDByAddress(lldb::addr_t addr) {
- if (BreakpointSiteSP bp = FindByAddress(addr))
- return bp.get()->GetID();
- return LLDB_INVALID_BREAK_ID;
-}
-
-bool BreakpointSiteList::Remove(lldb::break_id_t break_id) {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- collection::iterator pos = GetIDIterator(break_id); // Predicate
- if (pos != m_bp_site_list.end()) {
- m_bp_site_list.erase(pos);
- return true;
- }
- return false;
-}
-
-bool BreakpointSiteList::RemoveByAddress(lldb::addr_t address) {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- collection::iterator pos = m_bp_site_list.find(address);
- if (pos != m_bp_site_list.end()) {
- m_bp_site_list.erase(pos);
- return true;
- }
- return false;
-}
-
-class BreakpointSiteIDMatches {
-public:
- BreakpointSiteIDMatches(lldb::break_id_t break_id) : m_break_id(break_id) {}
-
- bool operator()(std::pair<lldb::addr_t, BreakpointSiteSP> val_pair) const {
- return m_break_id == val_pair.second->GetID();
- }
-
-private:
- const lldb::break_id_t m_break_id;
-};
-
-BreakpointSiteList::collection::iterator
-BreakpointSiteList::GetIDIterator(lldb::break_id_t break_id) {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- return std::find_if(m_bp_site_list.begin(),
- m_bp_site_list.end(), // Search full range
- BreakpointSiteIDMatches(break_id)); // Predicate
-}
-
-BreakpointSiteList::collection::const_iterator
-BreakpointSiteList::GetIDConstIterator(lldb::break_id_t break_id) const {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- return std::find_if(m_bp_site_list.begin(),
- m_bp_site_list.end(), // Search full range
- BreakpointSiteIDMatches(break_id)); // Predicate
-}
-
-BreakpointSiteSP BreakpointSiteList::FindByID(lldb::break_id_t break_id) {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- BreakpointSiteSP stop_sp;
- collection::iterator pos = GetIDIterator(break_id);
- if (pos != m_bp_site_list.end())
- stop_sp = pos->second;
-
- return stop_sp;
-}
-
-const BreakpointSiteSP
-BreakpointSiteList::FindByID(lldb::break_id_t break_id) const {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- BreakpointSiteSP stop_sp;
- collection::const_iterator pos = GetIDConstIterator(break_id);
- if (pos != m_bp_site_list.end())
- stop_sp = pos->second;
-
- return stop_sp;
-}
-
-BreakpointSiteSP BreakpointSiteList::FindByAddress(lldb::addr_t addr) {
- BreakpointSiteSP found_sp;
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- collection::iterator iter = m_bp_site_list.find(addr);
- if (iter != m_bp_site_list.end())
- found_sp = iter->second;
- return found_sp;
-}
-
-bool BreakpointSiteList::BreakpointSiteContainsBreakpoint(
- lldb::break_id_t bp_site_id, lldb::break_id_t bp_id) {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- collection::const_iterator pos = GetIDConstIterator(bp_site_id);
- if (pos != m_bp_site_list.end())
- return pos->second->IsBreakpointAtThisSite(bp_id);
-
- return false;
-}
-
-void BreakpointSiteList::Dump(Stream *s) const {
- s->Printf("%p: ", static_cast<const void *>(this));
- // s->Indent();
- s->Printf("BreakpointSiteList with %u BreakpointSites:\n",
- (uint32_t)m_bp_site_list.size());
- s->IndentMore();
- collection::const_iterator pos;
- collection::const_iterator end = m_bp_site_list.end();
- for (pos = m_bp_site_list.begin(); pos != end; ++pos)
- pos->second->Dump(s);
- s->IndentLess();
-}
-
-void BreakpointSiteList::ForEach(
- std::function<void(BreakpointSite *)> const &callback) {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- for (auto pair : m_bp_site_list)
- callback(pair.second.get());
-}
-
-bool BreakpointSiteList::FindInRange(lldb::addr_t lower_bound,
- lldb::addr_t upper_bound,
- BreakpointSiteList &bp_site_list) const {
- if (lower_bound > upper_bound)
- return false;
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- collection::const_iterator lower, upper, pos;
- lower = m_bp_site_list.lower_bound(lower_bound);
- if (lower == m_bp_site_list.end() || (*lower).first >= upper_bound)
- return false;
-
- // This is one tricky bit. The breakpoint might overlap the bottom end of
- // the range. So we grab the breakpoint prior to the lower bound, and check
- // that that + its byte size isn't in our range.
- if (lower != m_bp_site_list.begin()) {
- collection::const_iterator prev_pos = lower;
- prev_pos--;
- const BreakpointSiteSP &prev_bp = (*prev_pos).second;
- if (prev_bp->GetLoadAddress() + prev_bp->GetByteSize() > lower_bound)
- bp_site_list.Add(prev_bp);
- }
-
- upper = m_bp_site_list.upper_bound(upper_bound);
-
- for (pos = lower; pos != upper; pos++) {
- bp_site_list.Add((*pos).second);
- }
- return true;
-}
diff --git a/lldb/source/Breakpoint/CMakeLists.txt b/lldb/source/Breakpoint/CMakeLists.txt
index 5c28023..42ac338 100644
--- a/lldb/source/Breakpoint/CMakeLists.txt
+++ b/lldb/source/Breakpoint/CMakeLists.txt
@@ -16,13 +16,15 @@ add_lldb_library(lldbBreakpoint NO_PLUGIN_DEPENDENCIES
BreakpointResolverName.cpp
BreakpointResolverScripted.cpp
BreakpointSite.cpp
- BreakpointSiteList.cpp
Stoppoint.cpp
StoppointCallbackContext.cpp
StoppointSite.cpp
+ StopPointSiteList.cpp
Watchpoint.cpp
WatchpointList.cpp
WatchpointOptions.cpp
+ WatchpointResource.cpp
+ WatchpointResourceList.cpp
LINK_LIBS
lldbCore
diff --git a/lldb/source/Breakpoint/StopPointSiteList.cpp b/lldb/source/Breakpoint/StopPointSiteList.cpp
new file mode 100644
index 0000000..275d0fb
--- /dev/null
+++ b/lldb/source/Breakpoint/StopPointSiteList.cpp
@@ -0,0 +1,37 @@
+//===-- StopPointSiteList.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 "lldb/Breakpoint/StopPointSiteList.h"
+#include "lldb/Breakpoint/BreakpointSite.h"
+#include "lldb/Breakpoint/WatchpointResource.h"
+
+#include "lldb/Utility/Stream.h"
+#include <algorithm>
+
+using namespace lldb;
+using namespace lldb_private;
+
+// This method is only defined when we're specializing for
+// BreakpointSite / BreakpointLocation / Breakpoint.
+// Watchpoints don't have a similar structure, they are
+// WatchpointResource / Watchpoint
+
+template <>
+bool StopPointSiteList<BreakpointSite>::StopPointSiteContainsBreakpoint(
+ typename BreakpointSite::SiteID site_id, lldb::break_id_t bp_id) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ typename collection::const_iterator pos = GetIDConstIterator(site_id);
+ if (pos != m_site_list.end())
+ return pos->second->IsBreakpointAtThisSite(bp_id);
+
+ return false;
+}
+
+namespace lldb_private {
+template class StopPointSiteList<BreakpointSite>;
+} // namespace lldb_private
diff --git a/lldb/source/Breakpoint/Watchpoint.cpp b/lldb/source/Breakpoint/Watchpoint.cpp
index b58455f..4602ce4 100644
--- a/lldb/source/Breakpoint/Watchpoint.cpp
+++ b/lldb/source/Breakpoint/Watchpoint.cpp
@@ -9,9 +9,11 @@
#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Breakpoint/WatchpointResource.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/DataFormatters/DumpValueObjectOptions.h"
#include "lldb/Expression/UserExpression.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/Process.h"
@@ -161,7 +163,7 @@ bool Watchpoint::VariableWatchpointDisabler(void *baton,
"callback for watchpoint %" PRId32
" matched internal breakpoint execution context",
watch_sp->GetID());
- process_sp->DisableWatchpoint(watch_sp.get());
+ process_sp->DisableWatchpoint(watch_sp);
return false;
}
LLDB_LOGF(log,
@@ -266,33 +268,69 @@ void Watchpoint::Dump(Stream *s) const {
// If prefix is nullptr, we display the watch id and ignore the prefix
// altogether.
-void Watchpoint::DumpSnapshots(Stream *s, const char *prefix) const {
- if (!prefix) {
- s->Printf("\nWatchpoint %u hit:", GetID());
- prefix = "";
- }
+bool Watchpoint::DumpSnapshots(Stream *s, const char *prefix) const {
+ bool printed_anything = false;
+
+ // For read watchpoints, don't display any before/after value changes.
+ if (m_watch_read && !m_watch_modify && !m_watch_write)
+ return printed_anything;
+
+ s->Printf("\n");
+ s->Printf("Watchpoint %u hit:\n", GetID());
+
+ StreamString values_ss;
+ if (prefix)
+ values_ss.Indent(prefix);
if (m_old_value_sp) {
- const char *old_value_cstr = m_old_value_sp->GetValueAsCString();
- if (old_value_cstr && old_value_cstr[0])
- s->Printf("\n%sold value: %s", prefix, old_value_cstr);
- else {
- const char *old_summary_cstr = m_old_value_sp->GetSummaryAsCString();
- if (old_summary_cstr && old_summary_cstr[0])
- s->Printf("\n%sold value: %s", prefix, old_summary_cstr);
+ if (auto *old_value_cstr = m_old_value_sp->GetValueAsCString()) {
+ values_ss.Printf("old value: %s", old_value_cstr);
+ } else {
+ if (auto *old_summary_cstr = m_old_value_sp->GetSummaryAsCString())
+ values_ss.Printf("old value: %s", old_summary_cstr);
+ else {
+ StreamString strm;
+ DumpValueObjectOptions options;
+ options.SetUseDynamicType(eNoDynamicValues)
+ .SetHideRootType(true)
+ .SetHideRootName(true)
+ .SetHideName(true);
+ m_old_value_sp->Dump(strm, options);
+ if (strm.GetData())
+ values_ss.Printf("old value: %s", strm.GetData());
+ }
}
}
if (m_new_value_sp) {
- const char *new_value_cstr = m_new_value_sp->GetValueAsCString();
- if (new_value_cstr && new_value_cstr[0])
- s->Printf("\n%snew value: %s", prefix, new_value_cstr);
+ if (values_ss.GetSize())
+ values_ss.Printf("\n");
+
+ if (auto *new_value_cstr = m_new_value_sp->GetValueAsCString())
+ values_ss.Printf("new value: %s", new_value_cstr);
else {
- const char *new_summary_cstr = m_new_value_sp->GetSummaryAsCString();
- if (new_summary_cstr && new_summary_cstr[0])
- s->Printf("\n%snew value: %s", prefix, new_summary_cstr);
+ if (auto *new_summary_cstr = m_new_value_sp->GetSummaryAsCString())
+ values_ss.Printf("new value: %s", new_summary_cstr);
+ else {
+ StreamString strm;
+ DumpValueObjectOptions options;
+ options.SetUseDynamicType(eNoDynamicValues)
+ .SetHideRootType(true)
+ .SetHideRootName(true)
+ .SetHideName(true);
+ m_new_value_sp->Dump(strm, options);
+ if (strm.GetData())
+ values_ss.Printf("new value: %s", strm.GetData());
+ }
}
}
+
+ if (values_ss.GetSize()) {
+ s->Printf("%s", values_ss.GetData());
+ printed_anything = true;
+ }
+
+ return printed_anything;
}
void Watchpoint::DumpWithLevel(Stream *s,
diff --git a/lldb/source/Breakpoint/WatchpointResource.cpp b/lldb/source/Breakpoint/WatchpointResource.cpp
new file mode 100644
index 0000000..4b8fbe4
--- /dev/null
+++ b/lldb/source/Breakpoint/WatchpointResource.cpp
@@ -0,0 +1,122 @@
+//===-- WatchpointResource.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 <assert.h>
+
+#include "lldb/Breakpoint/WatchpointResource.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+WatchpointResource::WatchpointResource(lldb::addr_t addr, size_t size,
+ bool read, bool write)
+ : m_id(GetNextID()), m_addr(addr), m_size(size),
+ m_watch_read(read), m_watch_write(write) {}
+
+WatchpointResource::~WatchpointResource() {
+ std::lock_guard<std::mutex> guard(m_constituents_mutex);
+ m_constituents.clear();
+}
+
+addr_t WatchpointResource::GetLoadAddress() const { return m_addr; }
+
+size_t WatchpointResource::GetByteSize() const { return m_size; }
+
+bool WatchpointResource::WatchpointResourceRead() const { return m_watch_read; }
+
+bool WatchpointResource::WatchpointResourceWrite() const {
+ return m_watch_write;
+}
+
+void WatchpointResource::SetType(bool read, bool write) {
+ m_watch_read = read;
+ m_watch_write = write;
+}
+
+wp_resource_id_t WatchpointResource::GetID() const { return m_id; }
+
+void WatchpointResource::SetID(wp_resource_id_t id) { m_id = id; }
+
+bool WatchpointResource::Contains(addr_t addr) {
+ if (addr >= m_addr && addr < m_addr + m_size)
+ return true;
+ return false;
+}
+
+void WatchpointResource::AddConstituent(const WatchpointSP &wp_sp) {
+ std::lock_guard<std::mutex> guard(m_constituents_mutex);
+ m_constituents.push_back(wp_sp);
+}
+
+void WatchpointResource::RemoveConstituent(WatchpointSP &wp_sp) {
+ std::lock_guard<std::mutex> guard(m_constituents_mutex);
+ const auto &it =
+ std::find(m_constituents.begin(), m_constituents.end(), wp_sp);
+ if (it != m_constituents.end())
+ m_constituents.erase(it);
+}
+
+size_t WatchpointResource::GetNumberOfConstituents() {
+ std::lock_guard<std::mutex> guard(m_constituents_mutex);
+ return m_constituents.size();
+}
+
+bool WatchpointResource::ConstituentsContains(const WatchpointSP &wp_sp) {
+ return ConstituentsContains(wp_sp.get());
+}
+
+bool WatchpointResource::ConstituentsContains(const Watchpoint *wp) {
+ std::lock_guard<std::mutex> guard(m_constituents_mutex);
+ WatchpointCollection::const_iterator match =
+ std::find_if(m_constituents.begin(), m_constituents.end(),
+ [&wp](const WatchpointSP &x) { return x.get() == wp; });
+ return match != m_constituents.end();
+}
+
+WatchpointSP WatchpointResource::GetConstituentAtIndex(size_t idx) {
+ std::lock_guard<std::mutex> guard(m_constituents_mutex);
+ assert(idx < m_constituents.size());
+ if (idx >= m_constituents.size())
+ return {};
+
+ return m_constituents[idx];
+}
+
+WatchpointResource::WatchpointCollection
+WatchpointResource::CopyConstituentsList() {
+ std::lock_guard<std::mutex> guard(m_constituents_mutex);
+ return m_constituents;
+}
+
+bool WatchpointResource::ShouldStop(StoppointCallbackContext *context) {
+ // LWP_TODO: Need to poll all Watchpoint constituents and see if
+ // we should stop, like BreakpointSites do.
+#if 0
+ m_hit_counter.Increment();
+ // ShouldStop can do a lot of work, and might even come back and hit
+ // this breakpoint site again. So don't hold the m_constituents_mutex the
+ // whole while. Instead make a local copy of the collection and call
+ // ShouldStop on the copy.
+ WatchpointResourceCollection constituents_copy;
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_constituents_mutex);
+ constituents_copy = m_constituents;
+ }
+ return constituents_copy.ShouldStop(context);
+#endif
+ return true;
+}
+
+void WatchpointResource::Dump(Stream *s) const {
+ return; // LWP_TODO
+}
+
+wp_resource_id_t WatchpointResource::GetNextID() {
+ static wp_resource_id_t g_next_id = 0;
+ return ++g_next_id;
+}
diff --git a/lldb/source/Breakpoint/WatchpointResourceList.cpp b/lldb/source/Breakpoint/WatchpointResourceList.cpp
new file mode 100644
index 0000000..d1d3648
--- /dev/null
+++ b/lldb/source/Breakpoint/WatchpointResourceList.cpp
@@ -0,0 +1,114 @@
+//===-- WatchpointResourceList.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 "lldb/Breakpoint/WatchpointResourceList.h"
+#include "lldb/Breakpoint/WatchpointResource.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+WatchpointResourceList::WatchpointResourceList() : m_resources(), m_mutex() {}
+
+WatchpointResourceList::~WatchpointResourceList() { Clear(); }
+
+wp_resource_id_t
+WatchpointResourceList::Add(const WatchpointResourceSP &wp_res_sp) {
+ Log *log = GetLog(LLDBLog::Watchpoints);
+ std::lock_guard<std::mutex> guard(m_mutex);
+ LLDB_LOGF(log, "WatchpointResourceList::Add(addr 0x%" PRIx64 " size %zu)",
+ wp_res_sp->GetLoadAddress(), wp_res_sp->GetByteSize());
+
+ m_resources.push_back(wp_res_sp);
+ return wp_res_sp->GetID();
+}
+
+bool WatchpointResourceList::Remove(wp_resource_id_t id) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ Log *log = GetLog(LLDBLog::Watchpoints);
+ for (collection::iterator pos = m_resources.begin(); pos != m_resources.end();
+ ++pos) {
+ if ((*pos)->GetID() == id) {
+ LLDB_LOGF(log,
+ "WatchpointResourceList::Remove(addr 0x%" PRIx64 " size %zu)",
+ (*pos)->GetLoadAddress(), (*pos)->GetByteSize());
+ m_resources.erase(pos);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool WatchpointResourceList::RemoveByAddress(addr_t addr) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ Log *log = GetLog(LLDBLog::Watchpoints);
+ for (collection::iterator pos = m_resources.begin(); pos != m_resources.end();
+ ++pos) {
+ if ((*pos)->Contains(addr)) {
+ LLDB_LOGF(log,
+ "WatchpointResourceList::RemoveByAddress(addr 0x%" PRIx64
+ " size %zu)",
+ (*pos)->GetLoadAddress(), (*pos)->GetByteSize());
+ m_resources.erase(pos);
+ return true;
+ }
+ }
+ return false;
+}
+
+WatchpointResourceSP WatchpointResourceList::FindByAddress(addr_t addr) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ for (WatchpointResourceSP wp_res_sp : m_resources)
+ if (wp_res_sp->Contains(addr))
+ return wp_res_sp;
+ return {};
+}
+
+WatchpointResourceSP
+WatchpointResourceList::FindByWatchpointSP(WatchpointSP &wp_sp) {
+ return FindByWatchpoint(wp_sp.get());
+}
+
+WatchpointResourceSP
+WatchpointResourceList::FindByWatchpoint(const Watchpoint *wp) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ for (WatchpointResourceSP wp_res_sp : m_resources)
+ if (wp_res_sp->ConstituentsContains(wp))
+ return wp_res_sp;
+ return {};
+}
+
+WatchpointResourceSP WatchpointResourceList::FindByID(wp_resource_id_t id) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ for (WatchpointResourceSP wp_res_sp : m_resources)
+ if (wp_res_sp->GetID() == id)
+ return wp_res_sp;
+ return {};
+}
+
+uint32_t WatchpointResourceList::GetSize() {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ return m_resources.size();
+}
+
+lldb::WatchpointResourceSP
+WatchpointResourceList::GetResourceAtIndex(uint32_t idx) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ if (idx < m_resources.size())
+ return m_resources[idx];
+
+ return {};
+}
+
+void WatchpointResourceList::Clear() {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ m_resources.clear();
+}
+
+std::mutex &WatchpointResourceList::GetMutex() { return m_mutex; }
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index e42d637..6dc7648f 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -519,10 +519,10 @@ protected:
BreakpointSiteSP bp_site_sp(
process->GetBreakpointSiteList().FindByID(bp_site_id));
if (bp_site_sp) {
- const size_t num_owners = bp_site_sp->GetNumberOfOwners();
+ const size_t num_owners = bp_site_sp->GetNumberOfConstituents();
for (size_t i = 0; i < num_owners; i++) {
Breakpoint &bp_ref =
- bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
+ bp_site_sp->GetConstituentAtIndex(i)->GetBreakpoint();
if (!bp_ref.IsInternal()) {
bp_ref.SetIgnoreCount(m_options.m_ignore);
}
diff --git a/lldb/source/Commands/CommandObjectWatchpoint.cpp b/lldb/source/Commands/CommandObjectWatchpoint.cpp
index cd1d226..c80868d 100644
--- a/lldb/source/Commands/CommandObjectWatchpoint.cpp
+++ b/lldb/source/Commands/CommandObjectWatchpoint.cpp
@@ -918,9 +918,9 @@ protected:
if (addr_type == eAddressTypeLoad) {
// We're in business.
// Find out the size of this variable.
- size = m_option_watchpoint.watch_size == 0
+ size = m_option_watchpoint.watch_size.GetCurrentValue() == 0
? valobj_sp->GetByteSize().value_or(0)
- : m_option_watchpoint.watch_size;
+ : m_option_watchpoint.watch_size.GetCurrentValue();
}
compiler_type = valobj_sp->GetCompilerType();
} else {
@@ -1113,8 +1113,8 @@ protected:
return;
}
- if (m_option_watchpoint.watch_size != 0)
- size = m_option_watchpoint.watch_size;
+ if (m_option_watchpoint.watch_size.GetCurrentValue() != 0)
+ size = m_option_watchpoint.watch_size.GetCurrentValue();
else
size = target->GetArchitecture().GetAddressByteSize();
diff --git a/lldb/source/Interpreter/OptionGroupWatchpoint.cpp b/lldb/source/Interpreter/OptionGroupWatchpoint.cpp
index c3708e7..d1ae916 100644
--- a/lldb/source/Interpreter/OptionGroupWatchpoint.cpp
+++ b/lldb/source/Interpreter/OptionGroupWatchpoint.cpp
@@ -39,35 +39,12 @@ static constexpr OptionEnumValueElement g_watch_type[] = {
},
};
-static constexpr OptionEnumValueElement g_watch_size[] = {
- {
- 1,
- "1",
- "Watch for byte size of 1",
- },
- {
- 2,
- "2",
- "Watch for byte size of 2",
- },
- {
- 4,
- "4",
- "Watch for byte size of 4",
- },
- {
- 8,
- "8",
- "Watch for byte size of 8",
- },
-};
-
static constexpr OptionDefinition g_option_table[] = {
{LLDB_OPT_SET_1, false, "watch", 'w', OptionParser::eRequiredArgument,
nullptr, OptionEnumValues(g_watch_type), 0, eArgTypeWatchType,
"Specify the type of watching to perform."},
{LLDB_OPT_SET_1, false, "size", 's', OptionParser::eRequiredArgument,
- nullptr, OptionEnumValues(g_watch_size), 0, eArgTypeByteSize,
+ nullptr, {}, 0, eArgTypeByteSize,
"Number of bytes to use to watch a region."},
{LLDB_OPT_SET_2,
false,
@@ -80,16 +57,6 @@ static constexpr OptionDefinition g_option_table[] = {
eArgTypeLanguage,
"Language of expression to run"}};
-bool OptionGroupWatchpoint::IsWatchSizeSupported(uint32_t watch_size) {
- for (const auto& size : g_watch_size) {
- if (0 == size.value)
- break;
- if (watch_size == size.value)
- return true;
- }
- return false;
-}
-
Status
OptionGroupWatchpoint::SetOptionValue(uint32_t option_idx,
llvm::StringRef option_arg,
@@ -120,8 +87,10 @@ OptionGroupWatchpoint::SetOptionValue(uint32_t option_idx,
break;
}
case 's':
- watch_size = (uint32_t)OptionArgParser::ToOptionEnum(
- option_arg, g_option_table[option_idx].enum_values, 0, error);
+ error = watch_size.SetValueFromString(option_arg);
+ if (watch_size.GetCurrentValue() == 0)
+ error.SetErrorStringWithFormat("invalid --size option value '%s'",
+ option_arg.str().c_str());
break;
default:
@@ -135,7 +104,7 @@ void OptionGroupWatchpoint::OptionParsingStarting(
ExecutionContext *execution_context) {
watch_type_specified = false;
watch_type = eWatchInvalid;
- watch_size = 0;
+ watch_size.Clear();
language_type = eLanguageTypeUnknown;
}
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 6c763ea..a5c9ead 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -607,7 +607,7 @@ bool ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop(
return false;
uint64_t break_site_id = stop_reason->GetValue();
- return m_process->GetBreakpointSiteList().BreakpointSiteContainsBreakpoint(
+ return m_process->GetBreakpointSiteList().StopPointSiteContainsBreakpoint(
break_site_id, m_cxx_exception_bp_sp->GetID());
}
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index 80c7bd0..f08f9f0 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -445,7 +445,7 @@ bool AppleObjCRuntime::ExceptionBreakpointsExplainStop(
return false;
uint64_t break_site_id = stop_reason->GetValue();
- return m_process->GetBreakpointSiteList().BreakpointSiteContainsBreakpoint(
+ return m_process->GetBreakpointSiteList().StopPointSiteContainsBreakpoint(
break_site_id, m_objc_exception_bp_sp->GetID());
}
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
index 547a1f6..4093cbd 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
@@ -333,7 +333,7 @@ AppleThreadPlanStepThroughDirectDispatch::DoPlanExplainsStop(Event *event_ptr) {
if (site_sp->IsBreakpointAtThisSite(break_sp->GetID())) {
// If we aren't the only one with a breakpoint on this site, then we
// should just stop and return control to the user.
- if (site_sp->GetNumberOfOwners() > 1) {
+ if (site_sp->GetNumberOfConstituents() > 1) {
SetPlanComplete(true);
return false;
}
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index ae36d3f..ca7ff5a 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -432,7 +432,7 @@ PlatformDarwin::GetSoftwareBreakpointTrapOpcode(Target &target,
// Auto detect arm/thumb if it wasn't explicitly specified
if (!bp_is_thumb) {
- lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
+ lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetConstituentAtIndex(0));
if (bp_loc_sp)
bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass() ==
AddressClass::eCodeAlternateISA;
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
index e0956b4..70bb9aa 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -671,20 +671,6 @@ Status ProcessKDP::DisableBreakpointSite(BreakpointSite *bp_site) {
return DisableSoftwareBreakpoint(bp_site);
}
-Status ProcessKDP::EnableWatchpoint(Watchpoint *wp, bool notify) {
- Status error;
- error.SetErrorString(
- "watchpoints are not supported in kdp remote debugging");
- return error;
-}
-
-Status ProcessKDP::DisableWatchpoint(Watchpoint *wp, bool notify) {
- Status error;
- error.SetErrorString(
- "watchpoints are not supported in kdp remote debugging");
- return error;
-}
-
void ProcessKDP::Clear() { m_thread_list.Clear(); }
Status ProcessKDP::DoSignal(int signo) {
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
index 3c12fd4..e5ec591 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
@@ -124,13 +124,6 @@ public:
lldb_private::Status
DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
- // Process Watchpoints
- lldb_private::Status EnableWatchpoint(lldb_private::Watchpoint *wp,
- bool notify = true) override;
-
- lldb_private::Status DisableWatchpoint(lldb_private::Watchpoint *wp,
- bool notify = true) override;
-
CommunicationKDP &GetCommunication() { return m_comm; }
protected:
diff --git a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
index 5c947bb..565941d 100644
--- a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -491,6 +491,9 @@ static StopInfoSP GetStopInfoForHardwareBP(Thread &thread, Target *target,
uint64_t exc_sub_sub_code) {
// Try hardware watchpoint.
if (target) {
+ // LWP_TODO: We need to find the WatchpointResource that matches
+ // the address, and evaluate its Watchpoints.
+
// The exc_sub_code indicates the data break address.
lldb::WatchpointSP wp_sp =
target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code);
@@ -666,6 +669,9 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
case llvm::Triple::thumb:
if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
{
+ // LWP_TODO: We need to find the WatchpointResource that matches
+ // the address, and evaluate its Watchpoints.
+
// It's a watchpoint, then, if the exc_sub_code indicates a
// known/enabled data break address from our watchpoint list.
lldb::WatchpointSP wp_sp;
@@ -742,6 +748,9 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
}
if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
{
+ // LWP_TODO: We need to find the WatchpointResource that matches
+ // the address, and evaluate its Watchpoints.
+
// It's a watchpoint, then, if the exc_sub_code indicates a
// known/enabled data break address from our watchpoint list.
lldb::WatchpointSP wp_sp;
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index 91b3216..eb0834b 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -835,11 +835,11 @@ std::optional<uint32_t> ProcessWindows::GetWatchpointSlotCount() {
return RegisterContextWindows::GetNumHardwareBreakpointSlots();
}
-Status ProcessWindows::EnableWatchpoint(Watchpoint *wp, bool notify) {
+Status ProcessWindows::EnableWatchpoint(WatchpointSP wp_sp, bool notify) {
Status error;
- if (wp->IsEnabled()) {
- wp->SetEnabled(true, notify);
+ if (wp_sp->IsEnabled()) {
+ wp_sp->SetEnabled(true, notify);
return error;
}
@@ -851,13 +851,13 @@ Status ProcessWindows::EnableWatchpoint(Watchpoint *wp, bool notify) {
break;
if (info.slot_id == RegisterContextWindows::GetNumHardwareBreakpointSlots()) {
error.SetErrorStringWithFormat("Can't find free slot for watchpoint %i",
- wp->GetID());
+ wp_sp->GetID());
return error;
}
- info.address = wp->GetLoadAddress();
- info.size = wp->GetByteSize();
- info.read = wp->WatchpointRead();
- info.write = wp->WatchpointWrite();
+ info.address = wp_sp->GetLoadAddress();
+ info.size = wp_sp->GetByteSize();
+ info.read = wp_sp->WatchpointRead();
+ info.write = wp_sp->WatchpointWrite();
for (unsigned i = 0U; i < m_thread_list.GetSize(); i++) {
Thread *thread = m_thread_list.GetThreadAtIndex(i).get();
@@ -866,7 +866,7 @@ Status ProcessWindows::EnableWatchpoint(Watchpoint *wp, bool notify) {
if (!reg_ctx->AddHardwareBreakpoint(info.slot_id, info.address, info.size,
info.read, info.write)) {
error.SetErrorStringWithFormat(
- "Can't enable watchpoint %i on thread 0x%llx", wp->GetID(),
+ "Can't enable watchpoint %i on thread 0x%llx", wp_sp->GetID(),
thread->GetID());
break;
}
@@ -881,26 +881,26 @@ Status ProcessWindows::EnableWatchpoint(Watchpoint *wp, bool notify) {
return error;
}
- m_watchpoints[wp->GetID()] = info;
- m_watchpoint_ids[info.slot_id] = wp->GetID();
+ m_watchpoints[wp_sp->GetID()] = info;
+ m_watchpoint_ids[info.slot_id] = wp_sp->GetID();
- wp->SetEnabled(true, notify);
+ wp_sp->SetEnabled(true, notify);
return error;
}
-Status ProcessWindows::DisableWatchpoint(Watchpoint *wp, bool notify) {
+Status ProcessWindows::DisableWatchpoint(WatchpointSP wp_sp, bool notify) {
Status error;
- if (!wp->IsEnabled()) {
- wp->SetEnabled(false, notify);
+ if (!wp_sp->IsEnabled()) {
+ wp_sp->SetEnabled(false, notify);
return error;
}
- auto it = m_watchpoints.find(wp->GetID());
+ auto it = m_watchpoints.find(wp_sp->GetID());
if (it == m_watchpoints.end()) {
error.SetErrorStringWithFormat("Info about watchpoint %i is not found",
- wp->GetID());
+ wp_sp->GetID());
return error;
}
@@ -910,7 +910,7 @@ Status ProcessWindows::DisableWatchpoint(Watchpoint *wp, bool notify) {
thread->GetRegisterContext().get());
if (!reg_ctx->RemoveHardwareBreakpoint(it->second.slot_id)) {
error.SetErrorStringWithFormat(
- "Can't disable watchpoint %i on thread 0x%llx", wp->GetID(),
+ "Can't disable watchpoint %i on thread 0x%llx", wp_sp->GetID(),
thread->GetID());
break;
}
@@ -921,7 +921,7 @@ Status ProcessWindows::DisableWatchpoint(Watchpoint *wp, bool notify) {
m_watchpoint_ids[it->second.slot_id] = LLDB_INVALID_BREAK_ID;
m_watchpoints.erase(it);
- wp->SetEnabled(false, notify);
+ wp_sp->SetEnabled(false, notify);
return error;
}
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h
index ed083b9..e97cfb7 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h
@@ -96,8 +96,10 @@ public:
void OnDebuggerError(const Status &error, uint32_t type) override;
std::optional<uint32_t> GetWatchpointSlotCount() override;
- Status EnableWatchpoint(Watchpoint *wp, bool notify = true) override;
- Status DisableWatchpoint(Watchpoint *wp, bool notify = true) override;
+ Status EnableWatchpoint(lldb::WatchpointSP wp_sp,
+ bool notify = true) override;
+ Status DisableWatchpoint(lldb::WatchpointSP wp_sp,
+ bool notify = true) override;
protected:
ProcessWindows(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 9648f1f..fb67151 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -24,6 +24,7 @@
#include <sys/types.h>
#include "lldb/Breakpoint/Watchpoint.h"
+#include "lldb/Breakpoint/WatchpointResource.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
@@ -1798,24 +1799,29 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
addr_t wp_hit_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
bool silently_continue = false;
- WatchpointSP wp_sp;
+ WatchpointResourceSP wp_resource_sp;
if (wp_hit_addr != LLDB_INVALID_ADDRESS) {
- wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_hit_addr);
+ wp_resource_sp =
+ m_watchpoint_resource_list.FindByAddress(wp_hit_addr);
// On MIPS, \a wp_hit_addr outside the range of a watched
// region means we should silently continue, it is a false hit.
ArchSpec::Core core = GetTarget().GetArchitecture().GetCore();
- if (!wp_sp && core >= ArchSpec::kCore_mips_first &&
+ if (!wp_resource_sp && core >= ArchSpec::kCore_mips_first &&
core <= ArchSpec::kCore_mips_last)
silently_continue = true;
}
- if (!wp_sp && wp_addr != LLDB_INVALID_ADDRESS)
- wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr);
- if (wp_sp) {
- watch_id = wp_sp->GetID();
- }
- if (watch_id == LLDB_INVALID_WATCH_ID) {
+ if (!wp_resource_sp && wp_addr != LLDB_INVALID_ADDRESS)
+ wp_resource_sp = m_watchpoint_resource_list.FindByAddress(wp_addr);
+ if (!wp_resource_sp) {
Log *log(GetLog(GDBRLog::Watchpoints));
LLDB_LOGF(log, "failed to find watchpoint");
+ watch_id = LLDB_INVALID_SITE_ID;
+ } else {
+ // LWP_TODO: This is hardcoding a single Watchpoint in a
+ // Resource, need to add
+ // StopInfo::CreateStopReasonWithWatchpointResource which
+ // represents all watchpoints that were tripped at this stop.
+ watch_id = wp_resource_sp->GetConstituentAtIndex(0)->GetID();
}
thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithWatchpointID(
*thread_sp, watch_id, silently_continue));
@@ -2239,8 +2245,8 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
lldb::addr_t wp_addr = LLDB_INVALID_ADDRESS;
value.getAsInteger(16, wp_addr);
- WatchpointSP wp_sp =
- GetTarget().GetWatchpointList().FindByAddress(wp_addr);
+ WatchpointResourceSP wp_resource_sp =
+ m_watchpoint_resource_list.FindByAddress(wp_addr);
// Rewrite gdb standard watch/rwatch/awatch to
// "reason:watchpoint" + "description:ADDR",
@@ -3109,102 +3115,182 @@ Status ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) {
}
// Pre-requisite: wp != NULL.
-static GDBStoppointType GetGDBStoppointType(Watchpoint *wp) {
- assert(wp);
- bool watch_read = wp->WatchpointRead();
- bool watch_write = wp->WatchpointWrite();
- bool watch_modify = wp->WatchpointModify();
-
- // watch_read, watch_write, watch_modify cannot all be false.
- assert((watch_read || watch_write || watch_modify) &&
- "watch_read, watch_write, watch_modify cannot all be false.");
- if (watch_read && (watch_write || watch_modify))
+static GDBStoppointType
+GetGDBStoppointType(const WatchpointResourceSP &wp_res_sp) {
+ assert(wp_res_sp);
+ bool read = wp_res_sp->WatchpointResourceRead();
+ bool write = wp_res_sp->WatchpointResourceWrite();
+
+ assert((read || write) &&
+ "WatchpointResource type is neither read nor write");
+ if (read && write)
return eWatchpointReadWrite;
- else if (watch_read)
+ else if (read)
return eWatchpointRead;
- else // Must be watch_write or watch_modify, then.
+ else
return eWatchpointWrite;
}
-Status ProcessGDBRemote::EnableWatchpoint(Watchpoint *wp, bool notify) {
+Status ProcessGDBRemote::EnableWatchpoint(WatchpointSP wp_sp, bool notify) {
Status error;
- if (wp) {
- user_id_t watchID = wp->GetID();
- addr_t addr = wp->GetLoadAddress();
- Log *log(GetLog(GDBRLog::Watchpoints));
- LLDB_LOGF(log, "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")",
- watchID);
- if (wp->IsEnabled()) {
- LLDB_LOGF(log,
- "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
- watchID, (uint64_t)addr);
- return error;
- }
+ if (!wp_sp) {
+ error.SetErrorString("No watchpoint specified");
+ return error;
+ }
+ user_id_t watchID = wp_sp->GetID();
+ addr_t addr = wp_sp->GetLoadAddress();
+ Log *log(GetLog(GDBRLog::Watchpoints));
+ LLDB_LOGF(log, "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")",
+ watchID);
+ if (wp_sp->IsEnabled()) {
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
+ watchID, (uint64_t)addr);
+ return error;
+ }
- GDBStoppointType type = GetGDBStoppointType(wp);
- // Pass down an appropriate z/Z packet...
- if (m_gdb_comm.SupportsGDBStoppointPacket(type)) {
- if (m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr,
- wp->GetByteSize(),
- GetInterruptTimeout()) == 0) {
- wp->SetEnabled(true, notify);
- return error;
- } else
- error.SetErrorString("sending gdb watchpoint packet failed");
- } else
- error.SetErrorString("watchpoints not supported");
+ bool read = wp_sp->WatchpointRead();
+ bool write = wp_sp->WatchpointWrite() || wp_sp->WatchpointModify();
+ size_t size = wp_sp->GetByteSize();
+
+ // New WatchpointResources needed to implement this Watchpoint.
+ std::vector<WatchpointResourceSP> resources;
+
+ // LWP_TODO: Break up the user's request into pieces that can be watched
+ // given the capabilities of the target cpu / stub software.
+ // As a default, breaking the watched region up into target-pointer-sized,
+ // aligned, groups.
+ //
+ // Beyond the default, a stub can / should inform us of its capabilities,
+ // e.g. a stub that can do AArch64 power-of-2 MASK watchpoints.
+ //
+ // And the cpu may have unique capabilities. AArch64 BAS watchpoints
+ // can watch any sequential bytes in a doubleword, but Intel watchpoints
+ // can only watch 1, 2, 4, 8 bytes within a doubleword.
+ WatchpointResourceSP wp_res_sp =
+ std::make_shared<WatchpointResource>(addr, size, read, write);
+ resources.push_back(wp_res_sp);
+
+ // LWP_TODO: Now that we know the WP Resources needed to implement this
+ // Watchpoint, we need to look at currently allocated Resources in the
+ // Process and if they match, or are within the same memory granule, or
+ // overlapping memory ranges, then we need to combine them. e.g. one
+ // Watchpoint watching 1 byte at 0x1002 and a second watchpoint watching 1
+ // byte at 0x1003, they must use the same hardware watchpoint register
+ // (Resource) to watch them.
+
+ // This may mean that an existing resource changes its type (read to
+ // read+write) or address range it is watching, in which case the old
+ // watchpoint needs to be disabled and the new Resource addr/size/type
+ // watchpoint enabled.
+
+ // If we modify a shared Resource to accomodate this newly added Watchpoint,
+ // and we are unable to set all of the Resources for it in the inferior, we
+ // will return an error for this Watchpoint and the shared Resource should
+ // be restored. e.g. this Watchpoint requires three Resources, one which
+ // is shared with another Watchpoint. We extend the shared Resouce to
+ // handle both Watchpoints and we try to set two new ones. But if we don't
+ // have sufficient watchpoint register for all 3, we need to show an error
+ // for creating this Watchpoint and we should reset the shared Resource to
+ // its original configuration because it is no longer shared.
+
+ bool set_all_resources = true;
+ std::vector<WatchpointResourceSP> succesfully_set_resources;
+ for (const auto &wp_res_sp : resources) {
+ addr_t addr = wp_res_sp->GetLoadAddress();
+ size_t size = wp_res_sp->GetByteSize();
+ GDBStoppointType type = GetGDBStoppointType(wp_res_sp);
+ if (!m_gdb_comm.SupportsGDBStoppointPacket(type) ||
+ m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr, size,
+ GetInterruptTimeout())) {
+ set_all_resources = false;
+ break;
+ } else {
+ succesfully_set_resources.push_back(wp_res_sp);
+ }
+ }
+ if (set_all_resources) {
+ wp_sp->SetEnabled(true, notify);
+ for (const auto &wp_res_sp : resources) {
+ // LWP_TODO: If we expanded/reused an existing Resource,
+ // it's already in the WatchpointResourceList.
+ wp_res_sp->AddConstituent(wp_sp);
+ m_watchpoint_resource_list.Add(wp_res_sp);
+ }
+ return error;
} else {
- error.SetErrorString("Watchpoint argument was NULL.");
+ // We failed to allocate one of the resources. Unset all
+ // of the new resources we did successfully set in the
+ // process.
+ for (const auto &wp_res_sp : succesfully_set_resources) {
+ addr_t addr = wp_res_sp->GetLoadAddress();
+ size_t size = wp_res_sp->GetByteSize();
+ GDBStoppointType type = GetGDBStoppointType(wp_res_sp);
+ m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr, size,
+ GetInterruptTimeout());
+ }
+ error.SetErrorString("Setting one of the watchpoint resources failed");
}
- if (error.Success())
- error.SetErrorToGenericError();
return error;
}
-Status ProcessGDBRemote::DisableWatchpoint(Watchpoint *wp, bool notify) {
+Status ProcessGDBRemote::DisableWatchpoint(WatchpointSP wp_sp, bool notify) {
Status error;
- if (wp) {
- user_id_t watchID = wp->GetID();
+ if (!wp_sp) {
+ error.SetErrorString("Watchpoint argument was NULL.");
+ return error;
+ }
+
+ user_id_t watchID = wp_sp->GetID();
- Log *log(GetLog(GDBRLog::Watchpoints));
+ Log *log(GetLog(GDBRLog::Watchpoints));
- addr_t addr = wp->GetLoadAddress();
+ addr_t addr = wp_sp->GetLoadAddress();
+
+ LLDB_LOGF(log,
+ "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
+ ") addr = 0x%8.8" PRIx64,
+ watchID, (uint64_t)addr);
+ if (!wp_sp->IsEnabled()) {
LLDB_LOGF(log,
"ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64,
+ ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
watchID, (uint64_t)addr);
+ // See also 'class WatchpointSentry' within StopInfo.cpp. This disabling
+ // attempt might come from the user-supplied actions, we'll route it in
+ // order for the watchpoint object to intelligently process this action.
+ wp_sp->SetEnabled(false, notify);
+ return error;
+ }
- if (!wp->IsEnabled()) {
- LLDB_LOGF(log,
- "ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
- ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
- watchID, (uint64_t)addr);
- // See also 'class WatchpointSentry' within StopInfo.cpp. This disabling
- // attempt might come from the user-supplied actions, we'll route it in
- // order for the watchpoint object to intelligently process this action.
- wp->SetEnabled(false, notify);
- return error;
- }
+ if (wp_sp->IsHardware()) {
+ bool disabled_all = true;
- if (wp->IsHardware()) {
- GDBStoppointType type = GetGDBStoppointType(wp);
- // Pass down an appropriate z/Z packet...
- if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr,
- wp->GetByteSize(),
- GetInterruptTimeout()) == 0) {
- wp->SetEnabled(false, notify);
- return error;
- } else
- error.SetErrorString("sending gdb watchpoint packet failed");
+ std::vector<WatchpointResourceSP> unused_resources;
+ for (const auto &wp_res_sp : m_watchpoint_resource_list.Sites()) {
+ if (wp_res_sp->ConstituentsContains(wp_sp)) {
+ GDBStoppointType type = GetGDBStoppointType(wp_res_sp);
+ addr_t addr = wp_res_sp->GetLoadAddress();
+ size_t size = wp_res_sp->GetByteSize();
+ if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr, size,
+ GetInterruptTimeout())) {
+ disabled_all = false;
+ } else {
+ wp_res_sp->RemoveConstituent(wp_sp);
+ if (wp_res_sp->GetNumberOfConstituents() == 0)
+ unused_resources.push_back(wp_res_sp);
+ }
+ }
}
- // TODO: clear software watchpoints if we implement them
- } else {
- error.SetErrorString("Watchpoint argument was NULL.");
+ for (auto &wp_res_sp : unused_resources)
+ m_watchpoint_resource_list.Remove(wp_res_sp->GetID());
+
+ wp_sp->SetEnabled(false, notify);
+ if (!disabled_all)
+ error.SetErrorString("Failure disabling one of the watchpoint locations");
}
- if (error.Success())
- error.SetErrorToGenericError();
return error;
}
@@ -5456,16 +5542,12 @@ void ProcessGDBRemote::DidForkSwitchHardwareTraps(bool enable) {
});
}
- WatchpointList &wps = GetTarget().GetWatchpointList();
- size_t wp_count = wps.GetSize();
- for (size_t i = 0; i < wp_count; ++i) {
- WatchpointSP wp = wps.GetByIndex(i);
- if (wp->IsEnabled()) {
- GDBStoppointType type = GetGDBStoppointType(wp.get());
- m_gdb_comm.SendGDBStoppointTypePacket(type, enable, wp->GetLoadAddress(),
- wp->GetByteSize(),
- GetInterruptTimeout());
- }
+ for (const auto &wp_res_sp : m_watchpoint_resource_list.Sites()) {
+ addr_t addr = wp_res_sp->GetLoadAddress();
+ size_t size = wp_res_sp->GetByteSize();
+ GDBStoppointType type = GetGDBStoppointType(wp_res_sp);
+ m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr, size,
+ GetInterruptTimeout());
}
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index f3787e7..c1ea1cc 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -158,9 +158,11 @@ public:
Status DisableBreakpointSite(BreakpointSite *bp_site) override;
// Process Watchpoints
- Status EnableWatchpoint(Watchpoint *wp, bool notify = true) override;
+ Status EnableWatchpoint(lldb::WatchpointSP wp_sp,
+ bool notify = true) override;
- Status DisableWatchpoint(Watchpoint *wp, bool notify = true) override;
+ Status DisableWatchpoint(lldb::WatchpointSP wp_sp,
+ bool notify = true) override;
std::optional<uint32_t> GetWatchpointSlotCount() override;
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index c345e33..4ce290d 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -2014,7 +2014,7 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target,
static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde};
- lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
+ lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetConstituentAtIndex(0));
AddressClass addr_class = AddressClass::eUnknown;
if (bp_loc_sp) {
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index f3da283..2d77144 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -436,7 +436,7 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp,
m_exit_status_mutex(), m_thread_mutex(), m_thread_list_real(this),
m_thread_list(this), m_thread_plans(*this), m_extended_thread_list(this),
m_extended_thread_stop_id(0), m_queue_list(this), m_queue_list_stop_id(0),
- m_notifications(), m_image_tokens(),
+ m_watchpoint_resource_list(), m_notifications(), m_image_tokens(),
m_breakpoint_site_list(), m_dynamic_checkers_up(),
m_unix_signals_sp(unix_signals_sp), m_abi_sp(), m_process_input_reader(),
m_stdio_communication("process.stdio"), m_stdio_communication_mutex(),
@@ -547,6 +547,7 @@ void Process::Finalize() {
m_extended_thread_list.Destroy();
m_queue_list.Clear();
m_queue_list_stop_id = 0;
+ m_watchpoint_resource_list.Clear();
std::vector<Notifications> empty_notifications;
m_notifications.swap(empty_notifications);
m_image_tokens.clear();
@@ -1563,11 +1564,12 @@ void Process::SetDynamicCheckers(DynamicCheckerFunctions *dynamic_checkers) {
m_dynamic_checkers_up.reset(dynamic_checkers);
}
-BreakpointSiteList &Process::GetBreakpointSiteList() {
+StopPointSiteList<BreakpointSite> &Process::GetBreakpointSiteList() {
return m_breakpoint_site_list;
}
-const BreakpointSiteList &Process::GetBreakpointSiteList() const {
+const StopPointSiteList<BreakpointSite> &
+Process::GetBreakpointSiteList() const {
return m_breakpoint_site_list;
}
@@ -1615,7 +1617,7 @@ Status Process::EnableBreakpointSiteByID(lldb::user_id_t break_id) {
}
lldb::break_id_t
-Process::CreateBreakpointSite(const BreakpointLocationSP &owner,
+Process::CreateBreakpointSite(const BreakpointLocationSP &constituent,
bool use_hardware) {
addr_t load_addr = LLDB_INVALID_ADDRESS;
@@ -1642,10 +1644,10 @@ Process::CreateBreakpointSite(const BreakpointLocationSP &owner,
// Reset the IsIndirect flag here, in case the location changes from pointing
// to a indirect symbol to a regular symbol.
- owner->SetIsIndirect(false);
+ constituent->SetIsIndirect(false);
- if (owner->ShouldResolveIndirectFunctions()) {
- Symbol *symbol = owner->GetAddress().CalculateSymbolContextSymbol();
+ if (constituent->ShouldResolveIndirectFunctions()) {
+ Symbol *symbol = constituent->GetAddress().CalculateSymbolContextSymbol();
if (symbol && symbol->IsIndirect()) {
Status error;
Address symbol_address = symbol->GetAddress();
@@ -1655,37 +1657,37 @@ Process::CreateBreakpointSite(const BreakpointLocationSP &owner,
"warning: failed to resolve indirect function at 0x%" PRIx64
" for breakpoint %i.%i: %s\n",
symbol->GetLoadAddress(&GetTarget()),
- owner->GetBreakpoint().GetID(), owner->GetID(),
+ constituent->GetBreakpoint().GetID(), constituent->GetID(),
error.AsCString() ? error.AsCString() : "unknown error");
return LLDB_INVALID_BREAK_ID;
}
Address resolved_address(load_addr);
load_addr = resolved_address.GetOpcodeLoadAddress(&GetTarget());
- owner->SetIsIndirect(true);
+ constituent->SetIsIndirect(true);
} else
- load_addr = owner->GetAddress().GetOpcodeLoadAddress(&GetTarget());
+ load_addr = constituent->GetAddress().GetOpcodeLoadAddress(&GetTarget());
} else
- load_addr = owner->GetAddress().GetOpcodeLoadAddress(&GetTarget());
+ load_addr = constituent->GetAddress().GetOpcodeLoadAddress(&GetTarget());
if (load_addr != LLDB_INVALID_ADDRESS) {
BreakpointSiteSP bp_site_sp;
- // Look up this breakpoint site. If it exists, then add this new owner,
- // otherwise create a new breakpoint site and add it.
+ // Look up this breakpoint site. If it exists, then add this new
+ // constituent, otherwise create a new breakpoint site and add it.
bp_site_sp = m_breakpoint_site_list.FindByAddress(load_addr);
if (bp_site_sp) {
- bp_site_sp->AddOwner(owner);
- owner->SetBreakpointSite(bp_site_sp);
+ bp_site_sp->AddConstituent(constituent);
+ constituent->SetBreakpointSite(bp_site_sp);
return bp_site_sp->GetID();
} else {
- bp_site_sp.reset(new BreakpointSite(&m_breakpoint_site_list, owner,
- load_addr, use_hardware));
+ bp_site_sp.reset(
+ new BreakpointSite(constituent, load_addr, use_hardware));
if (bp_site_sp) {
Status error = EnableBreakpointSite(bp_site_sp.get());
if (error.Success()) {
- owner->SetBreakpointSite(bp_site_sp);
+ constituent->SetBreakpointSite(bp_site_sp);
return m_breakpoint_site_list.Add(bp_site_sp);
} else {
if (show_error || use_hardware) {
@@ -1693,7 +1695,8 @@ Process::CreateBreakpointSite(const BreakpointLocationSP &owner,
GetTarget().GetDebugger().GetErrorStream().Printf(
"warning: failed to set breakpoint site at 0x%" PRIx64
" for breakpoint %i.%i: %s\n",
- load_addr, owner->GetBreakpoint().GetID(), owner->GetID(),
+ load_addr, constituent->GetBreakpoint().GetID(),
+ constituent->GetID(),
error.AsCString() ? error.AsCString() : "unknown error");
}
}
@@ -1704,11 +1707,12 @@ Process::CreateBreakpointSite(const BreakpointLocationSP &owner,
return LLDB_INVALID_BREAK_ID;
}
-void Process::RemoveOwnerFromBreakpointSite(lldb::user_id_t owner_id,
- lldb::user_id_t owner_loc_id,
- BreakpointSiteSP &bp_site_sp) {
- uint32_t num_owners = bp_site_sp->RemoveOwner(owner_id, owner_loc_id);
- if (num_owners == 0) {
+void Process::RemoveConstituentFromBreakpointSite(
+ lldb::user_id_t constituent_id, lldb::user_id_t constituent_loc_id,
+ BreakpointSiteSP &bp_site_sp) {
+ uint32_t num_constituents =
+ bp_site_sp->RemoveConstituent(constituent_id, constituent_loc_id);
+ if (num_constituents == 0) {
// Don't try to disable the site if we don't have a live process anymore.
if (IsAlive())
DisableBreakpointSite(bp_site_sp.get());
@@ -1719,7 +1723,7 @@ void Process::RemoveOwnerFromBreakpointSite(lldb::user_id_t owner_id,
size_t Process::RemoveBreakpointOpcodesFromBuffer(addr_t bp_addr, size_t size,
uint8_t *buf) const {
size_t bytes_removed = 0;
- BreakpointSiteList bp_sites_in_range;
+ StopPointSiteList<BreakpointSite> bp_sites_in_range;
if (m_breakpoint_site_list.FindInRange(bp_addr, bp_addr + size,
bp_sites_in_range)) {
@@ -2140,7 +2144,7 @@ size_t Process::WriteMemory(addr_t addr, const void *buf, size_t size,
// (enabled software breakpoints) any software traps (breakpoints) that we
// may have placed in our tasks memory.
- BreakpointSiteList bp_sites_in_range;
+ StopPointSiteList<BreakpointSite> bp_sites_in_range;
if (!m_breakpoint_site_list.FindInRange(addr, addr + size, bp_sites_in_range))
return WriteMemoryPrivate(addr, buf, size, error);
@@ -2408,13 +2412,13 @@ bool Process::GetLoadAddressPermissions(lldb::addr_t load_addr,
return true;
}
-Status Process::EnableWatchpoint(Watchpoint *watchpoint, bool notify) {
+Status Process::EnableWatchpoint(WatchpointSP wp_sp, bool notify) {
Status error;
error.SetErrorString("watchpoints are not supported");
return error;
}
-Status Process::DisableWatchpoint(Watchpoint *watchpoint, bool notify) {
+Status Process::DisableWatchpoint(WatchpointSP wp_sp, bool notify) {
Status error;
error.SetErrorString("watchpoints are not supported");
return error;
diff --git a/lldb/source/Target/StackFrameList.cpp b/lldb/source/Target/StackFrameList.cpp
index 88cc518..2273e52 100644
--- a/lldb/source/Target/StackFrameList.cpp
+++ b/lldb/source/Target/StackFrameList.cpp
@@ -156,9 +156,10 @@ void StackFrameList::ResetCurrentInlinedDepth() {
m_thread.GetProcess()->GetBreakpointSiteList().FindByID(bp_site_id));
bool all_internal = true;
if (bp_site_sp) {
- uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
+ uint32_t num_owners = bp_site_sp->GetNumberOfConstituents();
for (uint32_t i = 0; i < num_owners; i++) {
- Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
+ Breakpoint &bp_ref =
+ bp_site_sp->GetConstituentAtIndex(i)->GetBreakpoint();
if (!bp_ref.IsInternal()) {
all_internal = false;
}
diff --git a/lldb/source/Target/StopInfo.cpp b/lldb/source/Target/StopInfo.cpp
index 0b85845..3b65d66 100644
--- a/lldb/source/Target/StopInfo.cpp
+++ b/lldb/source/Target/StopInfo.cpp
@@ -12,6 +12,7 @@
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Breakpoint/Watchpoint.h"
+#include "lldb/Breakpoint/WatchpointResource.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/UserExpression.h"
@@ -109,9 +110,9 @@ public:
BreakpointSiteSP bp_site_sp(
thread_sp->GetProcess()->GetBreakpointSiteList().FindByID(m_value));
if (bp_site_sp) {
- uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
- if (num_owners == 1) {
- BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(0);
+ uint32_t num_constituents = bp_site_sp->GetNumberOfConstituents();
+ if (num_constituents == 1) {
+ BreakpointLocationSP bp_loc_sp = bp_site_sp->GetConstituentAtIndex(0);
if (bp_loc_sp) {
Breakpoint & bkpt = bp_loc_sp->GetBreakpoint();
m_break_id = bkpt.GetID();
@@ -120,8 +121,10 @@ public:
}
} else {
m_was_all_internal = true;
- for (uint32_t i = 0; i < num_owners; i++) {
- if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal()) {
+ for (uint32_t i = 0; i < num_constituents; i++) {
+ if (!bp_site_sp->GetConstituentAtIndex(i)
+ ->GetBreakpoint()
+ .IsInternal()) {
m_was_all_internal = false;
break;
}
@@ -189,9 +192,9 @@ public:
// If we have just hit an internal breakpoint, and it has a kind
// description, print that instead of the full breakpoint printing:
if (bp_site_sp->IsInternal()) {
- size_t num_owners = bp_site_sp->GetNumberOfOwners();
- for (size_t idx = 0; idx < num_owners; idx++) {
- const char *kind = bp_site_sp->GetOwnerAtIndex(idx)
+ size_t num_constituents = bp_site_sp->GetNumberOfConstituents();
+ for (size_t idx = 0; idx < num_constituents; idx++) {
+ const char *kind = bp_site_sp->GetConstituentAtIndex(idx)
->GetBreakpoint()
.GetBreakpointKind();
if (kind != nullptr) {
@@ -284,13 +287,14 @@ protected:
// Use this variable to tell us if that is true.
bool actually_hit_any_locations = false;
if (bp_site_sp) {
- // Let's copy the owners list out of the site and store them in a local
- // list. That way if one of the breakpoint actions changes the site,
- // then we won't be operating on a bad list.
+ // Let's copy the constituents list out of the site and store them in a
+ // local list. That way if one of the breakpoint actions changes the
+ // site, then we won't be operating on a bad list.
BreakpointLocationCollection site_locations;
- size_t num_owners = bp_site_sp->CopyOwnersList(site_locations);
+ size_t num_constituents =
+ bp_site_sp->CopyConstituentsList(site_locations);
- if (num_owners == 0) {
+ if (num_constituents == 0) {
m_should_stop = true;
actually_hit_any_locations = true; // We're going to stop, don't
// change the stop info.
@@ -382,20 +386,21 @@ protected:
StoppointCallbackContext context(event_ptr, exe_ctx, false);
// For safety's sake let's also grab an extra reference to the
- // breakpoint owners of the locations we're going to examine, since
- // the locations are going to have to get back to their breakpoints,
- // and the locations don't keep their owners alive. I'm just
- // sticking the BreakpointSP's in a vector since I'm only using it to
- // locally increment their retain counts.
+ // breakpoint constituents of the locations we're going to examine,
+ // since the locations are going to have to get back to their
+ // breakpoints, and the locations don't keep their constituents alive.
+ // I'm just sticking the BreakpointSP's in a vector since I'm only
+ // using it to locally increment their retain counts.
- std::vector<lldb::BreakpointSP> location_owners;
+ std::vector<lldb::BreakpointSP> location_constituents;
- for (size_t j = 0; j < num_owners; j++) {
+ for (size_t j = 0; j < num_constituents; j++) {
BreakpointLocationSP loc(site_locations.GetByIndex(j));
- location_owners.push_back(loc->GetBreakpoint().shared_from_this());
+ location_constituents.push_back(
+ loc->GetBreakpoint().shared_from_this());
}
- for (size_t j = 0; j < num_owners; j++) {
+ for (size_t j = 0; j < num_constituents; j++) {
lldb::BreakpointLocationSP bp_loc_sp = site_locations.GetByIndex(j);
StreamString loc_desc;
if (log) {
@@ -631,7 +636,7 @@ public:
if (process_sp && watchpoint_sp) {
const bool notify = false;
watchpoint_sp->TurnOnEphemeralMode();
- process_sp->DisableWatchpoint(watchpoint_sp.get(), notify);
+ process_sp->DisableWatchpoint(watchpoint_sp, notify);
process_sp->AddPreResumeAction(SentryPreResumeAction, this);
}
}
@@ -642,9 +647,9 @@ public:
watchpoint_sp->TurnOffEphemeralMode();
const bool notify = false;
if (was_disabled) {
- process_sp->DisableWatchpoint(watchpoint_sp.get(), notify);
+ process_sp->DisableWatchpoint(watchpoint_sp, notify);
} else {
- process_sp->EnableWatchpoint(watchpoint_sp.get(), notify);
+ process_sp->EnableWatchpoint(watchpoint_sp, notify);
}
}
}
@@ -707,7 +712,7 @@ protected:
return true;
if (!m_did_disable_wp) {
- GetThread().GetProcess()->DisableWatchpoint(m_watch_sp.get(), false);
+ GetThread().GetProcess()->DisableWatchpoint(m_watch_sp, false);
m_did_disable_wp = true;
}
return true;
@@ -751,7 +756,7 @@ protected:
if (!m_did_disable_wp)
return;
m_did_disable_wp = true;
- GetThread().GetProcess()->EnableWatchpoint(m_watch_sp.get(), true);
+ GetThread().GetProcess()->EnableWatchpoint(m_watch_sp, true);
}
private:
@@ -991,9 +996,10 @@ protected:
Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
StreamSP output_sp = debugger.GetAsyncOutputStream();
- wp_sp->DumpSnapshots(output_sp.get());
- output_sp->EOL();
- output_sp->Flush();
+ if (wp_sp->DumpSnapshots(output_sp.get())) {
+ output_sp->EOL();
+ output_sp->Flush();
+ }
}
} else {
@@ -1366,6 +1372,8 @@ StopInfoSP StopInfo::CreateStopReasonWithBreakpointSiteID(Thread &thread,
return StopInfoSP(new StopInfoBreakpoint(thread, break_id, should_stop));
}
+// LWP_TODO: We'll need a CreateStopReasonWithWatchpointResourceID akin
+// to CreateStopReasonWithBreakpointSiteID
StopInfoSP StopInfo::CreateStopReasonWithWatchpointID(Thread &thread,
break_id_t watch_id,
bool silently_continue) {
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index a6d7148..2e8d1df 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -892,6 +892,18 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
if (ABISP abi = m_process_sp->GetABI())
addr = abi->FixDataAddress(addr);
+ // LWP_TODO this sequence is looking for an existing watchpoint
+ // at the exact same user-specified address, disables the new one
+ // if addr/size/type match. If type/size differ, disable old one.
+ // This isn't correct, we need both watchpoints to use a shared
+ // WatchpointResource in the target, and expand the WatchpointResource
+ // to handle the needs of both Watchpoints.
+ // Also, even if the addresses don't match, they may need to be
+ // supported by the same WatchpointResource, e.g. a watchpoint
+ // watching 1 byte at 0x102 and a watchpoint watching 1 byte at 0x103.
+ // They're in the same word and must be watched by a single hardware
+ // watchpoint register.
+
std::unique_lock<std::recursive_mutex> lock;
this->GetWatchpointList().GetListMutex(lock);
WatchpointSP matched_sp = m_watchpoint_list.FindByAddress(addr);
@@ -907,7 +919,7 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
wp_sp->SetEnabled(false, notify);
} else {
// Nil the matched watchpoint; we will be creating a new one.
- m_process_sp->DisableWatchpoint(matched_sp.get(), notify);
+ m_process_sp->DisableWatchpoint(matched_sp, notify);
m_watchpoint_list.Remove(matched_sp->GetID(), true);
}
}
@@ -918,7 +930,7 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
m_watchpoint_list.Add(wp_sp, true);
}
- error = m_process_sp->EnableWatchpoint(wp_sp.get(), notify);
+ error = m_process_sp->EnableWatchpoint(wp_sp, notify);
LLDB_LOGF(log, "Target::%s (creation of watchpoint %s with id = %u)\n",
__FUNCTION__, error.Success() ? "succeeded" : "failed",
wp_sp->GetID());
@@ -927,11 +939,6 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
// Enabling the watchpoint on the device side failed. Remove the said
// watchpoint from the list maintained by the target instance.
m_watchpoint_list.Remove(wp_sp->GetID(), true);
- // See if we could provide more helpful error message.
- if (!OptionGroupWatchpoint::IsWatchSizeSupported(size))
- error.SetErrorStringWithFormat(
- "watch size of %" PRIu64 " is not supported", (uint64_t)size);
-
wp_sp.reset();
} else
m_last_created_watchpoint = wp_sp;
@@ -1231,7 +1238,7 @@ bool Target::RemoveAllWatchpoints(bool end_to_end) {
if (!wp_sp)
return false;
- Status rc = m_process_sp->DisableWatchpoint(wp_sp.get());
+ Status rc = m_process_sp->DisableWatchpoint(wp_sp);
if (rc.Fail())
return false;
}
@@ -1260,7 +1267,7 @@ bool Target::DisableAllWatchpoints(bool end_to_end) {
if (!wp_sp)
return false;
- Status rc = m_process_sp->DisableWatchpoint(wp_sp.get());
+ Status rc = m_process_sp->DisableWatchpoint(wp_sp);
if (rc.Fail())
return false;
}
@@ -1287,7 +1294,7 @@ bool Target::EnableAllWatchpoints(bool end_to_end) {
if (!wp_sp)
return false;
- Status rc = m_process_sp->EnableWatchpoint(wp_sp.get());
+ Status rc = m_process_sp->EnableWatchpoint(wp_sp);
if (rc.Fail())
return false;
}
@@ -1350,7 +1357,7 @@ bool Target::DisableWatchpointByID(lldb::watch_id_t watch_id) {
WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id);
if (wp_sp) {
- Status rc = m_process_sp->DisableWatchpoint(wp_sp.get());
+ Status rc = m_process_sp->DisableWatchpoint(wp_sp);
if (rc.Success())
return true;
@@ -1369,7 +1376,7 @@ bool Target::EnableWatchpointByID(lldb::watch_id_t watch_id) {
WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id);
if (wp_sp) {
- Status rc = m_process_sp->EnableWatchpoint(wp_sp.get());
+ Status rc = m_process_sp->EnableWatchpoint(wp_sp);
if (rc.Success())
return true;
diff --git a/lldb/source/Target/ThreadPlanCallFunction.cpp b/lldb/source/Target/ThreadPlanCallFunction.cpp
index 31027cd..50dcb66 100644
--- a/lldb/source/Target/ThreadPlanCallFunction.cpp
+++ b/lldb/source/Target/ThreadPlanCallFunction.cpp
@@ -291,10 +291,10 @@ bool ThreadPlanCallFunction::DoPlanExplainsStop(Event *event_ptr) {
BreakpointSiteSP bp_site_sp;
bp_site_sp = m_process.GetBreakpointSiteList().FindByID(break_site_id);
if (bp_site_sp) {
- uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
+ uint32_t num_owners = bp_site_sp->GetNumberOfConstituents();
bool is_internal = true;
for (uint32_t i = 0; i < num_owners; i++) {
- Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
+ Breakpoint &bp = bp_site_sp->GetConstituentAtIndex(i)->GetBreakpoint();
LLDB_LOGF(log,
"ThreadPlanCallFunction::PlanExplainsStop: hit "
"breakpoint %d while calling function",
diff --git a/lldb/source/Target/ThreadPlanStepOut.cpp b/lldb/source/Target/ThreadPlanStepOut.cpp
index 7bf1d2a..0a1e2ae 100644
--- a/lldb/source/Target/ThreadPlanStepOut.cpp
+++ b/lldb/source/Target/ThreadPlanStepOut.cpp
@@ -322,7 +322,7 @@ bool ThreadPlanStepOut::DoPlanExplainsStop(Event *event_ptr) {
// important to report the user breakpoint than the step out
// completion.
- if (site_sp->GetNumberOfOwners() == 1)
+ if (site_sp->GetNumberOfConstituents() == 1)
return true;
}
return false;
diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp
index 0d5144d..bb92adc 100644
--- a/lldb/source/Target/ThreadPlanStepRange.cpp
+++ b/lldb/source/Target/ThreadPlanStepRange.cpp
@@ -400,14 +400,14 @@ bool ThreadPlanStepRange::NextRangeBreakpointExplainsStop(
return false;
else {
// If we've hit the next branch breakpoint, then clear it.
- size_t num_owners = bp_site_sp->GetNumberOfOwners();
+ size_t num_constituents = bp_site_sp->GetNumberOfConstituents();
bool explains_stop = true;
- // If all the owners are internal, then we are probably just stepping over
- // this range from multiple threads, or multiple frames, so we want to
+ // If all the constituents are internal, then we are probably just stepping
+ // over this range from multiple threads, or multiple frames, so we want to
// continue. If one is not internal, then we should not explain the stop,
// and let the user breakpoint handle the stop.
- for (size_t i = 0; i < num_owners; i++) {
- if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal()) {
+ for (size_t i = 0; i < num_constituents; i++) {
+ if (!bp_site_sp->GetConstituentAtIndex(i)->GetBreakpoint().IsInternal()) {
explains_stop = false;
break;
}
@@ -415,8 +415,8 @@ bool ThreadPlanStepRange::NextRangeBreakpointExplainsStop(
LLDB_LOGF(log,
"ThreadPlanStepRange::NextRangeBreakpointExplainsStop - Hit "
"next range breakpoint which has %" PRIu64
- " owners - explains stop: %u.",
- (uint64_t)num_owners, explains_stop);
+ " constituents - explains stop: %u.",
+ (uint64_t)num_constituents, explains_stop);
ClearNextBranchBreakpoint();
return explains_stop;
}
diff --git a/lldb/source/Target/ThreadPlanStepUntil.cpp b/lldb/source/Target/ThreadPlanStepUntil.cpp
index f63e97d..ee0f803 100644
--- a/lldb/source/Target/ThreadPlanStepUntil.cpp
+++ b/lldb/source/Target/ThreadPlanStepUntil.cpp
@@ -182,7 +182,7 @@ void ThreadPlanStepUntil::AnalyzeStop() {
} else
m_should_stop = false;
- if (this_site->GetNumberOfOwners() == 1)
+ if (this_site->GetNumberOfConstituents() == 1)
m_explains_stop = true;
else
m_explains_stop = false;
@@ -228,7 +228,7 @@ void ThreadPlanStepUntil::AnalyzeStop() {
// only breakpoint here, then we do explain the stop, and we'll
// continue. If not then we should let higher plans handle this
// stop.
- if (this_site->GetNumberOfOwners() == 1)
+ if (this_site->GetNumberOfConstituents() == 1)
m_explains_stop = true;
else {
m_should_stop = true;