1 //===-- BreakpointList.cpp --------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Breakpoint/BreakpointList.h"
14 // Other libraries and framework includes
16 #include "lldb/Target/Target.h"
19 using namespace lldb_private;
21 BreakpointList::BreakpointList(bool is_internal)
22 : m_mutex(), m_breakpoints(), m_next_break_id(0),
23 m_is_internal(is_internal) {}
25 BreakpointList::~BreakpointList() {}
27 break_id_t BreakpointList::Add(BreakpointSP &bp_sp, bool notify) {
28 std::lock_guard<std::recursive_mutex> guard(m_mutex);
29 // Internal breakpoint IDs are negative, normal ones are positive
30 bp_sp->SetID(m_is_internal ? --m_next_break_id : ++m_next_break_id);
32 m_breakpoints.push_back(bp_sp);
34 if (bp_sp->GetTarget().EventTypeHasListeners(
35 Target::eBroadcastBitBreakpointChanged))
36 bp_sp->GetTarget().BroadcastEvent(Target::eBroadcastBitBreakpointChanged,
37 new Breakpoint::BreakpointEventData(
38 eBreakpointEventTypeAdded, bp_sp));
40 return bp_sp->GetID();
43 bool BreakpointList::Remove(break_id_t break_id, bool notify) {
44 std::lock_guard<std::recursive_mutex> guard(m_mutex);
45 bp_collection::iterator pos = GetBreakpointIDIterator(break_id); // Predicate
46 if (pos != m_breakpoints.end()) {
47 BreakpointSP bp_sp(*pos);
48 m_breakpoints.erase(pos);
50 if (bp_sp->GetTarget().EventTypeHasListeners(
51 Target::eBroadcastBitBreakpointChanged))
52 bp_sp->GetTarget().BroadcastEvent(
53 Target::eBroadcastBitBreakpointChanged,
54 new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved,
62 void BreakpointList::RemoveInvalidLocations(const ArchSpec &arch) {
63 std::lock_guard<std::recursive_mutex> guard(m_mutex);
64 for (const auto &bp_sp : m_breakpoints)
65 bp_sp->RemoveInvalidLocations(arch);
68 void BreakpointList::SetEnabledAll(bool enabled) {
69 std::lock_guard<std::recursive_mutex> guard(m_mutex);
70 for (const auto &bp_sp : m_breakpoints)
71 bp_sp->SetEnabled(enabled);
74 void BreakpointList::SetEnabledAllowed(bool enabled) {
75 std::lock_guard<std::recursive_mutex> guard(m_mutex);
76 for (const auto &bp_sp : m_breakpoints)
77 if (bp_sp->AllowDisable())
78 bp_sp->SetEnabled(enabled);
81 void BreakpointList::RemoveAll(bool notify) {
82 std::lock_guard<std::recursive_mutex> guard(m_mutex);
83 ClearAllBreakpointSites();
86 bp_collection::iterator pos, end = m_breakpoints.end();
87 for (pos = m_breakpoints.begin(); pos != end; ++pos) {
88 if ((*pos)->GetTarget().EventTypeHasListeners(
89 Target::eBroadcastBitBreakpointChanged)) {
90 (*pos)->GetTarget().BroadcastEvent(
91 Target::eBroadcastBitBreakpointChanged,
92 new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved,
97 m_breakpoints.erase(m_breakpoints.begin(), m_breakpoints.end());
100 void BreakpointList::RemoveAllowed(bool notify) {
101 std::lock_guard<std::recursive_mutex> guard(m_mutex);
103 bp_collection::iterator pos, end = m_breakpoints.end();
105 for (pos = m_breakpoints.begin(); pos != end; ++pos) {
106 if(!(*pos)->AllowDelete())
108 if ((*pos)->GetTarget().EventTypeHasListeners(
109 Target::eBroadcastBitBreakpointChanged)) {
110 (*pos)->GetTarget().BroadcastEvent(
111 Target::eBroadcastBitBreakpointChanged,
112 new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved,
117 pos = m_breakpoints.begin();
118 while ( pos != end) {
120 if (bp->AllowDelete()) {
121 bp->ClearAllBreakpointSites();
122 pos = m_breakpoints.erase(pos);
128 class BreakpointIDMatches {
130 BreakpointIDMatches(break_id_t break_id) : m_break_id(break_id) {}
132 bool operator()(const BreakpointSP &bp) const {
133 return m_break_id == bp->GetID();
137 const break_id_t m_break_id;
140 BreakpointList::bp_collection::iterator
141 BreakpointList::GetBreakpointIDIterator(break_id_t break_id) {
142 return std::find_if(m_breakpoints.begin(),
143 m_breakpoints.end(), // Search full range
144 BreakpointIDMatches(break_id)); // Predicate
147 BreakpointList::bp_collection::const_iterator
148 BreakpointList::GetBreakpointIDConstIterator(break_id_t break_id) const {
149 return std::find_if(m_breakpoints.begin(),
150 m_breakpoints.end(), // Search full range
151 BreakpointIDMatches(break_id)); // Predicate
154 BreakpointSP BreakpointList::FindBreakpointByID(break_id_t break_id) {
155 std::lock_guard<std::recursive_mutex> guard(m_mutex);
156 BreakpointSP stop_sp;
157 bp_collection::iterator pos = GetBreakpointIDIterator(break_id);
158 if (pos != m_breakpoints.end())
165 BreakpointList::FindBreakpointByID(break_id_t break_id) const {
166 std::lock_guard<std::recursive_mutex> guard(m_mutex);
167 BreakpointSP stop_sp;
168 bp_collection::const_iterator pos = GetBreakpointIDConstIterator(break_id);
169 if (pos != m_breakpoints.end())
175 bool BreakpointList::FindBreakpointsByName(const char *name,
176 BreakpointList &matching_bps) {
181 if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(name), error))
184 for (BreakpointSP bkpt_sp : Breakpoints()) {
185 if (bkpt_sp->MatchesName(name)) {
186 matching_bps.Add(bkpt_sp, false);
192 void BreakpointList::Dump(Stream *s) const {
193 std::lock_guard<std::recursive_mutex> guard(m_mutex);
194 s->Printf("%p: ", static_cast<const void *>(this));
196 s->Printf("BreakpointList with %u Breakpoints:\n",
197 (uint32_t)m_breakpoints.size());
199 for (const auto &bp_sp : m_breakpoints)
204 BreakpointSP BreakpointList::GetBreakpointAtIndex(size_t i) {
205 std::lock_guard<std::recursive_mutex> guard(m_mutex);
206 BreakpointSP stop_sp;
207 bp_collection::iterator end = m_breakpoints.end();
208 bp_collection::iterator pos;
210 for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) {
217 const BreakpointSP BreakpointList::GetBreakpointAtIndex(size_t i) const {
218 std::lock_guard<std::recursive_mutex> guard(m_mutex);
219 BreakpointSP stop_sp;
220 bp_collection::const_iterator end = m_breakpoints.end();
221 bp_collection::const_iterator pos;
223 for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) {
230 void BreakpointList::UpdateBreakpoints(ModuleList &module_list, bool added,
231 bool delete_locations) {
232 std::lock_guard<std::recursive_mutex> guard(m_mutex);
233 for (const auto &bp_sp : m_breakpoints)
234 bp_sp->ModulesChanged(module_list, added, delete_locations);
237 void BreakpointList::UpdateBreakpointsWhenModuleIsReplaced(
238 ModuleSP old_module_sp, ModuleSP new_module_sp) {
239 std::lock_guard<std::recursive_mutex> guard(m_mutex);
240 for (const auto &bp_sp : m_breakpoints)
241 bp_sp->ModuleReplaced(old_module_sp, new_module_sp);
244 void BreakpointList::ClearAllBreakpointSites() {
245 std::lock_guard<std::recursive_mutex> guard(m_mutex);
246 for (const auto &bp_sp : m_breakpoints)
247 bp_sp->ClearAllBreakpointSites();
250 void BreakpointList::GetListMutex(
251 std::unique_lock<std::recursive_mutex> &lock) {
252 lock = std::unique_lock<std::recursive_mutex>(m_mutex);