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