121 lines · cpp
1//===-- WatchpointResource.cpp --------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include <assert.h>10 11#include "lldb/Breakpoint/WatchpointResource.h"12#include "lldb/Utility/Stream.h"13 14#include <algorithm>15 16using namespace lldb;17using namespace lldb_private;18 19WatchpointResource::WatchpointResource(lldb::addr_t addr, size_t size,20 bool read, bool write)21 : m_id(GetNextID()), m_addr(addr), m_size(size),22 m_watch_read(read), m_watch_write(write) {}23 24WatchpointResource::~WatchpointResource() {25 std::lock_guard<std::mutex> guard(m_constituents_mutex);26 m_constituents.clear();27}28 29addr_t WatchpointResource::GetLoadAddress() const { return m_addr; }30 31size_t WatchpointResource::GetByteSize() const { return m_size; }32 33bool WatchpointResource::WatchpointResourceRead() const { return m_watch_read; }34 35bool WatchpointResource::WatchpointResourceWrite() const {36 return m_watch_write;37}38 39void WatchpointResource::SetType(bool read, bool write) {40 m_watch_read = read;41 m_watch_write = write;42}43 44wp_resource_id_t WatchpointResource::GetID() const { return m_id; }45 46bool WatchpointResource::Contains(addr_t addr) {47 if (addr >= m_addr && addr < m_addr + m_size)48 return true;49 return false;50}51 52void WatchpointResource::AddConstituent(const WatchpointSP &wp_sp) {53 std::lock_guard<std::mutex> guard(m_constituents_mutex);54 m_constituents.push_back(wp_sp);55}56 57void WatchpointResource::RemoveConstituent(WatchpointSP &wp_sp) {58 std::lock_guard<std::mutex> guard(m_constituents_mutex);59 auto it = llvm::find(m_constituents, wp_sp);60 if (it != m_constituents.end())61 m_constituents.erase(it);62}63 64size_t WatchpointResource::GetNumberOfConstituents() {65 std::lock_guard<std::mutex> guard(m_constituents_mutex);66 return m_constituents.size();67}68 69bool WatchpointResource::ConstituentsContains(const WatchpointSP &wp_sp) {70 return ConstituentsContains(wp_sp.get());71}72 73bool WatchpointResource::ConstituentsContains(const Watchpoint *wp) {74 std::lock_guard<std::mutex> guard(m_constituents_mutex);75 return llvm::any_of(m_constituents,76 [&wp](const WatchpointSP &x) { return x.get() == wp; });77}78 79WatchpointSP WatchpointResource::GetConstituentAtIndex(size_t idx) {80 std::lock_guard<std::mutex> guard(m_constituents_mutex);81 assert(idx < m_constituents.size());82 if (idx >= m_constituents.size())83 return {};84 85 return m_constituents[idx];86}87 88WatchpointResource::WatchpointCollection89WatchpointResource::CopyConstituentsList() {90 std::lock_guard<std::mutex> guard(m_constituents_mutex);91 return m_constituents;92}93 94bool WatchpointResource::ShouldStop(StoppointCallbackContext *context) {95 // LWP_TODO: Need to poll all Watchpoint constituents and see if96 // we should stop, like BreakpointSites do.97#if 098 m_hit_counter.Increment();99 // ShouldStop can do a lot of work, and might even come back and hit100 // this breakpoint site again. So don't hold the m_constituents_mutex the101 // whole while. Instead make a local copy of the collection and call102 // ShouldStop on the copy.103 WatchpointResourceCollection constituents_copy;104 {105 std::lock_guard<std::recursive_mutex> guard(m_constituents_mutex);106 constituents_copy = m_constituents;107 }108 return constituents_copy.ShouldStop(context);109#endif110 return true;111}112 113void WatchpointResource::Dump(Stream *s) const {114 s->Printf("addr = 0x%8.8" PRIx64 " size = %zu", m_addr, m_size);115}116 117wp_resource_id_t WatchpointResource::GetNextID() {118 static wp_resource_id_t g_next_id = 0;119 return ++g_next_id;120}121