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