LLDB  mainline
BreakpointLocationCollection.cpp
Go to the documentation of this file.
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
12 #include "lldb/Core/ModuleList.h"
13 #include "lldb/Target/Thread.h"
14 #include "lldb/Target/ThreadSpec.h"
15 
16 using namespace lldb;
17 using namespace lldb_private;
18 
19 // BreakpointLocationCollection constructor
20 BreakpointLocationCollection::BreakpointLocationCollection() = default;
21 
22 // Destructor
23 BreakpointLocationCollection::~BreakpointLocationCollection() = default;
24 
25 void BreakpointLocationCollection::Add(const BreakpointLocationSP &bp_loc) {
26  std::lock_guard<std::mutex> guard(m_collection_mutex);
27  BreakpointLocationSP old_bp_loc =
28  FindByIDPair(bp_loc->GetBreakpoint().GetID(), bp_loc->GetID());
29  if (!old_bp_loc.get())
30  m_break_loc_collection.push_back(bp_loc);
31 }
32 
33 bool BreakpointLocationCollection::Remove(lldb::break_id_t bp_id,
34  lldb::break_id_t bp_loc_id) {
35  std::lock_guard<std::mutex> guard(m_collection_mutex);
36  collection::iterator pos = GetIDPairIterator(bp_id, bp_loc_id); // Predicate
37  if (pos != m_break_loc_collection.end()) {
38  m_break_loc_collection.erase(pos);
39  return true;
40  }
41  return false;
42 }
43 
45 public:
47  lldb::break_id_t break_loc_id)
48  : m_break_id(break_id), m_break_loc_id(break_loc_id) {}
49 
50  bool operator()(const BreakpointLocationSP &bp_loc) const {
51  return m_break_id == bp_loc->GetBreakpoint().GetID() &&
52  m_break_loc_id == bp_loc->GetID();
53  }
54 
55 private:
58 };
59 
60 BreakpointLocationCollection::collection::iterator
61 BreakpointLocationCollection::GetIDPairIterator(lldb::break_id_t break_id,
62  lldb::break_id_t break_loc_id) {
63  return std::find_if(
64  m_break_loc_collection.begin(),
65  m_break_loc_collection.end(), // Search full range
66  BreakpointIDPairMatches(break_id, break_loc_id)); // Predicate
67 }
68 
69 BreakpointLocationCollection::collection::const_iterator
70 BreakpointLocationCollection::GetIDPairConstIterator(
71  lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const {
72  return std::find_if(
73  m_break_loc_collection.begin(),
74  m_break_loc_collection.end(), // Search full range
75  BreakpointIDPairMatches(break_id, break_loc_id)); // Predicate
76 }
77 
78 BreakpointLocationSP
79 BreakpointLocationCollection::FindByIDPair(lldb::break_id_t break_id,
80  lldb::break_id_t break_loc_id) {
81  BreakpointLocationSP stop_sp;
82  collection::iterator pos = GetIDPairIterator(break_id, break_loc_id);
83  if (pos != m_break_loc_collection.end())
84  stop_sp = *pos;
85 
86  return stop_sp;
87 }
88 
89 const BreakpointLocationSP BreakpointLocationCollection::FindByIDPair(
90  lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const {
91  BreakpointLocationSP stop_sp;
92  collection::const_iterator pos =
93  GetIDPairConstIterator(break_id, break_loc_id);
94  if (pos != m_break_loc_collection.end())
95  stop_sp = *pos;
96 
97  return stop_sp;
98 }
99 
100 BreakpointLocationSP BreakpointLocationCollection::GetByIndex(size_t i) {
101  std::lock_guard<std::mutex> guard(m_collection_mutex);
102  BreakpointLocationSP stop_sp;
103  if (i < m_break_loc_collection.size())
104  stop_sp = m_break_loc_collection[i];
105 
106  return stop_sp;
107 }
108 
109 const BreakpointLocationSP
110 BreakpointLocationCollection::GetByIndex(size_t i) const {
111  std::lock_guard<std::mutex> guard(m_collection_mutex);
112  BreakpointLocationSP stop_sp;
113  if (i < m_break_loc_collection.size())
114  stop_sp = m_break_loc_collection[i];
115 
116  return stop_sp;
117 }
118 
119 bool BreakpointLocationCollection::ShouldStop(
120  StoppointCallbackContext *context) {
121  bool shouldStop = false;
122  size_t i = 0;
123  size_t prev_size = GetSize();
124  while (i < prev_size) {
125  // ShouldStop can remove the breakpoint from the list, or even delete
126  // it, so we should
127  BreakpointLocationSP cur_loc_sp = GetByIndex(i);
128  BreakpointSP keep_bkpt_alive_sp = cur_loc_sp->GetBreakpoint().shared_from_this();
129  if (cur_loc_sp->ShouldStop(context))
130  shouldStop = true;
131 
132  if (prev_size == GetSize())
133  i++;
134  prev_size = GetSize();
135  }
136  return shouldStop;
137 }
138 
139 bool BreakpointLocationCollection::ValidForThisThread(Thread &thread) {
140  std::lock_guard<std::mutex> guard(m_collection_mutex);
141  collection::iterator pos, begin = m_break_loc_collection.begin(),
142  end = m_break_loc_collection.end();
143 
144  for (pos = begin; pos != end; ++pos) {
145  if ((*pos)->ValidForThisThread(thread))
146  return true;
147  }
148  return false;
149 }
150 
151 bool BreakpointLocationCollection::IsInternal() const {
152  std::lock_guard<std::mutex> guard(m_collection_mutex);
153  collection::const_iterator pos, begin = m_break_loc_collection.begin(),
154  end = m_break_loc_collection.end();
155 
156  bool is_internal = true;
157 
158  for (pos = begin; pos != end; ++pos) {
159  if (!(*pos)->GetBreakpoint().IsInternal()) {
160  is_internal = false;
161  break;
162  }
163  }
164  return is_internal;
165 }
166 
167 void BreakpointLocationCollection::GetDescription(
168  Stream *s, lldb::DescriptionLevel level) {
169  std::lock_guard<std::mutex> guard(m_collection_mutex);
170  collection::iterator pos, begin = m_break_loc_collection.begin(),
171  end = m_break_loc_collection.end();
172 
173  for (pos = begin; pos != end; ++pos) {
174  if (pos != begin)
175  s->PutChar(' ');
176  (*pos)->GetDescription(s, level);
177  }
178 }
179 
180 BreakpointLocationCollection &BreakpointLocationCollection::operator=(
181  const BreakpointLocationCollection &rhs) {
182  if (this != &rhs) {
183  std::lock(m_collection_mutex, rhs.m_collection_mutex);
184  std::lock_guard<std::mutex> lhs_guard(m_collection_mutex, std::adopt_lock);
185  std::lock_guard<std::mutex> rhs_guard(rhs.m_collection_mutex, std::adopt_lock);
186  m_break_loc_collection = rhs.m_break_loc_collection;
187  }
188  return *this;
189 }
lldb_private::StoppointCallbackContext
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
Definition: StoppointCallbackContext.h:26
BreakpointIDPairMatches::operator()
bool operator()(const BreakpointLocationSP &bp_loc) const
Definition: BreakpointLocationCollection.cpp:50
BreakpointLocation.h
BreakpointIDPairMatches::BreakpointIDPairMatches
BreakpointIDPairMatches(lldb::break_id_t break_id, lldb::break_id_t break_loc_id)
Definition: BreakpointLocationCollection.cpp:46
lldb_private::Stream
Definition: Stream.h:28
lldb_private::BreakpointLocationCollection::m_break_loc_collection
collection m_break_loc_collection
Definition: BreakpointLocationCollection.h:164
lldb_private::BreakpointLocationCollection::m_collection_mutex
std::mutex m_collection_mutex
Definition: BreakpointLocationCollection.h:165
BreakpointIDPairMatches::m_break_id
const lldb::break_id_t m_break_id
Definition: BreakpointLocationCollection.cpp:56
ModuleList.h
lldb_private::Thread
Definition: Thread.h:61
ThreadSpec.h
lldb::break_id_t
int32_t break_id_t
Definition: lldb-types.h:88
BreakpointIDPairMatches::m_break_loc_id
const lldb::break_id_t m_break_loc_id
Definition: BreakpointLocationCollection.cpp:57
BreakpointIDPairMatches
Definition: BreakpointLocationCollection.cpp:44
Thread.h
lldb_private::Stream::PutChar
size_t PutChar(char ch)
Definition: Stream.cpp:104
lldb_private::BreakpointLocationCollection
Definition: BreakpointLocationCollection.h:20
BreakpointLocationCollection.h
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
Breakpoint.h
lldb
Definition: SBAddress.h:15
lldb::DescriptionLevel
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
Definition: lldb-enumerations.h:207