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
BreakpointList(bool is_internal)21 BreakpointList::BreakpointList (bool is_internal) :
22 m_mutex (Mutex::eMutexTypeRecursive),
23 m_breakpoints(),
24 m_next_break_id (0),
25 m_is_internal (is_internal)
26 {
27 }
28
~BreakpointList()29 BreakpointList::~BreakpointList()
30 {
31 }
32
33
34 break_id_t
Add(BreakpointSP & bp_sp,bool notify)35 BreakpointList::Add (BreakpointSP &bp_sp, bool notify)
36 {
37 Mutex::Locker locker(m_mutex);
38 // Internal breakpoint IDs are negative, normal ones are positive
39 bp_sp->SetID (m_is_internal ? --m_next_break_id : ++m_next_break_id);
40
41 m_breakpoints.push_back(bp_sp);
42 if (notify)
43 {
44 if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
45 bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
46 new Breakpoint::BreakpointEventData (eBreakpointEventTypeAdded, bp_sp));
47 }
48 return bp_sp->GetID();
49 }
50
51 bool
Remove(break_id_t break_id,bool notify)52 BreakpointList::Remove (break_id_t break_id, bool notify)
53 {
54 Mutex::Locker locker(m_mutex);
55 bp_collection::iterator pos = GetBreakpointIDIterator(break_id); // Predicate
56 if (pos != m_breakpoints.end())
57 {
58 BreakpointSP bp_sp (*pos);
59 m_breakpoints.erase(pos);
60 if (notify)
61 {
62 if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
63 bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
64 new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved, bp_sp));
65 }
66 return true;
67 }
68 return false;
69 }
70
71 void
SetEnabledAll(bool enabled)72 BreakpointList::SetEnabledAll (bool enabled)
73 {
74 Mutex::Locker locker(m_mutex);
75 bp_collection::iterator pos, end = m_breakpoints.end();
76 for (pos = m_breakpoints.begin(); pos != end; ++pos)
77 (*pos)->SetEnabled (enabled);
78 }
79
80
81 void
RemoveAll(bool notify)82 BreakpointList::RemoveAll (bool notify)
83 {
84 Mutex::Locker locker(m_mutex);
85 ClearAllBreakpointSites ();
86
87 if (notify)
88 {
89 bp_collection::iterator pos, end = m_breakpoints.end();
90 for (pos = m_breakpoints.begin(); pos != end; ++pos)
91 {
92 if ((*pos)->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
93 {
94 (*pos)->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
95 new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved,
96 *pos));
97 }
98 }
99 }
100 m_breakpoints.erase (m_breakpoints.begin(), m_breakpoints.end());
101 }
102
103 class BreakpointIDMatches
104 {
105 public:
BreakpointIDMatches(break_id_t break_id)106 BreakpointIDMatches (break_id_t break_id) :
107 m_break_id(break_id)
108 {
109 }
110
operator ()(const BreakpointSP & bp) const111 bool operator() (const BreakpointSP &bp) const
112 {
113 return m_break_id == bp->GetID();
114 }
115
116 private:
117 const break_id_t m_break_id;
118 };
119
120 BreakpointList::bp_collection::iterator
GetBreakpointIDIterator(break_id_t break_id)121 BreakpointList::GetBreakpointIDIterator (break_id_t break_id)
122 {
123 return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
124 BreakpointIDMatches(break_id)); // Predicate
125 }
126
127 BreakpointList::bp_collection::const_iterator
GetBreakpointIDConstIterator(break_id_t break_id) const128 BreakpointList::GetBreakpointIDConstIterator (break_id_t break_id) const
129 {
130 return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
131 BreakpointIDMatches(break_id)); // Predicate
132 }
133
134 BreakpointSP
FindBreakpointByID(break_id_t break_id)135 BreakpointList::FindBreakpointByID (break_id_t break_id)
136 {
137 Mutex::Locker locker(m_mutex);
138 BreakpointSP stop_sp;
139 bp_collection::iterator pos = GetBreakpointIDIterator(break_id);
140 if (pos != m_breakpoints.end())
141 stop_sp = *pos;
142
143 return stop_sp;
144 }
145
146 const BreakpointSP
FindBreakpointByID(break_id_t break_id) const147 BreakpointList::FindBreakpointByID (break_id_t break_id) const
148 {
149 Mutex::Locker locker(m_mutex);
150 BreakpointSP stop_sp;
151 bp_collection::const_iterator pos = GetBreakpointIDConstIterator(break_id);
152 if (pos != m_breakpoints.end())
153 stop_sp = *pos;
154
155 return stop_sp;
156 }
157
158 void
Dump(Stream * s) const159 BreakpointList::Dump (Stream *s) const
160 {
161 Mutex::Locker locker(m_mutex);
162 s->Printf("%p: ", this);
163 s->Indent();
164 s->Printf("BreakpointList with %u Breakpoints:\n", (uint32_t)m_breakpoints.size());
165 s->IndentMore();
166 bp_collection::const_iterator pos;
167 bp_collection::const_iterator end = m_breakpoints.end();
168 for (pos = m_breakpoints.begin(); pos != end; ++pos)
169 (*pos)->Dump(s);
170 s->IndentLess();
171 }
172
173
174 BreakpointSP
GetBreakpointAtIndex(size_t i)175 BreakpointList::GetBreakpointAtIndex (size_t i)
176 {
177 Mutex::Locker locker(m_mutex);
178 BreakpointSP stop_sp;
179 bp_collection::iterator end = m_breakpoints.end();
180 bp_collection::iterator pos;
181 size_t curr_i = 0;
182 for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
183 {
184 if (curr_i == i)
185 stop_sp = *pos;
186 }
187 return stop_sp;
188 }
189
190 const BreakpointSP
GetBreakpointAtIndex(size_t i) const191 BreakpointList::GetBreakpointAtIndex (size_t i) const
192 {
193 Mutex::Locker locker(m_mutex);
194 BreakpointSP stop_sp;
195 bp_collection::const_iterator end = m_breakpoints.end();
196 bp_collection::const_iterator pos;
197 size_t curr_i = 0;
198 for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
199 {
200 if (curr_i == i)
201 stop_sp = *pos;
202 }
203 return stop_sp;
204 }
205
206 void
UpdateBreakpoints(ModuleList & module_list,bool added)207 BreakpointList::UpdateBreakpoints (ModuleList& module_list, bool added)
208 {
209 Mutex::Locker locker(m_mutex);
210 bp_collection::iterator end = m_breakpoints.end();
211 bp_collection::iterator pos;
212 for (pos = m_breakpoints.begin(); pos != end; ++pos)
213 (*pos)->ModulesChanged (module_list, added);
214
215 }
216
217 void
UpdateBreakpointsWhenModuleIsReplaced(ModuleSP old_module_sp,ModuleSP new_module_sp)218 BreakpointList::UpdateBreakpointsWhenModuleIsReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
219 {
220 Mutex::Locker locker(m_mutex);
221 bp_collection::iterator end = m_breakpoints.end();
222 bp_collection::iterator pos;
223 for (pos = m_breakpoints.begin(); pos != end; ++pos)
224 (*pos)->ModuleReplaced (old_module_sp, new_module_sp);
225
226 }
227
228 void
ClearAllBreakpointSites()229 BreakpointList::ClearAllBreakpointSites ()
230 {
231 Mutex::Locker locker(m_mutex);
232 bp_collection::iterator end = m_breakpoints.end();
233 bp_collection::iterator pos;
234 for (pos = m_breakpoints.begin(); pos != end; ++pos)
235 (*pos)->ClearAllBreakpointSites ();
236
237 }
238
239 void
GetListMutex(Mutex::Locker & locker)240 BreakpointList::GetListMutex (Mutex::Locker &locker)
241 {
242 return locker.Lock (m_mutex);
243 }
244