brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.7 KiB · adff429 Raw
223 lines · cpp
1//===-- BreakpointLocationCollection.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 "lldb/Breakpoint/BreakpointLocationCollection.h"10#include "lldb/Breakpoint/Breakpoint.h"11#include "lldb/Breakpoint/BreakpointLocation.h"12#include "lldb/Core/ModuleList.h"13#include "lldb/Target/Thread.h"14#include "lldb/Target/ThreadSpec.h"15 16using namespace lldb;17using namespace lldb_private;18 19// BreakpointLocationCollection constructor20BreakpointLocationCollection::BreakpointLocationCollection(bool preserving)21    : m_preserving_bkpts(preserving) {}22 23// Destructor24BreakpointLocationCollection::~BreakpointLocationCollection() = default;25 26void BreakpointLocationCollection::Add(const BreakpointLocationSP &bp_loc) {27  std::lock_guard<std::recursive_mutex> guard(m_collection_mutex);28  BreakpointLocationSP old_bp_loc =29      FindByIDPair(bp_loc->GetBreakpoint().GetID(), bp_loc->GetID());30  if (!old_bp_loc.get()) {31    m_break_loc_collection.push_back(bp_loc);32    if (m_preserving_bkpts) {33      lldb::break_id_t bp_loc_id = bp_loc->GetID();34      Breakpoint &bkpt = bp_loc->GetBreakpoint();35      lldb::break_id_t bp_id = bkpt.GetID();36      std::pair<lldb::break_id_t, lldb::break_id_t> key =37          std::make_pair(bp_id, bp_loc_id);38      auto entry = m_preserved_bps.find(key);39      if (entry == m_preserved_bps.end())40        m_preserved_bps.emplace(key, bkpt.shared_from_this());41    }42  }43}44 45bool BreakpointLocationCollection::Remove(lldb::break_id_t bp_id,46                                          lldb::break_id_t bp_loc_id) {47  std::lock_guard<std::recursive_mutex> guard(m_collection_mutex);48  collection::iterator pos = GetIDPairIterator(bp_id, bp_loc_id); // Predicate49  if (pos != m_break_loc_collection.end()) {50    if (m_preserving_bkpts) {51      std::pair<lldb::break_id_t, lldb::break_id_t> key =52          std::make_pair(bp_id, bp_loc_id);53      auto entry = m_preserved_bps.find(key);54      if (entry == m_preserved_bps.end())55        assert(0 && "Breakpoint added to collection but not preserving map.");56      else57        m_preserved_bps.erase(entry);58    }59    m_break_loc_collection.erase(pos);60    return true;61  }62  return false;63}64 65class BreakpointIDPairMatches {66public:67  BreakpointIDPairMatches(lldb::break_id_t break_id,68                          lldb::break_id_t break_loc_id)69      : m_break_id(break_id), m_break_loc_id(break_loc_id) {}70 71  bool operator()(const BreakpointLocationSP &bp_loc) const {72    return m_break_id == bp_loc->GetBreakpoint().GetID() &&73           m_break_loc_id == bp_loc->GetID();74  }75 76private:77  const lldb::break_id_t m_break_id;78  const lldb::break_id_t m_break_loc_id;79};80 81BreakpointLocationCollection::collection::iterator82BreakpointLocationCollection::GetIDPairIterator(lldb::break_id_t break_id,83                                                lldb::break_id_t break_loc_id) {84  return llvm::find_if(85      m_break_loc_collection,                           // Search full range86      BreakpointIDPairMatches(break_id, break_loc_id)); // Predicate87}88 89BreakpointLocationCollection::collection::const_iterator90BreakpointLocationCollection::GetIDPairConstIterator(91    lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const {92  return llvm::find_if(93      m_break_loc_collection,                           // Search full range94      BreakpointIDPairMatches(break_id, break_loc_id)); // Predicate95}96 97BreakpointLocationSP98BreakpointLocationCollection::FindByIDPair(lldb::break_id_t break_id,99                                           lldb::break_id_t break_loc_id) {100  BreakpointLocationSP stop_sp;101  collection::iterator pos = GetIDPairIterator(break_id, break_loc_id);102  if (pos != m_break_loc_collection.end())103    stop_sp = *pos;104 105  return stop_sp;106}107 108const BreakpointLocationSP BreakpointLocationCollection::FindByIDPair(109    lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const {110  BreakpointLocationSP stop_sp;111  collection::const_iterator pos =112      GetIDPairConstIterator(break_id, break_loc_id);113  if (pos != m_break_loc_collection.end())114    stop_sp = *pos;115 116  return stop_sp;117}118 119BreakpointLocationSP BreakpointLocationCollection::GetByIndex(size_t i) {120  std::lock_guard<std::recursive_mutex> guard(m_collection_mutex);121  BreakpointLocationSP stop_sp;122  if (i < m_break_loc_collection.size())123    stop_sp = m_break_loc_collection[i];124 125  return stop_sp;126}127 128const BreakpointLocationSP129BreakpointLocationCollection::GetByIndex(size_t i) const {130  std::lock_guard<std::recursive_mutex> guard(m_collection_mutex);131  BreakpointLocationSP stop_sp;132  if (i < m_break_loc_collection.size())133    stop_sp = m_break_loc_collection[i];134 135  return stop_sp;136}137 138bool BreakpointLocationCollection::ShouldStop(139    StoppointCallbackContext *context,140    BreakpointLocationCollection &stopped_bp_locs) {141  bool shouldStop = false;142  size_t i = 0;143  size_t prev_size = GetSize();144  while (i < prev_size) {145    // ShouldStop can remove the breakpoint from the list, or even delete146    // it, so we should147    BreakpointLocationSP cur_loc_sp = GetByIndex(i);148    BreakpointLocationSP reported_loc_sp;149    BreakpointSP keep_bkpt_alive_sp = cur_loc_sp->GetBreakpoint().shared_from_this();150    // We're building up the list or which locations claim responsibility for151    // this stop.  If the location's ShouldStop defers to a facade location by152    // returning a non-null reported location, we want to use that.  Otherwise153    // use the original location.154    if (cur_loc_sp->ShouldStop(context, reported_loc_sp)) {155      if (reported_loc_sp)156        stopped_bp_locs.Add(reported_loc_sp);157      else158        stopped_bp_locs.Add(cur_loc_sp);159 160      shouldStop = true;161    }162 163    if (prev_size == GetSize())164      i++;165    prev_size = GetSize();166  }167  return shouldStop;168}169 170bool BreakpointLocationCollection::ValidForThisThread(Thread &thread) {171  std::lock_guard<std::recursive_mutex> guard(m_collection_mutex);172  collection::iterator pos, begin = m_break_loc_collection.begin(),173                            end = m_break_loc_collection.end();174 175  for (pos = begin; pos != end; ++pos) {176    if ((*pos)->ValidForThisThread(thread))177      return true;178  }179  return false;180}181 182bool BreakpointLocationCollection::IsInternal() const {183  std::lock_guard<std::recursive_mutex> guard(m_collection_mutex);184  collection::const_iterator pos, begin = m_break_loc_collection.begin(),185                                  end = m_break_loc_collection.end();186 187  bool is_internal = true;188 189  for (pos = begin; pos != end; ++pos) {190    if (!(*pos)->GetBreakpoint().IsInternal()) {191      is_internal = false;192      break;193    }194  }195  return is_internal;196}197 198void BreakpointLocationCollection::GetDescription(199    Stream *s, lldb::DescriptionLevel level) {200  std::lock_guard<std::recursive_mutex> guard(m_collection_mutex);201  collection::iterator pos, begin = m_break_loc_collection.begin(),202                            end = m_break_loc_collection.end();203 204  for (pos = begin; pos != end; ++pos) {205    if (pos != begin)206      s->PutChar(' ');207    (*pos)->GetDescription(s, level);208  }209}210 211BreakpointLocationCollection &BreakpointLocationCollection::operator=(212    const BreakpointLocationCollection &rhs) {213  if (this != &rhs) {214      std::lock(m_collection_mutex, rhs.m_collection_mutex);215      std::lock_guard<std::recursive_mutex> lhs_guard(m_collection_mutex,216                                                      std::adopt_lock);217      std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_collection_mutex,218                                                      std::adopt_lock);219      m_break_loc_collection = rhs.m_break_loc_collection;220  }221  return *this;222}223