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 18using namespace lldb; 19using namespace lldb_private; 20 21BreakpointList::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 29BreakpointList::~BreakpointList() 30{ 31} 32 33 34break_id_t 35BreakpointList::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 51bool 52BreakpointList::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 71void 72BreakpointList::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 81void 82BreakpointList::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 103class BreakpointIDMatches 104{ 105public: 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 116private: 117 const break_id_t m_break_id; 118}; 119 120BreakpointList::bp_collection::iterator 121BreakpointList::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 127BreakpointList::bp_collection::const_iterator 128BreakpointList::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 134BreakpointSP 135BreakpointList::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 146const BreakpointSP 147BreakpointList::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 158void 159BreakpointList::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 174BreakpointSP 175BreakpointList::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 190const BreakpointSP 191BreakpointList::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 206void 207BreakpointList::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 217void 218BreakpointList::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 228void 229BreakpointList::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 239void 240BreakpointList::GetListMutex (Mutex::Locker &locker) 241{ 242 return locker.Lock (m_mutex); 243} 244