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 (Mutex::eMutexTypeRecursive), 23 m_breakpoints(), 24 m_next_break_id (0), 25 m_is_internal (is_internal) 26 { 27 } 28 29 BreakpointList::~BreakpointList() 30 { 31 } 32 33 34 break_id_t 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 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 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 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: 106 BreakpointIDMatches (break_id_t break_id) : 107 m_break_id(break_id) 108 { 109 } 110 111 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 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 128 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 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 147 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 159 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 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 191 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 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 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 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 240 BreakpointList::GetListMutex (Mutex::Locker &locker) 241 { 242 return locker.Lock (m_mutex); 243 } 244