[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-28 Thread David Spickett via lldb-commits

DavidSpickett wrote:

I've reverted this due to failures on Linaro's Linux bots.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-27 Thread via lldb-commits

dyung wrote:

> Seems that it caused #73580 no?

I believe so. @jasonmolenda I see you attempted to make a fix in 
a0a1ff3ab40e347589b4e27d8fd350c600526735, however I still have two buildbots 
that are failing to build. Can you either fix it or revert if you need time to 
investigate?

https://lab.llvm.org/buildbot/#/builders/217/builds/31915
https://lab.llvm.org/buildbot/#/builders/243/builds/16118

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-27 Thread Sylvestre Ledru via lldb-commits

sylvestre wrote:

Seems that it caused https://github.com/llvm/llvm-project/issues/73580 no?


https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-27 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda closed 
https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-27 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere approved this pull request.


https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-27 Thread Jonas Devlieghere via lldb-commits


@@ -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 
+
+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::StopPointSiteContainsBreakpoint(
+typename BreakpointSite::SiteID site_id, lldb::break_id_t bp_id) {
+  std::lock_guard guard(m_mutex);
+  typename collection::const_iterator pos = GetIDConstIterator(site_id);

JDevlieghere wrote:

This would be a good candidate for `auto`.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-15 Thread Alex Langford via lldb-commits

https://github.com/bulbazord approved this pull request.

LGTM as well. I like the name Constituents quite a bit as well! 

I think most feedback at this point can probably be handled in follow-ups, esp. 
since some of it pertains to existing interfaces. 

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-15 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

> LGTM with a few nits. I like "constituents".
> 
> This is a pretty big patch which makes reviewing it challenging. I know it's 
> a big change that touches a lot of things but I'm sure that this could've 
> been broken up into smaller patches if you keep that goal in mind from the 
> beginning. Something to look out for in the future.

Thanks for the feedback.  Yeah originally this patch was a bit smaller but it 
has Grown as I've addressed (correct, good) feedback from everyone and now it's 
a little bit of a monster.  I'm surely going to have to rebase it before I can 
merge.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-15 Thread Jason Molenda via lldb-commits


@@ -1787,30 +1788,48 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
   // addresses should be provided as \a wp_addr.
   StringExtractor desc_extractor(description.c_str());
   addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
-  uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32);
+  wp_resource_id_t wp_hw_index =
+  desc_extractor.GetU32(LLDB_INVALID_WATCHPOINT_RESOURCE_ID);
   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_hw_index != LLDB_INVALID_WATCHPOINT_RESOURCE_ID) {
+wp_resource_sp = m_watchpoint_resource_list.FindByID(wp_hw_index);
+if (wp_resource_sp) {
+  // If we were given an access address, and the Resource we
+  // found by watchpoint register index does not contain that
+  // address, then the wp_resource_id's have not tracked the
+  // hardware watchpoint registers correctly, discard this
+  // Resource found by ID and look it up by access address.
+  if (wp_hit_addr != LLDB_INVALID_ADDRESS &&
+  !wp_resource_sp->Contains(wp_hit_addr)) {
+wp_resource_sp.reset();
+  }
+}
+  }
   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) {
-wp_sp->SetHardwareIndex(wp_index);
-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");
+abort(); // LWP_TODO FIXME don't continue executing this block if

jasonmolenda wrote:

My refactored code added a new nullptr deref, when I saw what I'd done I threw 
in an abort and a FIXME comment to fix that.  But I see how to fix it, let me 
do that.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-15 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,235 @@
+//===-- 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 
+
+using namespace lldb;
+using namespace lldb_private;
+
+// Add site to the list.  However, if the element already exists in
+// the list, then we don't add it, and return InvalidSiteID.
+
+template 
+typename StopPointSite::SiteID
+StopPointSiteList::Add(const StopPointSiteSP ) {
+  lldb::addr_t site_load_addr = site->GetLoadAddress();
+  std::lock_guard guard(m_mutex);
+  typename collection::iterator iter = m_site_list.find(site_load_addr);
+
+  if (iter == m_site_list.end()) {
+#if 0
+m_site_list.insert(iter, collection::value_type(site_load_addr, site));
+#endif
+m_site_list[site_load_addr] = site;
+return site->GetID();
+  } else {
+return UINT32_MAX;
+  }
+}
+
+template 
+bool StopPointSiteList::ShouldStop(
+StoppointCallbackContext *context, typename StopPointSite::SiteID site_id) 
{
+  StopPointSiteSP site_sp(FindByID(site_id));
+  if (site_sp) {
+// Let the site 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 site isn't valid anymore or it
+  // doesn't exist.
+  return true;
+}
+
+template 
+typename StopPointSite::SiteID
+StopPointSiteList::FindIDByAddress(lldb::addr_t addr) {
+  if (StopPointSiteSP site = FindByAddress(addr))
+return site->GetID();
+  return UINT32_MAX;
+}
+
+template 
+bool StopPointSiteList::Remove(
+typename StopPointSite::SiteID site_id) {
+  std::lock_guard guard(m_mutex);
+  typename collection::iterator pos = GetIDIterator(site_id); // Predicate
+  if (pos != m_site_list.end()) {
+m_site_list.erase(pos);
+return true;
+  }
+  return false;
+}
+
+template 
+bool StopPointSiteList::RemoveByAddress(lldb::addr_t address) {
+  std::lock_guard guard(m_mutex);
+  typename collection::iterator pos = m_site_list.find(address);
+  if (pos != m_site_list.end()) {
+m_site_list.erase(pos);
+return true;
+  }
+  return false;
+}
+
+template 
+typename StopPointSiteList::collection::iterator
+StopPointSiteList::GetIDIterator(
+typename StopPointSite::SiteID site_id) {
+  std::lock_guard guard(m_mutex);
+  auto id_matches = [site_id](const std::pair s) {
+return site_id == s.second->GetID();
+  };
+  return std::find_if(m_site_list.begin(),
+  m_site_list.end(), // Search full range
+  id_matches);
+}
+
+template 
+typename StopPointSiteList::collection::const_iterator
+StopPointSiteList::GetIDConstIterator(
+typename StopPointSite::SiteID site_id) const {
+  std::lock_guard guard(m_mutex);
+  auto id_matches = [site_id](const std::pair s) {
+return site_id == s.second->GetID();
+  };
+  return std::find_if(m_site_list.begin(),
+  m_site_list.end(), // Search full range
+  id_matches);
+}
+
+template 
+typename StopPointSiteList::StopPointSiteSP
+StopPointSiteList::FindByID(
+typename StopPointSite::SiteID site_id) {
+  std::lock_guard guard(m_mutex);
+  StopPointSiteSP stop_sp;
+  typename collection::iterator pos = GetIDIterator(site_id);
+  if (pos != m_site_list.end())
+stop_sp = pos->second;
+
+  return stop_sp;
+}
+
+template 
+const typename StopPointSiteList::StopPointSiteSP
+StopPointSiteList::FindByID(
+typename StopPointSite::SiteID site_id) const {
+  std::lock_guard guard(m_mutex);
+  StopPointSiteSP stop_sp;
+  typename collection::const_iterator pos = GetIDConstIterator(site_id);
+  if (pos != m_site_list.end())
+stop_sp = pos->second;
+
+  return stop_sp;
+}
+
+template 
+typename StopPointSiteList::StopPointSiteSP
+StopPointSiteList::FindByAddress(lldb::addr_t addr) {
+  StopPointSiteSP found_sp;
+  std::lock_guard guard(m_mutex);
+  typename collection::iterator iter = m_site_list.find(addr);
+  if (iter != m_site_list.end())
+found_sp = iter->second;
+  return found_sp;
+}
+
+// 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::StopPointSiteContainsBreakpoint(
+typename BreakpointSite::SiteID site_id, break_id_t bp_id) {
+  std::lock_guard guard(m_mutex);
+  typename collection::const_iterator pos = 

[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-15 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,235 @@
+//===-- 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 
+
+using namespace lldb;
+using namespace lldb_private;
+
+// Add site to the list.  However, if the element already exists in
+// the list, then we don't add it, and return InvalidSiteID.
+
+template 
+typename StopPointSite::SiteID
+StopPointSiteList::Add(const StopPointSiteSP ) {
+  lldb::addr_t site_load_addr = site->GetLoadAddress();
+  std::lock_guard guard(m_mutex);
+  typename collection::iterator iter = m_site_list.find(site_load_addr);
+
+  if (iter == m_site_list.end()) {
+#if 0
+m_site_list.insert(iter, collection::value_type(site_load_addr, site));
+#endif
+m_site_list[site_load_addr] = site;
+return site->GetID();
+  } else {
+return UINT32_MAX;
+  }
+}
+
+template 
+bool StopPointSiteList::ShouldStop(
+StoppointCallbackContext *context, typename StopPointSite::SiteID site_id) 
{
+  StopPointSiteSP site_sp(FindByID(site_id));
+  if (site_sp) {
+// Let the site 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 site isn't valid anymore or it
+  // doesn't exist.
+  return true;
+}
+
+template 
+typename StopPointSite::SiteID
+StopPointSiteList::FindIDByAddress(lldb::addr_t addr) {
+  if (StopPointSiteSP site = FindByAddress(addr))
+return site->GetID();
+  return UINT32_MAX;
+}
+
+template 
+bool StopPointSiteList::Remove(
+typename StopPointSite::SiteID site_id) {
+  std::lock_guard guard(m_mutex);
+  typename collection::iterator pos = GetIDIterator(site_id); // Predicate
+  if (pos != m_site_list.end()) {
+m_site_list.erase(pos);
+return true;
+  }
+  return false;
+}
+
+template 
+bool StopPointSiteList::RemoveByAddress(lldb::addr_t address) {
+  std::lock_guard guard(m_mutex);
+  typename collection::iterator pos = m_site_list.find(address);
+  if (pos != m_site_list.end()) {
+m_site_list.erase(pos);
+return true;
+  }
+  return false;
+}
+
+template 
+typename StopPointSiteList::collection::iterator
+StopPointSiteList::GetIDIterator(
+typename StopPointSite::SiteID site_id) {
+  std::lock_guard guard(m_mutex);
+  auto id_matches = [site_id](const std::pair s) {
+return site_id == s.second->GetID();
+  };
+  return std::find_if(m_site_list.begin(),
+  m_site_list.end(), // Search full range
+  id_matches);
+}
+
+template 
+typename StopPointSiteList::collection::const_iterator
+StopPointSiteList::GetIDConstIterator(
+typename StopPointSite::SiteID site_id) const {
+  std::lock_guard guard(m_mutex);
+  auto id_matches = [site_id](const std::pair s) {
+return site_id == s.second->GetID();
+  };
+  return std::find_if(m_site_list.begin(),
+  m_site_list.end(), // Search full range
+  id_matches);
+}
+
+template 
+typename StopPointSiteList::StopPointSiteSP
+StopPointSiteList::FindByID(
+typename StopPointSite::SiteID site_id) {
+  std::lock_guard guard(m_mutex);
+  StopPointSiteSP stop_sp;
+  typename collection::iterator pos = GetIDIterator(site_id);
+  if (pos != m_site_list.end())
+stop_sp = pos->second;
+
+  return stop_sp;
+}
+
+template 
+const typename StopPointSiteList::StopPointSiteSP
+StopPointSiteList::FindByID(
+typename StopPointSite::SiteID site_id) const {
+  std::lock_guard guard(m_mutex);
+  StopPointSiteSP stop_sp;
+  typename collection::const_iterator pos = GetIDConstIterator(site_id);
+  if (pos != m_site_list.end())
+stop_sp = pos->second;
+
+  return stop_sp;
+}
+
+template 
+typename StopPointSiteList::StopPointSiteSP
+StopPointSiteList::FindByAddress(lldb::addr_t addr) {
+  StopPointSiteSP found_sp;
+  std::lock_guard guard(m_mutex);
+  typename collection::iterator iter = m_site_list.find(addr);
+  if (iter != m_site_list.end())
+found_sp = iter->second;
+  return found_sp;
+}
+
+// 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::StopPointSiteContainsBreakpoint(
+typename BreakpointSite::SiteID site_id, break_id_t bp_id) {
+  std::lock_guard guard(m_mutex);
+  typename collection::const_iterator pos = 

[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-15 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,235 @@
+//===-- 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 
+
+using namespace lldb;
+using namespace lldb_private;
+
+// Add site to the list.  However, if the element already exists in
+// the list, then we don't add it, and return InvalidSiteID.
+
+template 
+typename StopPointSite::SiteID
+StopPointSiteList::Add(const StopPointSiteSP ) {
+  lldb::addr_t site_load_addr = site->GetLoadAddress();
+  std::lock_guard guard(m_mutex);
+  typename collection::iterator iter = m_site_list.find(site_load_addr);
+
+  if (iter == m_site_list.end()) {
+#if 0
+m_site_list.insert(iter, collection::value_type(site_load_addr, site));
+#endif

JDevlieghere wrote:

Remove.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-15 Thread Jonas Devlieghere via lldb-commits


@@ -1787,30 +1788,48 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
   // addresses should be provided as \a wp_addr.
   StringExtractor desc_extractor(description.c_str());
   addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
-  uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32);
+  wp_resource_id_t wp_hw_index =
+  desc_extractor.GetU32(LLDB_INVALID_WATCHPOINT_RESOURCE_ID);
   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_hw_index != LLDB_INVALID_WATCHPOINT_RESOURCE_ID) {
+wp_resource_sp = m_watchpoint_resource_list.FindByID(wp_hw_index);
+if (wp_resource_sp) {
+  // If we were given an access address, and the Resource we
+  // found by watchpoint register index does not contain that
+  // address, then the wp_resource_id's have not tracked the
+  // hardware watchpoint registers correctly, discard this
+  // Resource found by ID and look it up by access address.
+  if (wp_hit_addr != LLDB_INVALID_ADDRESS &&
+  !wp_resource_sp->Contains(wp_hit_addr)) {
+wp_resource_sp.reset();
+  }
+}
+  }
   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) {
-wp_sp->SetHardwareIndex(wp_index);
-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");
+abort(); // LWP_TODO FIXME don't continue executing this block if

JDevlieghere wrote:

??

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-15 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,235 @@
+//===-- 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 
+
+using namespace lldb;
+using namespace lldb_private;
+
+// Add site to the list.  However, if the element already exists in
+// the list, then we don't add it, and return InvalidSiteID.
+
+template 
+typename StopPointSite::SiteID
+StopPointSiteList::Add(const StopPointSiteSP ) {
+  lldb::addr_t site_load_addr = site->GetLoadAddress();
+  std::lock_guard guard(m_mutex);
+  typename collection::iterator iter = m_site_list.find(site_load_addr);
+
+  if (iter == m_site_list.end()) {
+#if 0
+m_site_list.insert(iter, collection::value_type(site_load_addr, site));
+#endif
+m_site_list[site_load_addr] = site;
+return site->GetID();
+  } else {
+return UINT32_MAX;
+  }
+}
+
+template 
+bool StopPointSiteList::ShouldStop(
+StoppointCallbackContext *context, typename StopPointSite::SiteID site_id) 
{
+  StopPointSiteSP site_sp(FindByID(site_id));
+  if (site_sp) {

JDevlieghere wrote:

```if(StopPointSiteSP site_sp = FindByID(site_id))``` 

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-15 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,235 @@
+//===-- 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 
+
+using namespace lldb;
+using namespace lldb_private;
+
+// Add site to the list.  However, if the element already exists in
+// the list, then we don't add it, and return InvalidSiteID.
+
+template 
+typename StopPointSite::SiteID
+StopPointSiteList::Add(const StopPointSiteSP ) {
+  lldb::addr_t site_load_addr = site->GetLoadAddress();
+  std::lock_guard guard(m_mutex);
+  typename collection::iterator iter = m_site_list.find(site_load_addr);
+
+  if (iter == m_site_list.end()) {
+#if 0
+m_site_list.insert(iter, collection::value_type(site_load_addr, site));
+#endif
+m_site_list[site_load_addr] = site;
+return site->GetID();
+  } else {
+return UINT32_MAX;
+  }
+}
+
+template 
+bool StopPointSiteList::ShouldStop(
+StoppointCallbackContext *context, typename StopPointSite::SiteID site_id) 
{
+  StopPointSiteSP site_sp(FindByID(site_id));
+  if (site_sp) {
+// Let the site 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 site isn't valid anymore or it
+  // doesn't exist.
+  return true;
+}
+
+template 
+typename StopPointSite::SiteID
+StopPointSiteList::FindIDByAddress(lldb::addr_t addr) {
+  if (StopPointSiteSP site = FindByAddress(addr))
+return site->GetID();
+  return UINT32_MAX;
+}
+
+template 
+bool StopPointSiteList::Remove(
+typename StopPointSite::SiteID site_id) {
+  std::lock_guard guard(m_mutex);
+  typename collection::iterator pos = GetIDIterator(site_id); // Predicate
+  if (pos != m_site_list.end()) {
+m_site_list.erase(pos);
+return true;
+  }
+  return false;
+}
+
+template 
+bool StopPointSiteList::RemoveByAddress(lldb::addr_t address) {
+  std::lock_guard guard(m_mutex);
+  typename collection::iterator pos = m_site_list.find(address);
+  if (pos != m_site_list.end()) {
+m_site_list.erase(pos);
+return true;
+  }
+  return false;
+}
+
+template 
+typename StopPointSiteList::collection::iterator
+StopPointSiteList::GetIDIterator(
+typename StopPointSite::SiteID site_id) {
+  std::lock_guard guard(m_mutex);
+  auto id_matches = [site_id](const std::pair s) {
+return site_id == s.second->GetID();
+  };
+  return std::find_if(m_site_list.begin(),
+  m_site_list.end(), // Search full range
+  id_matches);
+}
+
+template 
+typename StopPointSiteList::collection::const_iterator
+StopPointSiteList::GetIDConstIterator(
+typename StopPointSite::SiteID site_id) const {
+  std::lock_guard guard(m_mutex);
+  auto id_matches = [site_id](const std::pair s) {
+return site_id == s.second->GetID();
+  };
+  return std::find_if(m_site_list.begin(),
+  m_site_list.end(), // Search full range
+  id_matches);
+}
+
+template 
+typename StopPointSiteList::StopPointSiteSP
+StopPointSiteList::FindByID(
+typename StopPointSite::SiteID site_id) {
+  std::lock_guard guard(m_mutex);
+  StopPointSiteSP stop_sp;
+  typename collection::iterator pos = GetIDIterator(site_id);
+  if (pos != m_site_list.end())
+stop_sp = pos->second;
+
+  return stop_sp;
+}
+
+template 
+const typename StopPointSiteList::StopPointSiteSP
+StopPointSiteList::FindByID(
+typename StopPointSite::SiteID site_id) const {
+  std::lock_guard guard(m_mutex);
+  StopPointSiteSP stop_sp;
+  typename collection::const_iterator pos = GetIDConstIterator(site_id);
+  if (pos != m_site_list.end())
+stop_sp = pos->second;
+
+  return stop_sp;
+}
+
+template 
+typename StopPointSiteList::StopPointSiteSP
+StopPointSiteList::FindByAddress(lldb::addr_t addr) {
+  StopPointSiteSP found_sp;
+  std::lock_guard guard(m_mutex);
+  typename collection::iterator iter = m_site_list.find(addr);
+  if (iter != m_site_list.end())
+found_sp = iter->second;
+  return found_sp;
+}
+
+// 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::StopPointSiteContainsBreakpoint(
+typename BreakpointSite::SiteID site_id, break_id_t bp_id) {
+  std::lock_guard guard(m_mutex);
+  typename collection::const_iterator pos = 

[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-15 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere approved this pull request.

LGTM with a few nits. I like "constituents". 

This is a pretty big patch which makes reviewing it challenging. I know it's a 
big change that touches a lot of things but I'm sure that this could've been 
broken up into smaller patches if you keep that goal in mind from the 
beginning. Something to look out for in the future. 

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-11-15 Thread Jonas Devlieghere via lldb-commits

https://github.com/JDevlieghere edited 
https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-30 Thread Jason Molenda via lldb-commits


@@ -0,0 +1,146 @@
+//===-- WatchpointResourceList.h *- C++ 
-*-===//

jasonmolenda wrote:

I think it's the same except for the obvious BreakpointSite/WatchpointResource 
and BreakpointLocation/Watchpoint.  It's a little tricky reading through 
BreakpointSiteList.h to tell if all of the arguments refer to 
BreakpointLocations (they do it by id values) or if they might refer to 
Breakpoints - they seem to all use the same `break_id_t`?  (and `break_id_t` is 
also used for the BreakpointSite numbers); sometimes the arguments are called 
`bp_id` and sometimes they're called `BreakID` but I THINK they're always 
referring to BreakpointLocations.

It'd be nice if BreakpointSite and WatchpointResource could inherit from the 
same base class and have the StopPointList work in terms of the base class 
methods, but I think there's enough difference between these two that this 
might not work very cleanly.

Maybe a templated StopPointList could work though.  I'll need to look at that.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-30 Thread Jason Molenda via lldb-commits


@@ -266,33 +268,73 @@ 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;

jasonmolenda wrote:

The convention for these methods seems to be to return a stream without a final 
end-of-line character.  In StopInfo.cpp we call this method and check if it 
printed anything, and if so, print an EOL.  In Watchpoint::DumpWithLevel we 
ignore the return type from DumpSnapshots, but that's only because every line 
it adds is assumed to end without an EOL.  I don't really need a variable in 
this method, I could return false in the two places it is false and true in the 
one place it is true.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-30 Thread Jason Molenda via lldb-commits


@@ -0,0 +1,155 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Utility/Iterable.h"
+#include "lldb/lldb-public.h"
+
+#include 
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  bool WatchpointResourceRead() const;
+
+  bool WatchpointResourceWrite() const;
+
+  void SetType(bool read, bool write);
+
+  typedef std::vector WatchpointCollection;
+  typedef LockingAdaptedIterable
+  WatchpointIterable;
+
+  /// Iterate over the watchpoint owners for this resource
+  ///
+  /// \return
+  /// An Iterable object which can be used to loop over the watchpoints
+  /// that are owners of this resource.
+  WatchpointIterable Owners() {
+return WatchpointIterable(m_owners, m_owners_mutex);
+  }
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp_sp
+  /// The WatchpointSP to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(lldb::WatchpointSP _sp);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp
+  /// The Watchpoint to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(const lldb_private::Watchpoint *wp);
+
+  /// This method copies the watchpoint resource's owners into a new 
collection.
+  /// It does this while the owners mutex is locked.
+  ///
+  /// \param[out] out_collection
+  ///The BreakpointLocationCollection into which to put the owners
+  ///of this breakpoint site.
+  ///
+  /// \return
+  ///The number of elements copied into out_collection.
+  size_t CopyOwnersList(WatchpointCollection _collection);
+
+  // The ID of the WatchpointResource is set by the WatchpointResourceList
+  // when the Resource has been set in the inferior and is being added
+  // to the List, in an attempt to match the hardware watchpoint register
+  // ordering.  If a Process can correctly identify the hardware watchpoint
+  // register index when it has created the Resource, it may initialize it
+  // before it is inserted in the WatchpointResourceList.
+  void SetID(lldb::wp_resource_id_t);
+
+  lldb::wp_resource_id_t GetID() const;
+
+  bool Contains(lldb::addr_t addr);
+
+protected:
+  // The StopInfoWatchpoint knows when it is processing a hit for a thread for
+  // a site, so let it be the one to manage setting the location hit count once
+  // and only once.
+  friend class StopInfoWatchpoint;
+
+  void BumpHitCounts();
+
+private:
+  lldb::wp_resource_id_t m_id;
+
+  // start address & size aligned & expanded to be a valid watchpoint
+  // memory granule on this target.
+  lldb::addr_t m_addr;
+  size_t m_size;
+
+  bool m_watch_read;  // true if we stop when the watched data is read from
+  bool m_watch_write; // true if we stop when the watched data is written to
+
+  // The watchpoints using this WatchpointResource.
+  WatchpointCollection m_owners;
+
+  std::recursive_mutex
+  m_owners_mutex; ///< This mutex protects the owners collection.

jasonmolenda wrote:

No, I was just copying BreakpointSite when I used that.

https://github.com/llvm/llvm-project/pull/68845
___

[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-30 Thread Jason Molenda via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);

jasonmolenda wrote:

Just getting back to the review comments.  I remember writing something about 
this last week but we have some API to select specific BreakpointLocations that 
own the BreakpointSite and the code to do that is most naturally exposed as 
"GetAtIndex" style access.  I'm trying to create the WatchpointResource class 
similar to BreakpointSite so I can follow the same coding style for these 
Watchpoints that own the WatchpointResources.  I may end up being able to drop 
the GetAtIndex method later if it's natural go access it via an Owners method, 
but I'm starting with the assumption that this will be more natural.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-26 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp_sp
+  /// The WatchpointSP to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(lldb::WatchpointSP _sp);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp
+  /// The Watchpoint to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(const lldb_private::Watchpoint *wp);
+
+  /// This method copies the watchpoint resource's owners into a new 
collection.
+  /// It does this while the owners mutex is locked.
+  ///
+  /// \param[out] out_collection
+  ///The BreakpointLocationCollection into which to put the owners
+  ///of this breakpoint site.
+  ///
+  /// \return
+  ///The number of elements copied into out_collection.
+  size_t CopyOwnersList(WatchpointCollection _collection);
+
+  // The ID of the WatchpointResource is set by the WatchpointResourceList
+  // when the Resource has been set in the inferior and is being added
+  // to the List, in an attempt to match the hardware watchpoint register
+  // ordering.  If a Process can correctly identify the hardware watchpoint
+  // register index when it has created the Resource, it may initialize it
+  // before it is inserted in the WatchpointResourceList.
+  void SetID(lldb::wp_resource_id_t);
+
+  lldb::wp_resource_id_t GetID() const;
+
+  bool Contains(lldb::addr_t addr);
+
+protected:
+  // The StopInfoWatchpoint knows when it is processing a hit for a thread for
+  // a site, so let it be the one to manage setting the location hit count once
+  // and only once.
+  friend class StopInfoWatchpoint;
+
+  void BumpHitCounts();
+
+private:
+  lldb::wp_resource_id_t m_id;
+
+  // start address & size aligned & expanded to be a valid watchpoint
+  // memory granule on this target.
+  lldb::addr_t m_addr;
+  size_t m_size;
+
+  bool m_watch_read;  // true if we stop when the watched data is read from
+  bool m_watch_write; // true if we stop when the watched data is written to

JDevlieghere wrote:

+1. Otherwise they should go above the line, with `///` and make it a 
capitalized sentence with a period. 

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-26 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,146 @@
+//===-- WatchpointResourceList.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_BREAKPOINT_WATCHPOINTRESOURCELIST_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCELIST_H
+
+#include "lldb/Utility/Iterable.h"
+#include "lldb/lldb-private.h"
+#include "lldb/lldb-public.h"
+
+#include 
+#include 
+
+namespace lldb_private {
+
+class WatchpointResourceList {
+
+public:
+  // Constructors and Destructors

JDevlieghere wrote:

Remove

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-26 Thread Jonas Devlieghere via lldb-commits


@@ -266,33 +268,73 @@ 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;

JDevlieghere wrote:

Doesn't look like you actually need this. You change the value exactly once 
below. I would just return false on line 276 and 337 and true on line 334. I 
think the return value of a `Dump` function is more self explanatory than 
having to scroll up and see if `printed_anything` happened to be modified in 
the 50 lines between 275 and 325. 

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-26 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,97 @@
+//===-- 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 "lldb/Breakpoint/WatchpointResource.h"
+#include "lldb/Utility/LLDBAssert.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+WatchpointResource::WatchpointResource(lldb::addr_t addr, size_t size,
+   bool read, bool write)
+: m_id(LLDB_INVALID_WATCHPOINT_RESOURCE_ID), m_addr(addr), m_size(size),
+  m_watch_read(read), m_watch_write(write) {}
+
+WatchpointResource::~WatchpointResource() {
+  std::lock_guard guard(m_owners_mutex);
+  m_owners.clear();
+}
+
+addr_t WatchpointResource::GetAddress() 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::AddOwner(const WatchpointSP _sp) {
+  std::lock_guard guard(m_owners_mutex);
+  m_owners.push_back(wp_sp);
+}
+
+void WatchpointResource::RemoveOwner(WatchpointSP _sp) {
+  std::lock_guard guard(m_owners_mutex);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  if (it != m_owners.end())
+m_owners.erase(it);
+}
+
+size_t WatchpointResource::GetNumberOfOwners() {
+  std::lock_guard guard(m_owners_mutex);
+  return m_owners.size();
+}
+
+bool WatchpointResource::OwnersContains(WatchpointSP _sp) {
+  std::lock_guard guard(m_owners_mutex);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  return it != m_owners.end();
+}
+
+bool WatchpointResource::OwnersContains(const Watchpoint *wp) {
+  std::lock_guard guard(m_owners_mutex);
+  WatchpointCollection::const_iterator match =
+  std::find_if(m_owners.begin(), m_owners.end(),
+   [](const WatchpointSP ) { return x.get() == wp; });
+  return match != m_owners.end();
+}
+
+WatchpointSP WatchpointResource::GetOwnerAtIndex(size_t idx) {
+  std::lock_guard guard(m_owners_mutex);
+  lldbassert(idx < m_owners.size());
+  if (idx >= m_owners.size())
+return {};
+
+  return m_owners[idx];
+}
+
+size_t
+WatchpointResource::CopyOwnersList(WatchpointCollection _collection) {
+  std::lock_guard guard(m_owners_mutex);
+  for (auto wp_sp : m_owners) {
+out_collection.push_back(wp_sp);
+  }

JDevlieghere wrote:

No braces

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-26 Thread Jonas Devlieghere via lldb-commits


@@ -331,6 +373,16 @@ void Watchpoint::DumpWithLevel(Stream *s,
 
 bool Watchpoint::IsEnabled() const { return m_enabled; }
 
+uint32_t Watchpoint::GetHardwareIndex() const {
+  if (IsEnabled())
+return m_target.GetProcessSP()
+->GetWatchpointResourceList()
+.FindByWatchpoint(this)
+->GetID();
+  else
+return UINT32_MAX;

JDevlieghere wrote:

+1

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-26 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,154 @@
+//===-- 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 _res_sp) {
+  Log *log = GetLog(LLDBLog::Watchpoints);
+  std::lock_guard guard(m_mutex);
+
+  LLDB_LOGF(log, "WatchpointResourceList::Add(addr 0x%" PRIx64 " size %zu)",
+wp_res_sp->GetAddress(), wp_res_sp->GetByteSize());
+
+  // The goal is to have the wp_resource_id_t match the actual hardware
+  // watchpoint register number.  If we assume that the remote stub is
+  // setting them in the register context in the same order that they
+  // are sent from lldb, and if a watchpoint is removed and then a new
+  // one is added and gets the same register number, then we can
+  // iterate over all used IDs looking for the first unused number.
+
+  // If the Process was able to find the actual hardware watchpoint register
+  // number that was used, it can set the ID for the WatchpointResource
+  // before we get here.
+
+  if (wp_res_sp->GetID() == LLDB_INVALID_WATCHPOINT_RESOURCE_ID) {
+std::set used_ids;
+size_t size = m_resources.size();
+for (size_t i = 0; i < size; ++i)
+  used_ids.insert(m_resources[i]->GetID());
+
+wp_resource_id_t best = 0;
+for (wp_resource_id_t id : used_ids)
+  if (id == best)
+best++;
+  else
+break;
+
+LLDB_LOGF(log,
+  "WatchpointResourceList::Add assigning next "
+  "available WatchpointResource ID, %u",
+  best);
+wp_res_sp->SetID(best);
+  }
+
+  m_resources.push_back(wp_res_sp);
+  return wp_res_sp->GetID();
+}
+
+bool WatchpointResourceList::Remove(wp_resource_id_t id) {
+  std::lock_guard 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)->GetAddress(), (*pos)->GetByteSize());
+  m_resources.erase(pos);
+  return true;
+}
+  }
+  return false;
+}
+
+bool WatchpointResourceList::RemoveByAddress(addr_t addr) {
+  std::lock_guard 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)->GetAddress(), (*pos)->GetByteSize());
+  m_resources.erase(pos);
+  return true;
+}
+  }
+  return false;
+}
+
+WatchpointResourceSP WatchpointResourceList::FindByAddress(addr_t addr) {
+  std::lock_guard guard(m_mutex);
+  for (collection::iterator pos = m_resources.begin(); pos != 
m_resources.end();
+   ++pos)
+if ((*pos)->Contains(addr))
+  return *pos;

JDevlieghere wrote:

Can you use a range-based for loop here and below?

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-26 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp_sp
+  /// The WatchpointSP to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(lldb::WatchpointSP _sp);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp
+  /// The Watchpoint to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(const lldb_private::Watchpoint *wp);
+
+  /// This method copies the watchpoint resource's owners into a new 
collection.
+  /// It does this while the owners mutex is locked.
+  ///
+  /// \param[out] out_collection
+  ///The BreakpointLocationCollection into which to put the owners
+  ///of this breakpoint site.
+  ///
+  /// \return
+  ///The number of elements copied into out_collection.
+  size_t CopyOwnersList(WatchpointCollection _collection);

JDevlieghere wrote:

Starting with C++17, copy elision is guaranteed. 

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-26 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,155 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Utility/Iterable.h"
+#include "lldb/lldb-public.h"
+
+#include 
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  bool WatchpointResourceRead() const;
+
+  bool WatchpointResourceWrite() const;
+
+  void SetType(bool read, bool write);
+
+  typedef std::vector WatchpointCollection;
+  typedef LockingAdaptedIterable
+  WatchpointIterable;
+
+  /// Iterate over the watchpoint owners for this resource
+  ///
+  /// \return
+  /// An Iterable object which can be used to loop over the watchpoints
+  /// that are owners of this resource.
+  WatchpointIterable Owners() {
+return WatchpointIterable(m_owners, m_owners_mutex);
+  }
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp_sp
+  /// The WatchpointSP to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(lldb::WatchpointSP _sp);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp
+  /// The Watchpoint to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(const lldb_private::Watchpoint *wp);
+
+  /// This method copies the watchpoint resource's owners into a new 
collection.
+  /// It does this while the owners mutex is locked.
+  ///
+  /// \param[out] out_collection
+  ///The BreakpointLocationCollection into which to put the owners
+  ///of this breakpoint site.
+  ///
+  /// \return
+  ///The number of elements copied into out_collection.
+  size_t CopyOwnersList(WatchpointCollection _collection);
+
+  // The ID of the WatchpointResource is set by the WatchpointResourceList
+  // when the Resource has been set in the inferior and is being added
+  // to the List, in an attempt to match the hardware watchpoint register
+  // ordering.  If a Process can correctly identify the hardware watchpoint
+  // register index when it has created the Resource, it may initialize it
+  // before it is inserted in the WatchpointResourceList.
+  void SetID(lldb::wp_resource_id_t);
+
+  lldb::wp_resource_id_t GetID() const;
+
+  bool Contains(lldb::addr_t addr);
+
+protected:
+  // The StopInfoWatchpoint knows when it is processing a hit for a thread for
+  // a site, so let it be the one to manage setting the location hit count once
+  // and only once.
+  friend class StopInfoWatchpoint;
+
+  void BumpHitCounts();
+
+private:
+  lldb::wp_resource_id_t m_id;
+
+  // start address & size aligned & expanded to be a valid watchpoint
+  // memory granule on this target.
+  lldb::addr_t m_addr;
+  size_t m_size;
+
+  bool m_watch_read;  // true if we stop when the watched data is read from
+  bool m_watch_write; // true if we stop when the watched data is written to
+
+  // The watchpoints using this WatchpointResource.
+  WatchpointCollection m_owners;
+
+  std::recursive_mutex
+  m_owners_mutex; ///< This mutex protects the owners collection.

JDevlieghere wrote:

Move the comment to the line above. Does this have to be a recursive mutex?

https://github.com/llvm/llvm-project/pull/68845

[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-26 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,155 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Utility/Iterable.h"
+#include "lldb/lldb-public.h"
+
+#include 
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  bool WatchpointResourceRead() const;
+
+  bool WatchpointResourceWrite() const;
+
+  void SetType(bool read, bool write);
+
+  typedef std::vector WatchpointCollection;
+  typedef LockingAdaptedIterable
+  WatchpointIterable;
+
+  /// Iterate over the watchpoint owners for this resource
+  ///
+  /// \return
+  /// An Iterable object which can be used to loop over the watchpoints
+  /// that are owners of this resource.
+  WatchpointIterable Owners() {
+return WatchpointIterable(m_owners, m_owners_mutex);
+  }
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp_sp
+  /// The WatchpointSP to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(lldb::WatchpointSP _sp);

JDevlieghere wrote:

Does this method care about the shared pointer or the underlying watchpoint? If 
it's the former, the docs should make that explicit. 

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-26 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,155 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Utility/Iterable.h"
+#include "lldb/lldb-public.h"
+
+#include 
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  bool WatchpointResourceRead() const;
+
+  bool WatchpointResourceWrite() const;
+
+  void SetType(bool read, bool write);
+
+  typedef std::vector WatchpointCollection;
+  typedef LockingAdaptedIterable
+  WatchpointIterable;
+
+  /// Iterate over the watchpoint owners for this resource
+  ///
+  /// \return
+  /// An Iterable object which can be used to loop over the watchpoints
+  /// that are owners of this resource.
+  WatchpointIterable Owners() {
+return WatchpointIterable(m_owners, m_owners_mutex);
+  }
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp_sp
+  /// The WatchpointSP to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(lldb::WatchpointSP _sp);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp
+  /// The Watchpoint to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(const lldb_private::Watchpoint *wp);
+
+  /// This method copies the watchpoint resource's owners into a new 
collection.
+  /// It does this while the owners mutex is locked.
+  ///
+  /// \param[out] out_collection
+  ///The BreakpointLocationCollection into which to put the owners
+  ///of this breakpoint site.
+  ///
+  /// \return
+  ///The number of elements copied into out_collection.
+  size_t CopyOwnersList(WatchpointCollection _collection);
+
+  // The ID of the WatchpointResource is set by the WatchpointResourceList
+  // when the Resource has been set in the inferior and is being added
+  // to the List, in an attempt to match the hardware watchpoint register
+  // ordering.  If a Process can correctly identify the hardware watchpoint
+  // register index when it has created the Resource, it may initialize it
+  // before it is inserted in the WatchpointResourceList.
+  void SetID(lldb::wp_resource_id_t);
+
+  lldb::wp_resource_id_t GetID() const;
+
+  bool Contains(lldb::addr_t addr);
+
+protected:
+  // The StopInfoWatchpoint knows when it is processing a hit for a thread for
+  // a site, so let it be the one to manage setting the location hit count once
+  // and only once.
+  friend class StopInfoWatchpoint;
+
+  void BumpHitCounts();
+
+private:
+  lldb::wp_resource_id_t m_id;
+
+  // start address & size aligned & expanded to be a valid watchpoint
+  // memory granule on this target.
+  lldb::addr_t m_addr;
+  size_t m_size;
+
+  bool m_watch_read;  // true if we stop when the watched data is read from
+  bool m_watch_write; // true if we stop when the watched data is written to
+
+  // The watchpoints using this WatchpointResource.

JDevlieghere wrote:

`///`

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-26 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,146 @@
+//===-- WatchpointResourceList.h *- C++ 
-*-===//

JDevlieghere wrote:

Do we really need this class? It looks like a pretty trivial wrapper around a 
vector and a mutex. How much overlap is there with the `BreakpointSiteList.h`? 
Can we template this into a `StopPointList`? 

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-26 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,155 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Utility/Iterable.h"
+#include "lldb/lldb-public.h"
+
+#include 
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  bool WatchpointResourceRead() const;
+
+  bool WatchpointResourceWrite() const;
+
+  void SetType(bool read, bool write);
+
+  typedef std::vector WatchpointCollection;
+  typedef LockingAdaptedIterable
+  WatchpointIterable;
+
+  /// Iterate over the watchpoint owners for this resource
+  ///
+  /// \return
+  /// An Iterable object which can be used to loop over the watchpoints
+  /// that are owners of this resource.
+  WatchpointIterable Owners() {
+return WatchpointIterable(m_owners, m_owners_mutex);
+  }
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp_sp
+  /// The WatchpointSP to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(lldb::WatchpointSP _sp);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp
+  /// The Watchpoint to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(const lldb_private::Watchpoint *wp);

JDevlieghere wrote:

Can this be a const reference?

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-26 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,155 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Utility/Iterable.h"
+#include "lldb/lldb-public.h"
+
+#include 
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors

JDevlieghere wrote:

Nit: these comments are useless. We've been gradually removing them. Please 
remove this. 

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-26 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,155 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Utility/Iterable.h"
+#include "lldb/lldb-public.h"
+
+#include 
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  bool WatchpointResourceRead() const;
+
+  bool WatchpointResourceWrite() const;
+
+  void SetType(bool read, bool write);
+
+  typedef std::vector WatchpointCollection;
+  typedef LockingAdaptedIterable
+  WatchpointIterable;
+
+  /// Iterate over the watchpoint owners for this resource
+  ///
+  /// \return
+  /// An Iterable object which can be used to loop over the watchpoints
+  /// that are owners of this resource.
+  WatchpointIterable Owners() {
+return WatchpointIterable(m_owners, m_owners_mutex);
+  }
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp_sp
+  /// The WatchpointSP to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(lldb::WatchpointSP _sp);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp
+  /// The Watchpoint to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(const lldb_private::Watchpoint *wp);
+
+  /// This method copies the watchpoint resource's owners into a new 
collection.
+  /// It does this while the owners mutex is locked.
+  ///
+  /// \param[out] out_collection
+  ///The BreakpointLocationCollection into which to put the owners
+  ///of this breakpoint site.
+  ///
+  /// \return
+  ///The number of elements copied into out_collection.
+  size_t CopyOwnersList(WatchpointCollection _collection);
+
+  // The ID of the WatchpointResource is set by the WatchpointResourceList
+  // when the Resource has been set in the inferior and is being added
+  // to the List, in an attempt to match the hardware watchpoint register
+  // ordering.  If a Process can correctly identify the hardware watchpoint
+  // register index when it has created the Resource, it may initialize it
+  // before it is inserted in the WatchpointResourceList.
+  void SetID(lldb::wp_resource_id_t);
+
+  lldb::wp_resource_id_t GetID() const;
+
+  bool Contains(lldb::addr_t addr);
+
+protected:
+  // The StopInfoWatchpoint knows when it is processing a hit for a thread for
+  // a site, so let it be the one to manage setting the location hit count once
+  // and only once.
+  friend class StopInfoWatchpoint;
+
+  void BumpHitCounts();
+
+private:
+  lldb::wp_resource_id_t m_id;
+
+  // start address & size aligned & expanded to be a valid watchpoint

JDevlieghere wrote:

Nit: Capitalize

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-26 Thread Jonas Devlieghere via lldb-commits


@@ -0,0 +1,97 @@
+//===-- 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 "lldb/Breakpoint/WatchpointResource.h"
+#include "lldb/Utility/LLDBAssert.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+WatchpointResource::WatchpointResource(lldb::addr_t addr, size_t size,
+   bool read, bool write)
+: m_id(LLDB_INVALID_WATCHPOINT_RESOURCE_ID), m_addr(addr), m_size(size),
+  m_watch_read(read), m_watch_write(write) {}
+
+WatchpointResource::~WatchpointResource() {
+  std::lock_guard guard(m_owners_mutex);
+  m_owners.clear();
+}
+
+addr_t WatchpointResource::GetAddress() 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::AddOwner(const WatchpointSP _sp) {
+  std::lock_guard guard(m_owners_mutex);
+  m_owners.push_back(wp_sp);
+}
+
+void WatchpointResource::RemoveOwner(WatchpointSP _sp) {
+  std::lock_guard guard(m_owners_mutex);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  if (it != m_owners.end())
+m_owners.erase(it);
+}
+
+size_t WatchpointResource::GetNumberOfOwners() {
+  std::lock_guard guard(m_owners_mutex);
+  return m_owners.size();
+}
+
+bool WatchpointResource::OwnersContains(WatchpointSP _sp) {
+  std::lock_guard guard(m_owners_mutex);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  return it != m_owners.end();
+}
+
+bool WatchpointResource::OwnersContains(const Watchpoint *wp) {
+  std::lock_guard guard(m_owners_mutex);
+  WatchpointCollection::const_iterator match =
+  std::find_if(m_owners.begin(), m_owners.end(),
+   [](const WatchpointSP ) { return x.get() == wp; });
+  return match != m_owners.end();
+}
+
+WatchpointSP WatchpointResource::GetOwnerAtIndex(size_t idx) {
+  std::lock_guard guard(m_owners_mutex);
+  lldbassert(idx < m_owners.size());

JDevlieghere wrote:

I'd just make this a normal assert.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-25 Thread Jason Molenda via lldb-commits


@@ -53,44 +49,52 @@ bool WatchpointResource::Contains(addr_t addr) {
 
 void WatchpointResource::AddOwner(const WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  m_owners.Add(wp_sp);
+  m_owners.push_back(wp_sp);
 }
 
 void WatchpointResource::RemoveOwner(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  m_owners.Remove(wp_sp);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  if (it != m_owners.end())
+m_owners.erase(it);
 }
 
 size_t WatchpointResource::GetNumberOfOwners() {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.GetSize();
+  return m_owners.size();
 }
 
 bool WatchpointResource::OwnersContains(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.Contains(wp_sp);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  if (it != m_owners.end())
+return true;
+  return false;
 }
 
 bool WatchpointResource::OwnersContains(const Watchpoint *wp) {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.Contains(wp);
+  for (WatchpointCollection::const_iterator it = m_owners.begin();
+   it != m_owners.end(); ++it)
+if ((*it).get() == wp)
+  return true;
+  return false;
 }
 
 WatchpointSP WatchpointResource::GetOwnerAtIndex(size_t idx) {
   std::lock_guard guard(m_owners_mutex);
-  assert(idx < m_owners.GetSize());
-  if (idx >= m_owners.GetSize())
+  lldbassert(idx < m_owners.size());
+  if (idx >= m_owners.size())
 return {};
 
-  return m_owners.GetByIndex(idx);
+  return m_owners[idx];

jasonmolenda wrote:

This is a good point.  I am mostly trying to copy the API of BreakpointSite 
which has methods like this, and that's how its Owners are accessed today in 
different parts of lldb.  I haven't gotten to the point where I use the Owners 
anywhere yet, so I'm not locked in to the same API that BreakpointSite exposes. 
 We have things like `SBThread::GetStopReasonDataAtIndex()` which for 
Breakpoints exposes all of the Breakpoints that were owning the BreakpointSite 
that was hit.  We have other places like 
`StackFrameList::ResetCurrentInlinedDepth` which is iterating over a 
BreakpointSite's owners to see if any of them are internal; the 
IterableWatchpoint returned by `WatchpointResources::Owners` would be a cleaner 
approach in this case.  We have some places in the code that need to know the 
address of the breakpoint that was hit and are grabbing the first 
BreakpointLocation associated with the BreakpointSite, e.g. 
`PlatformDarwin::GetSoftwareBreakpointTrapOpcode` (for some arm/thumb reason).  
In `ThreadPlanCallFunction::DoPlanExplainsStop` we're iterating over the Owners 
to log about them and detect if any are Internal breakpoint locations, which 
could be done with an Iterable.  

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-25 Thread Alex Langford via lldb-commits


@@ -67,18 +67,15 @@ size_t WatchpointResource::GetNumberOfOwners() {
 bool WatchpointResource::OwnersContains(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
   const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
-  if (it != m_owners.end())
-return true;
-  return false;
+  return it != m_owners.end();
 }
 
 bool WatchpointResource::OwnersContains(const Watchpoint *wp) {
   std::lock_guard guard(m_owners_mutex);
-  for (WatchpointCollection::const_iterator it = m_owners.begin();
-   it != m_owners.end(); ++it)
-if ((*it).get() == wp)
-  return true;
-  return false;
+  WatchpointCollection::const_iterator match =

bulbazord wrote:

My bad... 臘 

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-25 Thread Alex Langford via lldb-commits

https://github.com/bulbazord edited 
https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-25 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda edited 
https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-25 Thread Jason Molenda via lldb-commits


@@ -67,18 +67,15 @@ size_t WatchpointResource::GetNumberOfOwners() {
 bool WatchpointResource::OwnersContains(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
   const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
-  if (it != m_owners.end())
-return true;
-  return false;
+  return it != m_owners.end();
 }
 
 bool WatchpointResource::OwnersContains(const Watchpoint *wp) {
   std::lock_guard guard(m_owners_mutex);
-  for (WatchpointCollection::const_iterator it = m_owners.begin();
-   it != m_owners.end(); ++it)
-if ((*it).get() == wp)
-  return true;
-  return false;
+  WatchpointCollection::const_iterator match =

jasonmolenda wrote:

It's a typedef to std::vector.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-25 Thread Alex Langford via lldb-commits


@@ -67,18 +67,15 @@ size_t WatchpointResource::GetNumberOfOwners() {
 bool WatchpointResource::OwnersContains(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
   const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
-  if (it != m_owners.end())
-return true;
-  return false;
+  return it != m_owners.end();
 }
 
 bool WatchpointResource::OwnersContains(const Watchpoint *wp) {
   std::lock_guard guard(m_owners_mutex);
-  for (WatchpointCollection::const_iterator it = m_owners.begin();
-   it != m_owners.end(); ++it)
-if ((*it).get() == wp)
-  return true;
-  return false;
+  WatchpointCollection::const_iterator match =

bulbazord wrote:

Looks fine, but the type should be different right? I think you removed 
`WatchpointCollection` in the 3rd commit

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-25 Thread Alex Langford via lldb-commits


@@ -53,44 +49,52 @@ bool WatchpointResource::Contains(addr_t addr) {
 
 void WatchpointResource::AddOwner(const WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  m_owners.Add(wp_sp);
+  m_owners.push_back(wp_sp);
 }
 
 void WatchpointResource::RemoveOwner(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  m_owners.Remove(wp_sp);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  if (it != m_owners.end())
+m_owners.erase(it);
 }
 
 size_t WatchpointResource::GetNumberOfOwners() {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.GetSize();
+  return m_owners.size();
 }
 
 bool WatchpointResource::OwnersContains(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.Contains(wp_sp);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  if (it != m_owners.end())
+return true;
+  return false;
 }
 
 bool WatchpointResource::OwnersContains(const Watchpoint *wp) {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.Contains(wp);
+  for (WatchpointCollection::const_iterator it = m_owners.begin();
+   it != m_owners.end(); ++it)
+if ((*it).get() == wp)
+  return true;
+  return false;
 }
 
 WatchpointSP WatchpointResource::GetOwnerAtIndex(size_t idx) {
   std::lock_guard guard(m_owners_mutex);
-  assert(idx < m_owners.GetSize());
-  if (idx >= m_owners.GetSize())
+  lldbassert(idx < m_owners.size());
+  if (idx >= m_owners.size())
 return {};
 
-  return m_owners.GetByIndex(idx);
+  return m_owners[idx];

bulbazord wrote:

Well, I'm not entirely sure how we're going to want to access the Owners list, 
so I'd like to understand more how you plan on using it. If you want to do 
something like `wp_resource_sp->Owners()[2]` then this method makes sense to 
keep around, but I'd also be curious to know why you would want to access the 
3rd owner directly. What I would like to avoid is writing a loop like this:
```
for (int i = 0; i < wp_resource_sp.GetNumberOfOwners(); i++) {
  WatchpointSP wp_sp = wp_resource_sp->GetOwnerAtIndex(i);
  // Use wp_sp
}
```
The two main reasons I am not a fan of this pattern:
1. As you pointed out, one would need to grab the `wp_resource_sp` owner mutex 
to do this safely since another thread may call `RemoveOwner` in the middle of 
this loop. I can't say I'm a fan of exposing the vector primarily because it 
would mean we'd have to expose the mutex too.
2. Off-by-one errors are fairly easy to put in by mistake. Doubly so if we ever 
iterate in reverse (i >0 vs i >=0 for the termination condition).

If we don't need to be able to access any of the owners at an arbitrary index, 
I would suggest removing it so nobody can write that kind of loop. WDYT?

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-25 Thread Jason Molenda via lldb-commits


@@ -53,44 +49,52 @@ bool WatchpointResource::Contains(addr_t addr) {
 
 void WatchpointResource::AddOwner(const WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  m_owners.Add(wp_sp);
+  m_owners.push_back(wp_sp);
 }
 
 void WatchpointResource::RemoveOwner(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  m_owners.Remove(wp_sp);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  if (it != m_owners.end())
+m_owners.erase(it);
 }
 
 size_t WatchpointResource::GetNumberOfOwners() {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.GetSize();
+  return m_owners.size();
 }
 
 bool WatchpointResource::OwnersContains(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.Contains(wp_sp);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  if (it != m_owners.end())
+return true;
+  return false;
 }
 
 bool WatchpointResource::OwnersContains(const Watchpoint *wp) {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.Contains(wp);
+  for (WatchpointCollection::const_iterator it = m_owners.begin();
+   it != m_owners.end(); ++it)
+if ((*it).get() == wp)
+  return true;
+  return false;
 }
 
 WatchpointSP WatchpointResource::GetOwnerAtIndex(size_t idx) {
   std::lock_guard guard(m_owners_mutex);
-  assert(idx < m_owners.GetSize());
-  if (idx >= m_owners.GetSize())
+  lldbassert(idx < m_owners.size());
+  if (idx >= m_owners.size())
 return {};
 
-  return m_owners.GetByIndex(idx);
+  return m_owners[idx];

jasonmolenda wrote:

I'm not completely clear what having WatchpointResource::Owners() returning a 
WatchpointIterable is going to do beyond allowing someone to write `for 
(WatchpointSP _sp : wp_resource_sp->Owners())` - it's not exposing the 
underlying std::vector so I can't call `wp_resource_sp->Owners().size()` or 
`wp_resource_sp->Owners()[2]` is it?  Right now the WatchpointResource has 
methods like `AddOwner`, `RemoveOwner`, `GetNumberOfOwners`, `GetOwnerAtIndex`, 
and some methods to check if the list of owners contains a watchpoint; should 
callers be able to lock the Resource's mutex and get a reference to the 
std::vector and query/manipulate it directly?  

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-25 Thread Jason Molenda via lldb-commits


@@ -53,44 +49,52 @@ bool WatchpointResource::Contains(addr_t addr) {
 
 void WatchpointResource::AddOwner(const WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  m_owners.Add(wp_sp);
+  m_owners.push_back(wp_sp);
 }
 
 void WatchpointResource::RemoveOwner(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  m_owners.Remove(wp_sp);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  if (it != m_owners.end())
+m_owners.erase(it);
 }
 
 size_t WatchpointResource::GetNumberOfOwners() {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.GetSize();
+  return m_owners.size();
 }
 
 bool WatchpointResource::OwnersContains(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.Contains(wp_sp);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  if (it != m_owners.end())
+return true;
+  return false;
 }
 
 bool WatchpointResource::OwnersContains(const Watchpoint *wp) {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.Contains(wp);
+  for (WatchpointCollection::const_iterator it = m_owners.begin();
+   it != m_owners.end(); ++it)
+if ((*it).get() == wp)
+  return true;
+  return false;
 }
 
 WatchpointSP WatchpointResource::GetOwnerAtIndex(size_t idx) {
   std::lock_guard guard(m_owners_mutex);
-  assert(idx < m_owners.GetSize());
-  if (idx >= m_owners.GetSize())
+  lldbassert(idx < m_owners.size());
+  if (idx >= m_owners.size())
 return {};
 
-  return m_owners.GetByIndex(idx);
+  return m_owners[idx];

jasonmolenda wrote:

Right now nothing is using the WatchpointResource owners - I need to add that 
in a follow on patch when a watchpoint has been triggered.  BreakpointSite uses 
this method in many places, but I agree that the Owners() method could be used. 
 We lose the range check/possible-assert in GetOwnerAtIndex() but hopefully 
that shouldn't actually happen...

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-25 Thread Alex Langford via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp_sp
+  /// The WatchpointSP to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(lldb::WatchpointSP _sp);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp
+  /// The Watchpoint to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(const lldb_private::Watchpoint *wp);
+
+  /// This method copies the watchpoint resource's owners into a new 
collection.
+  /// It does this while the owners mutex is locked.
+  ///
+  /// \param[out] out_collection
+  ///The BreakpointLocationCollection into which to put the owners
+  ///of this breakpoint site.
+  ///
+  /// \return
+  ///The number of elements copied into out_collection.
+  size_t CopyOwnersList(WatchpointCollection _collection);

bulbazord wrote:

It should take advantage of copy elision. Specifically we should be able to 
take advantage of NRVO.

https://en.cppreference.com/w/cpp/language/copy_elision

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-25 Thread Alex Langford via lldb-commits


@@ -53,44 +49,52 @@ bool WatchpointResource::Contains(addr_t addr) {
 
 void WatchpointResource::AddOwner(const WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  m_owners.Add(wp_sp);
+  m_owners.push_back(wp_sp);
 }
 
 void WatchpointResource::RemoveOwner(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  m_owners.Remove(wp_sp);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  if (it != m_owners.end())
+m_owners.erase(it);
 }
 
 size_t WatchpointResource::GetNumberOfOwners() {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.GetSize();
+  return m_owners.size();
 }
 
 bool WatchpointResource::OwnersContains(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.Contains(wp_sp);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  if (it != m_owners.end())
+return true;
+  return false;
 }
 
 bool WatchpointResource::OwnersContains(const Watchpoint *wp) {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.Contains(wp);
+  for (WatchpointCollection::const_iterator it = m_owners.begin();
+   it != m_owners.end(); ++it)
+if ((*it).get() == wp)
+  return true;
+  return false;

bulbazord wrote:

`WatchpointCollection` got removed right? I think you'll need to rewrite it... 
I'd suggest using `find_if`

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-25 Thread Alex Langford via lldb-commits


@@ -53,44 +49,52 @@ bool WatchpointResource::Contains(addr_t addr) {
 
 void WatchpointResource::AddOwner(const WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  m_owners.Add(wp_sp);
+  m_owners.push_back(wp_sp);
 }
 
 void WatchpointResource::RemoveOwner(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  m_owners.Remove(wp_sp);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  if (it != m_owners.end())
+m_owners.erase(it);
 }
 
 size_t WatchpointResource::GetNumberOfOwners() {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.GetSize();
+  return m_owners.size();
 }
 
 bool WatchpointResource::OwnersContains(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.Contains(wp_sp);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  if (it != m_owners.end())
+return true;
+  return false;
 }
 
 bool WatchpointResource::OwnersContains(const Watchpoint *wp) {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.Contains(wp);
+  for (WatchpointCollection::const_iterator it = m_owners.begin();
+   it != m_owners.end(); ++it)
+if ((*it).get() == wp)
+  return true;
+  return false;
 }
 
 WatchpointSP WatchpointResource::GetOwnerAtIndex(size_t idx) {
   std::lock_guard guard(m_owners_mutex);
-  assert(idx < m_owners.GetSize());
-  if (idx >= m_owners.GetSize())
+  lldbassert(idx < m_owners.size());
+  if (idx >= m_owners.size())
 return {};
 
-  return m_owners.GetByIndex(idx);
+  return m_owners[idx];

bulbazord wrote:

Looking over this again, is there a use case where you would want to reference 
a specific owner by index instead of using `Owners()`?

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-25 Thread Alex Langford via lldb-commits


@@ -53,44 +49,52 @@ bool WatchpointResource::Contains(addr_t addr) {
 
 void WatchpointResource::AddOwner(const WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  m_owners.Add(wp_sp);
+  m_owners.push_back(wp_sp);
 }
 
 void WatchpointResource::RemoveOwner(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  m_owners.Remove(wp_sp);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  if (it != m_owners.end())
+m_owners.erase(it);
 }
 
 size_t WatchpointResource::GetNumberOfOwners() {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.GetSize();
+  return m_owners.size();
 }
 
 bool WatchpointResource::OwnersContains(WatchpointSP _sp) {
   std::lock_guard guard(m_owners_mutex);
-  return m_owners.Contains(wp_sp);
+  const auto  = std::find(m_owners.begin(), m_owners.end(), wp_sp);
+  if (it != m_owners.end())
+return true;
+  return false;

bulbazord wrote:

`return it != m_owners.end();`

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-24 Thread Med Ismail Bennani via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp_sp
+  /// The WatchpointSP to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(lldb::WatchpointSP _sp);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp
+  /// The Watchpoint to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(const lldb_private::Watchpoint *wp);
+
+  /// This method copies the watchpoint resource's owners into a new 
collection.
+  /// It does this while the owners mutex is locked.
+  ///
+  /// \param[out] out_collection
+  ///The BreakpointLocationCollection into which to put the owners
+  ///of this breakpoint site.
+  ///
+  /// \return
+  ///The number of elements copied into out_collection.
+  size_t CopyOwnersList(WatchpointCollection _collection);
+
+  // The ID of the WatchpointResource is set by the WatchpointResourceList
+  // when the Resource has been set in the inferior and is being added
+  // to the List, in an attempt to match the hardware watchpoint register
+  // ordering.  If a Process can correctly identify the hardware watchpoint
+  // register index when it has created the Resource, it may initialize it
+  // before it is inserted in the WatchpointResourceList.
+  void SetID(lldb::wp_resource_id_t);

medismailben wrote:

Thanks for the explanation, that makes more sense to me now.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-24 Thread Jason Molenda via lldb-commits


@@ -839,11 +841,11 @@ std::optional 
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()) {

jasonmolenda wrote:

The original code didn't check it, but more importantly on this topic, I have 
real concern about touching any of ProcessWindows, NativeProcessWindows because 
I can't build or test it directly myself.  I have a feeling I'll keep most/all 
of the existing interfaces for creating a StopInfo etc so the Windows code can 
continue to work unmodified.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-24 Thread Jason Molenda via lldb-commits


@@ -491,14 +491,13 @@ static StopInfoSP GetStopInfoForHardwareBP(Thread 
, Target *target,
uint64_t exc_sub_sub_code) {
   // Try hardware watchpoint.
   if (target) {
+// LWP_TODO: We need to find the WatchpointResource that matches

jasonmolenda wrote:

Yeah good point my idea was that these are temporary placeholders as I roll 
this out, so they wouldn't be in the source for very long. (this feature is not 
really useful with all the parts landed so it's unlikely I'll be distracted by 
some other issue )

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-24 Thread Jason Molenda via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp_sp
+  /// The WatchpointSP to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(lldb::WatchpointSP _sp);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp
+  /// The Watchpoint to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(const lldb_private::Watchpoint *wp);
+
+  /// This method copies the watchpoint resource's owners into a new 
collection.
+  /// It does this while the owners mutex is locked.
+  ///
+  /// \param[out] out_collection
+  ///The BreakpointLocationCollection into which to put the owners
+  ///of this breakpoint site.
+  ///
+  /// \return
+  ///The number of elements copied into out_collection.
+  size_t CopyOwnersList(WatchpointCollection _collection);

jasonmolenda wrote:

Hm, I do not have a lot of confidence about avoiding an extra copy of the 
vector if I return by value.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-24 Thread Jason Molenda via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();

jasonmolenda wrote:

none of that is done yet though.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-24 Thread Jason Molenda via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();

jasonmolenda wrote:

tbh there could be an argument for locking the whole object because a 
WatchpointResource may be expanded to service multiple watchpoints (one 
watchpoint watches bytes 0-1, a second watchpoint watches bytes 2-3) and then 
reduced again when one of those watchpoints is deleted/disabled.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-24 Thread Alex Langford via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();

bulbazord wrote:

Oh wait, the mutex is to protect the Owners. Nevermind! 

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-24 Thread Alex Langford via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();

bulbazord wrote:

Ah I could have sworn the mutex was marked as `mutable`. How are things like 
`GetType` and `GetByteSize` marked `const` then? Do they not lock?

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-24 Thread Jason Molenda via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;

jasonmolenda wrote:

idk about this one, `GetType(bool , bool )` makes the order easy to 
see, and matches the `SetType (bool read, bool write)` whereas the pair would 
be less explicitly named.  I should follow the Watchpoint class method and have 
`bool WatchpointResourceRead()`, `bool WatchpointResourceWrite()`.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-24 Thread Jason Molenda via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();

jasonmolenda wrote:

I lock the object's mutex in all of these methods.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-24 Thread Jason Molenda via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;

jasonmolenda wrote:

I originally wrote the WatchpointResource::GetMemoryRange that returned both 
via out parameters, then at a later point I added a GetAddress & GetByteSize 
methods meaning to remove GetMemoryRange which I wasn't happy with... but 
forgot.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Alex Langford via lldb-commits


@@ -266,33 +268,73 @@ 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 {
+if (old_value_cstr) {
+  values_ss.Printf("old value: %s", 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 (old_summary_cstr)
+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) {
+if (values_ss.GetSize())
+  values_ss.Printf("\n");
+
 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 (new_value_cstr)
+  values_ss.Printf("new value: %s", new_value_cstr);

bulbazord wrote:

Same here

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Alex Langford via lldb-commits


@@ -491,14 +491,13 @@ static StopInfoSP GetStopInfoForHardwareBP(Thread 
, Target *target,
uint64_t exc_sub_sub_code) {
   // Try hardware watchpoint.
   if (target) {
+// LWP_TODO: We need to find the WatchpointResource that matches

bulbazord wrote:

`LWP_TODO` doesn't mean much to a lot of contributors, maybe you can change 
this to something like `TODO(Large Watchpoint Support)`? Mostly to avoid 
acronyms that aren't written down anywhere else.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Alex Langford via lldb-commits


@@ -3105,102 +3122,184 @@ 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 _res_sp) {
+  assert(wp_res_sp);
+  bool read, write;
+  wp_res_sp->GetType(read, write);
+
+  assert((read || write) && "read and write cannot both be false.");
+  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();
+  if (wp_sp) {

bulbazord wrote:

Since you're already refactoring this part, maybe you could flip the condition 
and do the error handling up front. It's small, but it saves a level of 
indentation in an already large code block.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Alex Langford via lldb-commits


@@ -266,33 +268,73 @@ 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 {
+if (old_value_cstr) {
+  values_ss.Printf("old value: %s", 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 (old_summary_cstr)
+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) {
+if (values_ss.GetSize())
+  values_ss.Printf("\n");
+
 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 (new_value_cstr)
+  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 (new_summary_cstr)
+values_ss.Printf("new value: %s", new_summary_cstr);

bulbazord wrote:

Same here

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Alex Langford via lldb-commits


@@ -0,0 +1,90 @@
+//===-- WatchpointCollection.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/WatchpointCollection.h"
+#include "lldb/Breakpoint/Watchpoint.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadSpec.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+// WatchpointCollection constructor
+WatchpointCollection::WatchpointCollection() = default;
+
+// Destructor
+WatchpointCollection::~WatchpointCollection() = default;
+
+void WatchpointCollection::Add(const WatchpointSP ) {
+  std::lock_guard guard(m_collection_mutex);
+  m_collection.push_back(wp);
+}
+
+bool WatchpointCollection::Remove(WatchpointSP ) {
+  std::lock_guard guard(m_collection_mutex);
+  for (collection::iterator pos = m_collection.begin();
+   pos != m_collection.end(); ++pos) {
+if (*pos == wp) {
+  m_collection.erase(pos);
+  return true;
+}
+  }
+  return false;
+}
+
+WatchpointSP WatchpointCollection::GetByIndex(size_t i) {
+  std::lock_guard guard(m_collection_mutex);
+  if (i < m_collection.size())
+return m_collection[i];
+  return {};
+}
+
+const WatchpointSP WatchpointCollection::GetByIndex(size_t i) const {
+  std::lock_guard guard(m_collection_mutex);
+  if (i < m_collection.size())
+return m_collection[i];
+  return {};
+}
+
+WatchpointCollection &
+WatchpointCollection::operator=(const WatchpointCollection ) {
+  if (this != ) {
+std::lock(m_collection_mutex, rhs.m_collection_mutex);
+std::lock_guard lhs_guard(m_collection_mutex, std::adopt_lock);
+std::lock_guard rhs_guard(rhs.m_collection_mutex,
+  std::adopt_lock);

bulbazord wrote:

You can use `std::scoped_lock` for this now that we're using C++17!  

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Alex Langford via lldb-commits


@@ -3105,102 +3122,184 @@ 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 _res_sp) {
+  assert(wp_res_sp);
+  bool read, write;
+  wp_res_sp->GetType(read, write);
+
+  assert((read || write) && "read and write cannot both be false.");

bulbazord wrote:

The assertion message here could be fleshed out a bit more. Something like 
`"WatchpointResource type is neither read nor write"`.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Alex Langford via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);

bulbazord wrote:

Instead of exposing this primitive, maybe it would make more sense to return an 
iterator or an iterator range?
Something like:
```
IteratorRange Owners();
```
IMO this would make it easier to write bug-free code since we're not going to 
have to manually set up index iteration logic.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Alex Langford via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp_sp
+  /// The WatchpointSP to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(lldb::WatchpointSP _sp);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp
+  /// The Watchpoint to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(const lldb_private::Watchpoint *wp);
+
+  /// This method copies the watchpoint resource's owners into a new 
collection.
+  /// It does this while the owners mutex is locked.
+  ///
+  /// \param[out] out_collection
+  ///The BreakpointLocationCollection into which to put the owners
+  ///of this breakpoint site.
+  ///
+  /// \return
+  ///The number of elements copied into out_collection.
+  size_t CopyOwnersList(WatchpointCollection _collection);

bulbazord wrote:

Why return the size instead of returning just a new `WatchpointCollection` 
object? That way callers don't have to create a new one and pass it in, they 
can just grab it from this method directly.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Alex Langford via lldb-commits

https://github.com/bulbazord commented:

A lot of the `WatchpointResourceList::FindBy` methods can probably be rewritten 
with `std::find_if` (or `llvm::find_if` which is a little easier to use IMO).

Overall, looks like a pretty nice mostly-NFC refactor!  

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Alex Langford via lldb-commits


@@ -0,0 +1,90 @@
+//===-- WatchpointCollection.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/WatchpointCollection.h"
+#include "lldb/Breakpoint/Watchpoint.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadSpec.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+// WatchpointCollection constructor
+WatchpointCollection::WatchpointCollection() = default;
+
+// Destructor
+WatchpointCollection::~WatchpointCollection() = default;
+
+void WatchpointCollection::Add(const WatchpointSP ) {
+  std::lock_guard guard(m_collection_mutex);
+  m_collection.push_back(wp);
+}
+
+bool WatchpointCollection::Remove(WatchpointSP ) {
+  std::lock_guard guard(m_collection_mutex);
+  for (collection::iterator pos = m_collection.begin();
+   pos != m_collection.end(); ++pos) {
+if (*pos == wp) {
+  m_collection.erase(pos);
+  return true;
+}
+  }
+  return false;
+}
+
+WatchpointSP WatchpointCollection::GetByIndex(size_t i) {
+  std::lock_guard guard(m_collection_mutex);
+  if (i < m_collection.size())
+return m_collection[i];
+  return {};
+}
+
+const WatchpointSP WatchpointCollection::GetByIndex(size_t i) const {
+  std::lock_guard guard(m_collection_mutex);
+  if (i < m_collection.size())
+return m_collection[i];
+  return {};
+}
+
+WatchpointCollection &
+WatchpointCollection::operator=(const WatchpointCollection ) {
+  if (this != ) {
+std::lock(m_collection_mutex, rhs.m_collection_mutex);
+std::lock_guard lhs_guard(m_collection_mutex, std::adopt_lock);
+std::lock_guard rhs_guard(rhs.m_collection_mutex,
+  std::adopt_lock);
+m_collection = rhs.m_collection;
+  }
+  return *this;
+}
+
+void WatchpointCollection::Clear() {
+  std::lock_guard guard(m_collection_mutex);
+  m_collection.clear();
+}
+
+bool WatchpointCollection::Contains(const WatchpointSP _sp) {
+  std::lock_guard guard(m_collection_mutex);
+  const size_t size = m_collection.size();
+  for (size_t i = 0; i < size; ++i) {
+if (m_collection[i] == wp_sp)
+  return true;
+  }

bulbazord wrote:

Why not use iterators here? You can also use `llvm::is_contained` too.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Alex Langford via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp_sp
+  /// The WatchpointSP to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(lldb::WatchpointSP _sp);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp
+  /// The Watchpoint to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(const lldb_private::Watchpoint *wp);
+
+  /// This method copies the watchpoint resource's owners into a new 
collection.
+  /// It does this while the owners mutex is locked.
+  ///
+  /// \param[out] out_collection
+  ///The BreakpointLocationCollection into which to put the owners
+  ///of this breakpoint site.
+  ///
+  /// \return
+  ///The number of elements copied into out_collection.
+  size_t CopyOwnersList(WatchpointCollection _collection);
+
+  // The ID of the WatchpointResource is set by the WatchpointResourceList
+  // when the Resource has been set in the inferior and is being added
+  // to the List, in an attempt to match the hardware watchpoint register
+  // ordering.  If a Process can correctly identify the hardware watchpoint
+  // register index when it has created the Resource, it may initialize it
+  // before it is inserted in the WatchpointResourceList.
+  void SetID(lldb::wp_resource_id_t);
+
+  lldb::wp_resource_id_t GetID() const;
+
+  bool Contains(lldb::addr_t addr);
+
+protected:
+  // The StopInfoWatchpoint knows when it is processing a hit for a thread for
+  // a site, so let it be the one to manage setting the location hit count once
+  // and only once.
+  friend class StopInfoWatchpoint;
+
+  void BumpHitCounts();
+
+private:
+  lldb::wp_resource_id_t m_id;
+
+  // start address & size aligned & expanded to be a valid watchpoint
+  // memory granule on this target.
+  lldb::addr_t m_addr;
+  size_t m_size;
+
+  bool m_watch_read;  // true if we stop when the watched data is read from
+  bool m_watch_write; // true if we stop when the watched data is written to

bulbazord wrote:

IMO these comments are unnecessary, the names of the variables already describe 
the intended semantics quite well I think.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Alex Langford via lldb-commits


@@ -266,33 +268,73 @@ 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 {
+if (old_value_cstr) {
+  values_ss.Printf("old value: %s", 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 (old_summary_cstr)

bulbazord wrote:

Same here

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Alex Langford via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;

bulbazord wrote:

Suggestion: Return `std::pair` instead of passing out parameters.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Alex Langford via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();

bulbazord wrote:

This can be `const`-qualified right?

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Alex Langford via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;

bulbazord wrote:

Instead of out parameters, you could do `std::pair`.
But why have this and `GetAddress()` + `GetByteSize()`?

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Alex Langford via lldb-commits

https://github.com/bulbazord edited 
https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Jason Molenda via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp_sp
+  /// The WatchpointSP to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(lldb::WatchpointSP _sp);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp
+  /// The Watchpoint to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(const lldb_private::Watchpoint *wp);
+
+  /// This method copies the watchpoint resource's owners into a new 
collection.
+  /// It does this while the owners mutex is locked.
+  ///
+  /// \param[out] out_collection
+  ///The BreakpointLocationCollection into which to put the owners
+  ///of this breakpoint site.
+  ///
+  /// \return
+  ///The number of elements copied into out_collection.
+  size_t CopyOwnersList(WatchpointCollection _collection);
+
+  // The ID of the WatchpointResource is set by the WatchpointResourceList
+  // when the Resource has been set in the inferior and is being added
+  // to the List, in an attempt to match the hardware watchpoint register
+  // ordering.  If a Process can correctly identify the hardware watchpoint
+  // register index when it has created the Resource, it may initialize it
+  // before it is inserted in the WatchpointResourceList.
+  void SetID(lldb::wp_resource_id_t);

jasonmolenda wrote:

To be honest, I'm VERY close to just removing the hardware index numbers 
altogether and having SBWatchpoint::GetHardwareIndex return UINT32_MAX.  It 
might be the better idea than these convoluted things I'm doing to try to 
heuristically guess the hw index.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Jason Molenda via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp_sp
+  /// The WatchpointSP to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(lldb::WatchpointSP _sp);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp
+  /// The Watchpoint to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(const lldb_private::Watchpoint *wp);
+
+  /// This method copies the watchpoint resource's owners into a new 
collection.
+  /// It does this while the owners mutex is locked.
+  ///
+  /// \param[out] out_collection
+  ///The BreakpointLocationCollection into which to put the owners
+  ///of this breakpoint site.
+  ///
+  /// \return
+  ///The number of elements copied into out_collection.
+  size_t CopyOwnersList(WatchpointCollection _collection);
+
+  // The ID of the WatchpointResource is set by the WatchpointResourceList
+  // when the Resource has been set in the inferior and is being added
+  // to the List, in an attempt to match the hardware watchpoint register
+  // ordering.  If a Process can correctly identify the hardware watchpoint
+  // register index when it has created the Resource, it may initialize it
+  // before it is inserted in the WatchpointResourceList.
+  void SetID(lldb::wp_resource_id_t);

jasonmolenda wrote:

When the Process method is given a watchpoint request from the user, which must 
be broken into one or more WatchpointResources (or an existing 
WatchpointResource reused), we can only get the hardware register number by 
looking at the IDs of currently allocated WatchpointResources in the 
WatchpointResourceList, which start at 0.  I assume that the remote stub will 
allocate its watchpoints in the hardware registers starting at index 0, and 
when removing/disabling them, will leave that slot unused until another request 
comes along, at which point the stub will start from 0 and look for the first 
unused hardware register.

In the specific case of gdb remote serial protocol (ProcessGDBRemote), it has 
none of this.  The Z2/Z3/Z4 packets don't tell you what hardware register was 
used.  

Today, lldb sets the hardware watchpoint index based on the watchpoint access 
stop.  SOME ways of passing the watchpoint trap back to lldb can communicate 
the hardware watchpoint index.  The standard gdb remote serial protocol does 
not with its `watch/rwatch/awatch:address` key-value in the stop packet.  
lldb-server has a different way of reporting watchpoints, `reason:watchpoint` 
and `description:addr[ index]` where the address is sent in the description: 
and it may be followed by a space and then the index number of the hardware 
watchpoint that was triggered.  For macOS systems, the mach exception data is 
sent at 

[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Med Ismail Bennani via lldb-commits


@@ -0,0 +1,140 @@
+//===-- WatchpointResource.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_BREAKPOINT_WATCHPOINTRESOURCE_H
+#define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
+
+#include "lldb/Breakpoint/WatchpointCollection.h"
+#include "lldb/lldb-public.h"
+
+#include 
+
+namespace lldb_private {
+
+class WatchpointResource
+: public std::enable_shared_from_this {
+
+public:
+  // Constructors and Destructors
+  WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
+
+  ~WatchpointResource();
+
+  void GetMemoryRange(lldb::addr_t , size_t ) const;
+
+  lldb::addr_t GetAddress() const;
+
+  size_t GetByteSize() const;
+
+  void GetType(bool , bool ) const;
+
+  void SetType(bool read, bool write);
+
+  /// The "Owners" are the watchpoints that share this resource.
+  /// The method adds the \a owner to this resource's owner list.
+  ///
+  /// \param[in] owner
+  ///\a owner is the Wachpoint to add.
+  void AddOwner(const lldb::WatchpointSP );
+
+  /// The method removes the owner at \a owner from this watchpoint
+  /// resource.
+  void RemoveOwner(lldb::WatchpointSP );
+
+  /// This method returns the number of Watchpoints currently using
+  /// watchpoint resource.
+  ///
+  /// \return
+  ///The number of owners.
+  size_t GetNumberOfOwners();
+
+  /// This method returns the Watchpoint at index \a index using this
+  /// Resource.  The owners are listed ordinally from 0 to
+  /// GetNumberOfOwners() - 1 so you can use this method to iterate over the
+  /// owners.
+  ///
+  /// \param[in] idx
+  /// The index in the list of owners for which you wish the owner 
location.
+  ///
+  /// \return
+  ///The Watchpoint at that index.
+  lldb::WatchpointSP GetOwnerAtIndex(size_t idx);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp_sp
+  /// The WatchpointSP to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(lldb::WatchpointSP _sp);
+
+  /// Check if the owners includes a watchpoint.
+  ///
+  /// \param[in] wp
+  /// The Watchpoint to search for.
+  ///
+  /// \result
+  /// true if this resource's owners includes the watchpoint.
+  bool OwnersContains(const lldb_private::Watchpoint *wp);
+
+  /// This method copies the watchpoint resource's owners into a new 
collection.
+  /// It does this while the owners mutex is locked.
+  ///
+  /// \param[out] out_collection
+  ///The BreakpointLocationCollection into which to put the owners
+  ///of this breakpoint site.
+  ///
+  /// \return
+  ///The number of elements copied into out_collection.
+  size_t CopyOwnersList(WatchpointCollection _collection);
+
+  // The ID of the WatchpointResource is set by the WatchpointResourceList
+  // when the Resource has been set in the inferior and is being added
+  // to the List, in an attempt to match the hardware watchpoint register
+  // ordering.  If a Process can correctly identify the hardware watchpoint
+  // register index when it has created the Resource, it may initialize it
+  // before it is inserted in the WatchpointResourceList.
+  void SetID(lldb::wp_resource_id_t);

medismailben wrote:

IIUC, this ID shouldn't change during the `Resource`'s lifetime so why not set 
it once in the constructor, and get rid of this setter ?

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-23 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

@bulbazord @JDevlieghere OK this is the second set of refinement where it's 
closer to the structure of BreakpointSites.  It's still not actually doing 
anything -- each one WatchpointResource corresponds to one Watchpoint, a single 
Watchpoint's request is not broken into multiple WatchpointResources, and when 
a watchpoint access is hit, I'm not iterating all of the Watchpoints (lol, all 
1 of them) to bump their hit count, run conditions, etc.  These remaining 
pieces of work will be smaller scale, more complicated I think, and it will be 
easier to consider those parts if the patches are small.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-19 Thread David Spickett via lldb-commits

https://github.com/DavidSpickett edited 
https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-19 Thread David Spickett via lldb-commits


@@ -135,5 +135,5 @@ def test_watch_address_with_invalid_watch_size(self):
 self.expect(
 error.GetCString(),
 exe=False,
-substrs=["watch size of %d is not supported" % 365],
+substrs=["Setting one of the watchpoint resources failed"],

DavidSpickett wrote:

Yeah I don't think it would need to be super specific, that is what logs are 
for. Drawing the distinction between failed because the stub didn't have 
resources, and failed because the stub exploded, that's more what I'd like to 
see.

And here the original error message is actually still pretty vague. It tells me 
that size N isn't support, but not what is supported (which is a whole other 
thing).

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-18 Thread Jason Molenda via lldb-commits


@@ -2,8 +2,8 @@
 #include 
 
 int main() {
-  uint8_t x1 = 0;
-  uint16_t x2 = 0;
+  long x1 = 0;
+  long x2 = 0;

jasonmolenda wrote:

You're right.  I thought this test was *unintentionally* testing the case where 
we have two hardware watchpoint register watching the same doubleword of 
memory.  But that was actually the point of the test (v. 
https://reviews.llvm.org/D77173 ).  I'm not sure how thrilled I am about this 
test, it seems to be encoding the behavior of the cpu with multiple watchpoint 
registers on the same doubleword and I don't know how universal that is - if a 
CPU might only evaluate the first watchpoint on a doubleword and ignore the 
second.  

This is very much in the wheelhouse of the work I need to do on large 
watchpoints where a single WatchpointResource should be used for both 
watchpoints, expanded to include the byte range of both, and then reduced back 
down again when one is disabled or deleted.  I'll be adding tests like this one 
as part of that work.  I'll revert my change here.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-18 Thread Jason Molenda via lldb-commits


@@ -1,3 +1,10 @@
 # REQUIRES: system-darwin
+# TODO: This test is breaking with my output 
+# reformatting done for Large Watchpoint support,
+# but the lines being output by lldb are identical,
+# by visual inspection.  
+# FileCheck is seeing some difference between them,
+# which I need to get to the bottom of.

jasonmolenda wrote:

Good idea, it must surely be something like that.  The test wasn't adding 
anything super useful and I spent so much time trying to rearrange things to 
make it pass I finally punted on it for now.  I'm going to need to add a bunch 
of new tests once I get the large watchpoint work finished.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-18 Thread Jason Molenda via lldb-commits


@@ -135,5 +135,5 @@ def test_watch_address_with_invalid_watch_size(self):
 self.expect(
 error.GetCString(),
 exe=False,
-substrs=["watch size of %d is not supported" % 365],
+substrs=["Setting one of the watchpoint resources failed"],

jasonmolenda wrote:

This test is trying to watch a 365 byte region, it was intended to detect the 
fact that you can only watch 1/2/4/8 byte blocks of memory (the --size was 
really an enum and it had to be one of those).  With this patch currently, lldb 
will accept the 365 byte watch request and pass it to the remote stub, which 
will probably return an error.  (debugserver will actually break it into 
aligned watchable regions and do the right thing). When I finish the large 
watchpoint work, lldb will break this 365 byte request into 46 8-byte regions 
(for linux with BAS only watchpoints) and when we try to set the 5th one (or 
however many the core actually supports), that watch request will fail.  Maybe 
the error message should say something about how your watchpoint was broken 
into  watchpoint requests but only  of them could be set.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-17 Thread David Spickett via lldb-commits


@@ -2,8 +2,8 @@
 #include 
 
 int main() {
-  uint8_t x1 = 0;
-  uint16_t x2 = 0;
+  long x1 = 0;
+  long x2 = 0;

DavidSpickett wrote:

We need the type change here because?

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-17 Thread David Spickett via lldb-commits


@@ -0,0 +1,61 @@
+//===-- 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/Target/WatchpointResourceList.h"
+#include "lldb/Target/WatchpointResource.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+WatchpointResourceList::WatchpointResourceList() : m_resources(), m_mutex() {}
+
+WatchpointResourceList::~WatchpointResourceList() { Clear(); }
+
+uint32_t WatchpointResourceList::GetSize() {
+  std::lock_guard guard(m_mutex);
+  return m_resources.size();
+}
+
+lldb::WatchpointResourceSP
+WatchpointResourceList::GetResourceAtIndex(uint32_t idx) {
+  std::lock_guard guard(m_mutex);
+  if (idx < m_resources.size()) {
+return m_resources[idx];
+  } else {
+return {};

DavidSpickett wrote:

Single line ifs.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-17 Thread David Spickett via lldb-commits


@@ -0,0 +1,61 @@
+//===-- 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/Target/WatchpointResourceList.h"
+#include "lldb/Target/WatchpointResource.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+WatchpointResourceList::WatchpointResourceList() : m_resources(), m_mutex() {}
+
+WatchpointResourceList::~WatchpointResourceList() { Clear(); }
+
+uint32_t WatchpointResourceList::GetSize() {
+  std::lock_guard guard(m_mutex);
+  return m_resources.size();
+}
+
+lldb::WatchpointResourceSP
+WatchpointResourceList::GetResourceAtIndex(uint32_t idx) {
+  std::lock_guard guard(m_mutex);
+  if (idx < m_resources.size()) {
+return m_resources[idx];
+  } else {
+return {};

DavidSpickett wrote:

Also return in an else (as in, no need for the else)

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-17 Thread David Spickett via lldb-commits


@@ -135,5 +135,5 @@ def test_watch_address_with_invalid_watch_size(self):
 self.expect(
 error.GetCString(),
 exe=False,
-substrs=["watch size of %d is not supported" % 365],
+substrs=["Setting one of the watchpoint resources failed"],

DavidSpickett wrote:

Is the original error still relevant? Should it be one of the watchpoint 
resources failed because...

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-17 Thread David Spickett via lldb-commits


@@ -1,3 +1,10 @@
 # REQUIRES: system-darwin
+# TODO: This test is breaking with my output 
+# reformatting done for Large Watchpoint support,
+# but the lines being output by lldb are identical,
+# by visual inspection.  
+# FileCheck is seeing some difference between them,
+# which I need to get to the bottom of.

DavidSpickett wrote:

A trick I used to do for python doctests was `str.replace(" ", "?")`. Then you 
could see the trailing spaces. Might work here if you have that or extra 
newlines.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-12 Thread Jason Molenda via lldb-commits

jasonmolenda wrote:

I started on the next step of updating ProcessGDBRemote to identify the 
WatchpointResource that was hit by a watchpoint stop, and evaluate all of its 
Watchpoints, when I looked at BreakpointSite and BreakpointSiteList and realize 
I should have started by coping their design/functionality.  I'm rewriting 
WatchpointResource / WatchpointResourceList right now.

https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-11 Thread via lldb-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 1379a7286e156af2d96cb0f3d8aa8e5c7f56bccd 
791fd06fe642f1163c39d79c57c7a6daae2c8ea6 -- 
lldb/include/lldb/Target/WatchpointResource.h 
lldb/include/lldb/Target/WatchpointResourceList.h 
lldb/source/Target/WatchpointResource.cpp 
lldb/source/Target/WatchpointResourceList.cpp 
lldb/include/lldb/Breakpoint/Watchpoint.h 
lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h 
lldb/include/lldb/Target/Process.h lldb/include/lldb/lldb-forward.h 
lldb/source/API/SBWatchpoint.cpp lldb/source/Breakpoint/Watchpoint.cpp 
lldb/source/Commands/CommandObjectWatchpoint.cpp 
lldb/source/Interpreter/OptionGroupWatchpoint.cpp 
lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp 
lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h 
lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp 
lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp 
lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h 
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp 
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h 
lldb/source/Target/Process.cpp lldb/source/Target/StopInfo.cpp 
lldb/source/Target/Target.cpp 
lldb/test/API/commands/watchpoints/watchpoint_count/main.c 
lldb/test/Shell/Watchpoint/Inputs/val.c
``





View the diff from clang-format here.


``diff
diff --git a/lldb/source/Interpreter/OptionGroupWatchpoint.cpp 
b/lldb/source/Interpreter/OptionGroupWatchpoint.cpp
index d1ae916cd74b..48cbc9ec0e75 100644
--- a/lldb/source/Interpreter/OptionGroupWatchpoint.cpp
+++ b/lldb/source/Interpreter/OptionGroupWatchpoint.cpp
@@ -43,8 +43,15 @@ 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, {}, 0, eArgTypeByteSize, 
+{LLDB_OPT_SET_1,
+ false,
+ "size",
+ 's',
+ OptionParser::eRequiredArgument,
+ nullptr,
+ {},
+ 0,
+ eArgTypeByteSize,
  "Number of bytes to use to watch a region."},
 {LLDB_OPT_SET_2,
  false,

``




https://github.com/llvm/llvm-project/pull/68845
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-11 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Jason Molenda (jasonmolenda)


Changes

This patch is rearranging code a bit to add WatchpointResources to Process.  A 
WatchpointResource is meant to represent a hardware watchpoint register in the 
inferior process.  It has an address, a size, a type, and a list of Watchpoints 
that are using this WatchpointResource.

This current patch doesn't add any of the features of WatchpointResources that 
make them interesting -- a user asking to watch a 24 byte object could watch 
this with three 8 byte WatchpointResources.  Or a Watchpoint on 1 byte at 
0x1002 and a second watchpoint on 1 byte at 0x1003, these must both be served 
by a single WatchpointResource on that doubleword at 0x1000 on a 64-bit target, 
if two hardware watchpoint registers were used to track these separately, one 
of them may not be hit.  Or if you have one Watchpoint on a variable with a 
condition set, and another Watchpoint on that same variable with a command 
defined or different condition, or ignorecount, both of those Watchpoints need 
to evaluate their criteria/commands when their WatchpointResource has been hit.

There's a bit of code movement to rearrange things in the direction I'll need 
for implementing this feature, so I want to start with reviewing  landing 
this mostly NFC patch and we can focus on the algorithmic choices about how 
WatchpointResources are shared and handled as they're triggeed, separately.

This patch also stops printing "Watchpoint n hit: old value: x, 
new vlaue: y" for Read watchpoints.  I could make an argument for print 
"Watchpoint n hit: current value x" but the current output 
doesn't make any sense, and the user can print the value if they are 
particularly interested.  Read watchpoints are used primarily to understand 
what code is reading a variable.

This patch adds more fallbacks for how to print the objects being watched if we 
have types, instead of assuming they are all integral values, so a struct will 
print its elements.  As large watchpoints are added, we'll be doing a lot more 
of those.

To track the WatchpointSP in the WatchpointResources, I changed the internal 
API which took a WatchpointSP and devolved it to a Watchpoint*, which meant 
touching several different Process files. I removed the watchpoint code in 
ProcessKDP which only reported that watchpoints aren't supported, the base 
class does that already.

I haven't yet changed how we receive a watchpoint to identify the 
WatchpointResource responsible for the trigger, and identify all Watchpoints 
that are using this Resource to evaluate their conditions etc.  This is the 
same work that a BreakpointSite needs to do when it has been tiggered, where 
multiple Breakpoints may be at the same address.

There is not yet any printing of the Resources that a Watchpoint is implemented 
in terms of ("watchpoint list", or
SBWatchpoint::GetDescription).

"watchpoint set var" and "watchpoint set expression" take a size argument which 
was previously 1, 2, 4, or 8 (an enum).  I've changed this to an unsigned int.  
Most hardware implementations can only watch 1, 2, 4, 8 byte ranges, but with 
Resources we'll allow a user to ask for different sized watchpoints and set 
them in hardware-expressble terms soon.

I've annotated areas where I know there is work still needed with LWP_TODO that 
I'll be working on once this is landed.

I've tested this on aarch64 macOS, aarch64 Linux, and Intel macOS.

https://discourse.llvm.org/t/rfc-large-watchpoint-support-in-lldb/72116

---

Patch is 54.63 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/68845.diff


28 Files Affected:

- (modified) lldb/include/lldb/Breakpoint/Watchpoint.h (+1-1) 
- (modified) lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h (+2-3) 
- (modified) lldb/include/lldb/Target/Process.h (+10-2) 
- (added) lldb/include/lldb/Target/WatchpointResource.h (+57) 
- (added) lldb/include/lldb/Target/WatchpointResourceList.h (+85) 
- (modified) lldb/include/lldb/lldb-forward.h (+2) 
- (modified) lldb/source/API/SBWatchpoint.cpp (+2-2) 
- (modified) lldb/source/Breakpoint/Watchpoint.cpp (+56-15) 
- (modified) lldb/source/Commands/CommandObjectWatchpoint.cpp (+4-4) 
- (modified) lldb/source/Interpreter/OptionGroupWatchpoint.cpp (+6-37) 
- (modified) lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp (-14) 
- (modified) lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h (-7) 
- (modified) lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp (+9) 
- (modified) lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp 
(+21-19) 
- (modified) lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h (+4-2) 
- (modified) lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp 
(+143-61) 
- (modified) lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (+4-2) 
- (modified) lldb/source/Target/CMakeLists.txt (+2) 
- (modified) lldb/source/Target/Process.cpp 

[Lldb-commits] [lldb] [lldb] [mostly NFC] Large WP foundation: WatchpointResources (PR #68845)

2023-10-11 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda created 
https://github.com/llvm/llvm-project/pull/68845

This patch is rearranging code a bit to add WatchpointResources to Process.  A 
WatchpointResource is meant to represent a hardware watchpoint register in the 
inferior process.  It has an address, a size, a type, and a list of Watchpoints 
that are using this WatchpointResource.

This current patch doesn't add any of the features of WatchpointResources that 
make them interesting -- a user asking to watch a 24 byte object could watch 
this with three 8 byte WatchpointResources.  Or a Watchpoint on 1 byte at 
0x1002 and a second watchpoint on 1 byte at 0x1003, these must both be served 
by a single WatchpointResource on that doubleword at 0x1000 on a 64-bit target, 
if two hardware watchpoint registers were used to track these separately, one 
of them may not be hit.  Or if you have one Watchpoint on a variable with a 
condition set, and another Watchpoint on that same variable with a command 
defined or different condition, or ignorecount, both of those Watchpoints need 
to evaluate their criteria/commands when their WatchpointResource has been hit.

There's a bit of code movement to rearrange things in the direction I'll need 
for implementing this feature, so I want to start with reviewing & landing this 
mostly NFC patch and we can focus on the algorithmic choices about how 
WatchpointResources are shared and handled as they're triggeed, separately.

This patch also stops printing "Watchpoint  hit: old value: , new vlaue: 
" for Read watchpoints.  I could make an argument for print "Watchpoint  
hit: current value " but the current output doesn't make any sense, and the 
user can print the value if they are particularly interested.  Read watchpoints 
are used primarily to understand what code is reading a variable.

This patch adds more fallbacks for how to print the objects being watched if we 
have types, instead of assuming they are all integral values, so a struct will 
print its elements.  As large watchpoints are added, we'll be doing a lot more 
of those.

To track the WatchpointSP in the WatchpointResources, I changed the internal 
API which took a WatchpointSP and devolved it to a Watchpoint*, which meant 
touching several different Process files. I removed the watchpoint code in 
ProcessKDP which only reported that watchpoints aren't supported, the base 
class does that already.

I haven't yet changed how we receive a watchpoint to identify the 
WatchpointResource responsible for the trigger, and identify all Watchpoints 
that are using this Resource to evaluate their conditions etc.  This is the 
same work that a BreakpointSite needs to do when it has been tiggered, where 
multiple Breakpoints may be at the same address.

There is not yet any printing of the Resources that a Watchpoint is implemented 
in terms of ("watchpoint list", or
SBWatchpoint::GetDescription).

"watchpoint set var" and "watchpoint set expression" take a size argument which 
was previously 1, 2, 4, or 8 (an enum).  I've changed this to an unsigned int.  
Most hardware implementations can only watch 1, 2, 4, 8 byte ranges, but with 
Resources we'll allow a user to ask for different sized watchpoints and set 
them in hardware-expressble terms soon.

I've annotated areas where I know there is work still needed with LWP_TODO that 
I'll be working on once this is landed.

I've tested this on aarch64 macOS, aarch64 Linux, and Intel macOS.

https://discourse.llvm.org/t/rfc-large-watchpoint-support-in-lldb/72116

>From 791fd06fe642f1163c39d79c57c7a6daae2c8ea6 Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Wed, 11 Oct 2023 20:05:58 -0700
Subject: [PATCH] [lldb] [mostly NFC] Large WP foundation: WatchpointResources

This patch is rearranging code a bit to add WatchpointResources to
Process.  A WatchpointResource is meant to represent a hardware
watchpoint register in the inferior process.  It has an address, a
size, a type, and a list of Watchpoints that are using this
WatchpointResource.

This current patch doesn't add any of the features of WatchpointResources
that make them interesting -- a user asking to watch a 24 byte
object could watch this with three 8 byte WatchpointResources.  Or
a Watchpoint on 1 byte at 0x1002 and a second watchpoint on 1 byte
at 0x1003, these must both be served by a single WatchpointResource
on that doubleword at 0x1000 on a 64-bit target, if two hardware
watchpoint registers were used to track these separately, one of
them may not be hit.  Or if you have one Watchpoint on a variable
with a condition set, and another Watchpoint on that same variable
with a command defined or different condition, or ignorecount, both
of those Watchpoints need to evaluate their criteria/commands when
their WatchpointResource has been hit.

There's a bit of code movement to rearrange things in the direction
I'll need for implementing this feature, so I want to start with
reviewing & landing this mostly NFC patch and we can