Path: blob/main/contrib/llvm-project/lldb/source/Breakpoint/WatchpointResource.cpp
39587 views
//===-- WatchpointResource.cpp --------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include <assert.h>910#include "lldb/Breakpoint/WatchpointResource.h"11#include "lldb/Utility/Stream.h"1213#include <algorithm>1415using namespace lldb;16using namespace lldb_private;1718WatchpointResource::WatchpointResource(lldb::addr_t addr, size_t size,19bool read, bool write)20: m_id(GetNextID()), m_addr(addr), m_size(size),21m_watch_read(read), m_watch_write(write) {}2223WatchpointResource::~WatchpointResource() {24std::lock_guard<std::mutex> guard(m_constituents_mutex);25m_constituents.clear();26}2728addr_t WatchpointResource::GetLoadAddress() const { return m_addr; }2930size_t WatchpointResource::GetByteSize() const { return m_size; }3132bool WatchpointResource::WatchpointResourceRead() const { return m_watch_read; }3334bool WatchpointResource::WatchpointResourceWrite() const {35return m_watch_write;36}3738void WatchpointResource::SetType(bool read, bool write) {39m_watch_read = read;40m_watch_write = write;41}4243wp_resource_id_t WatchpointResource::GetID() const { return m_id; }4445bool WatchpointResource::Contains(addr_t addr) {46if (addr >= m_addr && addr < m_addr + m_size)47return true;48return false;49}5051void WatchpointResource::AddConstituent(const WatchpointSP &wp_sp) {52std::lock_guard<std::mutex> guard(m_constituents_mutex);53m_constituents.push_back(wp_sp);54}5556void WatchpointResource::RemoveConstituent(WatchpointSP &wp_sp) {57std::lock_guard<std::mutex> guard(m_constituents_mutex);58const auto &it =59std::find(m_constituents.begin(), m_constituents.end(), wp_sp);60if (it != m_constituents.end())61m_constituents.erase(it);62}6364size_t WatchpointResource::GetNumberOfConstituents() {65std::lock_guard<std::mutex> guard(m_constituents_mutex);66return m_constituents.size();67}6869bool WatchpointResource::ConstituentsContains(const WatchpointSP &wp_sp) {70return ConstituentsContains(wp_sp.get());71}7273bool WatchpointResource::ConstituentsContains(const Watchpoint *wp) {74std::lock_guard<std::mutex> guard(m_constituents_mutex);75WatchpointCollection::const_iterator match =76std::find_if(m_constituents.begin(), m_constituents.end(),77[&wp](const WatchpointSP &x) { return x.get() == wp; });78return match != m_constituents.end();79}8081WatchpointSP WatchpointResource::GetConstituentAtIndex(size_t idx) {82std::lock_guard<std::mutex> guard(m_constituents_mutex);83assert(idx < m_constituents.size());84if (idx >= m_constituents.size())85return {};8687return m_constituents[idx];88}8990WatchpointResource::WatchpointCollection91WatchpointResource::CopyConstituentsList() {92std::lock_guard<std::mutex> guard(m_constituents_mutex);93return m_constituents;94}9596bool WatchpointResource::ShouldStop(StoppointCallbackContext *context) {97// LWP_TODO: Need to poll all Watchpoint constituents and see if98// we should stop, like BreakpointSites do.99#if 0100m_hit_counter.Increment();101// ShouldStop can do a lot of work, and might even come back and hit102// this breakpoint site again. So don't hold the m_constituents_mutex the103// whole while. Instead make a local copy of the collection and call104// ShouldStop on the copy.105WatchpointResourceCollection constituents_copy;106{107std::lock_guard<std::recursive_mutex> guard(m_constituents_mutex);108constituents_copy = m_constituents;109}110return constituents_copy.ShouldStop(context);111#endif112return true;113}114115void WatchpointResource::Dump(Stream *s) const {116s->Printf("addr = 0x%8.8" PRIx64 " size = %zu", m_addr, m_size);117}118119wp_resource_id_t WatchpointResource::GetNextID() {120static wp_resource_id_t g_next_id = 0;121return ++g_next_id;122}123124125