]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Breakpoint/BreakpointList.cpp
Vendor import of lldb trunk r338150:
[FreeBSD/FreeBSD.git] / source / Breakpoint / BreakpointList.cpp
1 //===-- BreakpointList.cpp --------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Breakpoint/BreakpointList.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Target/Target.h"
17
18 using namespace lldb;
19 using namespace lldb_private;
20
21 BreakpointList::BreakpointList(bool is_internal)
22     : m_mutex(), m_breakpoints(), m_next_break_id(0),
23       m_is_internal(is_internal) {}
24
25 BreakpointList::~BreakpointList() {}
26
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);
31
32   m_breakpoints.push_back(bp_sp);
33   if (notify) {
34     if (bp_sp->GetTarget().EventTypeHasListeners(
35             Target::eBroadcastBitBreakpointChanged))
36       bp_sp->GetTarget().BroadcastEvent(Target::eBroadcastBitBreakpointChanged,
37                                         new Breakpoint::BreakpointEventData(
38                                             eBreakpointEventTypeAdded, bp_sp));
39   }
40   return bp_sp->GetID();
41 }
42
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);
49     if (notify) {
50       if (bp_sp->GetTarget().EventTypeHasListeners(
51               Target::eBroadcastBitBreakpointChanged))
52         bp_sp->GetTarget().BroadcastEvent(
53             Target::eBroadcastBitBreakpointChanged,
54             new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved,
55                                                 bp_sp));
56     }
57     return true;
58   }
59   return false;
60 }
61
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);
66 }
67
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);
72 }
73
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);
79 }
80
81 void BreakpointList::RemoveAll(bool notify) {
82   std::lock_guard<std::recursive_mutex> guard(m_mutex);
83   ClearAllBreakpointSites();
84
85   if (notify) {
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,
93                                                 *pos));
94       }
95     }
96   }
97   m_breakpoints.erase(m_breakpoints.begin(), m_breakpoints.end());
98 }
99
100 void BreakpointList::RemoveAllowed(bool notify) {
101   std::lock_guard<std::recursive_mutex> guard(m_mutex);
102
103   bp_collection::iterator pos, end = m_breakpoints.end();
104   if (notify) {
105     for (pos = m_breakpoints.begin(); pos != end; ++pos) {
106       if(!(*pos)->AllowDelete())
107         continue;
108       if ((*pos)->GetTarget().EventTypeHasListeners(
109               Target::eBroadcastBitBreakpointChanged)) {
110         (*pos)->GetTarget().BroadcastEvent(
111             Target::eBroadcastBitBreakpointChanged,
112             new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved,
113                                                 *pos));
114       }
115     }
116   }
117   pos = m_breakpoints.begin();
118   while ( pos != end) {
119     auto bp = *pos;
120     if (bp->AllowDelete()) {
121       bp->ClearAllBreakpointSites();
122       pos = m_breakpoints.erase(pos);
123     } else
124       pos++;
125   }
126 }
127
128 class BreakpointIDMatches {
129 public:
130   BreakpointIDMatches(break_id_t break_id) : m_break_id(break_id) {}
131
132   bool operator()(const BreakpointSP &bp) const {
133     return m_break_id == bp->GetID();
134   }
135
136 private:
137   const break_id_t m_break_id;
138 };
139
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
145 }
146
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
152 }
153
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())
159     stop_sp = *pos;
160
161   return stop_sp;
162 }
163
164 const BreakpointSP
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())
170     stop_sp = *pos;
171
172   return stop_sp;
173 }
174
175 bool BreakpointList::FindBreakpointsByName(const char *name,
176                                            BreakpointList &matching_bps) {
177   Status error;
178   if (!name)
179     return false;
180
181   if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(name), error))
182     return false;
183
184   for (BreakpointSP bkpt_sp : Breakpoints()) {
185     if (bkpt_sp->MatchesName(name)) {
186       matching_bps.Add(bkpt_sp, false);
187     }
188   }
189   return true;
190 }
191
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));
195   s->Indent();
196   s->Printf("BreakpointList with %u Breakpoints:\n",
197             (uint32_t)m_breakpoints.size());
198   s->IndentMore();
199   for (const auto &bp_sp : m_breakpoints)
200     bp_sp->Dump(s);
201   s->IndentLess();
202 }
203
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;
209   size_t curr_i = 0;
210   for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) {
211     if (curr_i == i)
212       stop_sp = *pos;
213   }
214   return stop_sp;
215 }
216
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;
222   size_t curr_i = 0;
223   for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) {
224     if (curr_i == i)
225       stop_sp = *pos;
226   }
227   return stop_sp;
228 }
229
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);
235 }
236
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);
242 }
243
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();
248 }
249
250 void BreakpointList::GetListMutex(
251     std::unique_lock<std::recursive_mutex> &lock) {
252   lock = std::unique_lock<std::recursive_mutex>(m_mutex);
253 }