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::RemoveInvalidLocations (const ArchSpec &arch) 73 { 74 Mutex::Locker locker(m_mutex); 75 for (const auto &bp_sp : m_breakpoints) 76 bp_sp->RemoveInvalidLocations(arch); 77 } 78 79 80 void 81 BreakpointList::SetEnabledAll (bool enabled) 82 { 83 Mutex::Locker locker(m_mutex); 84 for (const auto &bp_sp : m_breakpoints) 85 bp_sp->SetEnabled (enabled); 86 } 87 88 89 void 90 BreakpointList::RemoveAll (bool notify) 91 { 92 Mutex::Locker locker(m_mutex); 93 ClearAllBreakpointSites (); 94 95 if (notify) 96 { 97 bp_collection::iterator pos, end = m_breakpoints.end(); 98 for (pos = m_breakpoints.begin(); pos != end; ++pos) 99 { 100 if ((*pos)->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 101 { 102 (*pos)->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, 103 new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved, 104 *pos)); 105 } 106 } 107 } 108 m_breakpoints.erase (m_breakpoints.begin(), m_breakpoints.end()); 109 } 110 111 class BreakpointIDMatches 112 { 113 public: 114 BreakpointIDMatches (break_id_t break_id) : 115 m_break_id(break_id) 116 { 117 } 118 119 bool operator() (const BreakpointSP &bp) const 120 { 121 return m_break_id == bp->GetID(); 122 } 123 124 private: 125 const break_id_t m_break_id; 126 }; 127 128 BreakpointList::bp_collection::iterator 129 BreakpointList::GetBreakpointIDIterator (break_id_t break_id) 130 { 131 return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range 132 BreakpointIDMatches(break_id)); // Predicate 133 } 134 135 BreakpointList::bp_collection::const_iterator 136 BreakpointList::GetBreakpointIDConstIterator (break_id_t break_id) const 137 { 138 return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range 139 BreakpointIDMatches(break_id)); // Predicate 140 } 141 142 BreakpointSP 143 BreakpointList::FindBreakpointByID (break_id_t break_id) 144 { 145 Mutex::Locker locker(m_mutex); 146 BreakpointSP stop_sp; 147 bp_collection::iterator pos = GetBreakpointIDIterator(break_id); 148 if (pos != m_breakpoints.end()) 149 stop_sp = *pos; 150 151 return stop_sp; 152 } 153 154 const BreakpointSP 155 BreakpointList::FindBreakpointByID (break_id_t break_id) const 156 { 157 Mutex::Locker locker(m_mutex); 158 BreakpointSP stop_sp; 159 bp_collection::const_iterator pos = GetBreakpointIDConstIterator(break_id); 160 if (pos != m_breakpoints.end()) 161 stop_sp = *pos; 162 163 return stop_sp; 164 } 165 166 void 167 BreakpointList::Dump (Stream *s) const 168 { 169 Mutex::Locker locker(m_mutex); 170 s->Printf("%p: ", static_cast<const void*>(this)); 171 s->Indent(); 172 s->Printf("BreakpointList with %u Breakpoints:\n", (uint32_t)m_breakpoints.size()); 173 s->IndentMore(); 174 for (const auto &bp_sp : m_breakpoints) 175 bp_sp->Dump(s); 176 s->IndentLess(); 177 } 178 179 180 BreakpointSP 181 BreakpointList::GetBreakpointAtIndex (size_t i) 182 { 183 Mutex::Locker locker(m_mutex); 184 BreakpointSP stop_sp; 185 bp_collection::iterator end = m_breakpoints.end(); 186 bp_collection::iterator pos; 187 size_t curr_i = 0; 188 for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) 189 { 190 if (curr_i == i) 191 stop_sp = *pos; 192 } 193 return stop_sp; 194 } 195 196 const BreakpointSP 197 BreakpointList::GetBreakpointAtIndex (size_t i) const 198 { 199 Mutex::Locker locker(m_mutex); 200 BreakpointSP stop_sp; 201 bp_collection::const_iterator end = m_breakpoints.end(); 202 bp_collection::const_iterator pos; 203 size_t curr_i = 0; 204 for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) 205 { 206 if (curr_i == i) 207 stop_sp = *pos; 208 } 209 return stop_sp; 210 } 211 212 void 213 BreakpointList::UpdateBreakpoints (ModuleList& module_list, bool added, bool delete_locations) 214 { 215 Mutex::Locker locker(m_mutex); 216 for (const auto &bp_sp : m_breakpoints) 217 bp_sp->ModulesChanged (module_list, added, delete_locations); 218 219 } 220 221 void 222 BreakpointList::UpdateBreakpointsWhenModuleIsReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp) 223 { 224 Mutex::Locker locker(m_mutex); 225 for (const auto &bp_sp : m_breakpoints) 226 bp_sp->ModuleReplaced (old_module_sp, new_module_sp); 227 228 } 229 230 void 231 BreakpointList::ClearAllBreakpointSites () 232 { 233 Mutex::Locker locker(m_mutex); 234 for (const auto &bp_sp : m_breakpoints) 235 bp_sp->ClearAllBreakpointSites (); 236 237 } 238 239 void 240 BreakpointList::GetListMutex (Mutex::Locker &locker) 241 { 242 return locker.Lock (m_mutex); 243 } 244