BreakpointList.cpp revision 341825
1254721Semaste//===-- BreakpointList.cpp --------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Breakpoint/BreakpointList.h" 11254721Semaste 12254721Semaste// C Includes 13254721Semaste// C++ Includes 14254721Semaste// Other libraries and framework includes 15254721Semaste// Project includes 16254721Semaste#include "lldb/Target/Target.h" 17254721Semaste 18254721Semasteusing namespace lldb; 19254721Semasteusing namespace lldb_private; 20254721Semaste 21309124SdimBreakpointList::BreakpointList(bool is_internal) 22314564Sdim : m_mutex(), m_breakpoints(), m_next_break_id(0), 23314564Sdim m_is_internal(is_internal) {} 24254721Semaste 25314564SdimBreakpointList::~BreakpointList() {} 26254721Semaste 27314564Sdimbreak_id_t BreakpointList::Add(BreakpointSP &bp_sp, bool notify) { 28314564Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 29314564Sdim // Internal breakpoint IDs are negative, normal ones are positive 30314564Sdim bp_sp->SetID(m_is_internal ? --m_next_break_id : ++m_next_break_id); 31254721Semaste 32314564Sdim m_breakpoints.push_back(bp_sp); 33314564Sdim if (notify) { 34314564Sdim if (bp_sp->GetTarget().EventTypeHasListeners( 35314564Sdim Target::eBroadcastBitBreakpointChanged)) 36314564Sdim bp_sp->GetTarget().BroadcastEvent(Target::eBroadcastBitBreakpointChanged, 37314564Sdim new Breakpoint::BreakpointEventData( 38314564Sdim eBreakpointEventTypeAdded, bp_sp)); 39314564Sdim } 40314564Sdim return bp_sp->GetID(); 41254721Semaste} 42254721Semaste 43314564Sdimbool BreakpointList::Remove(break_id_t break_id, bool notify) { 44314564Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 45314564Sdim bp_collection::iterator pos = GetBreakpointIDIterator(break_id); // Predicate 46314564Sdim if (pos != m_breakpoints.end()) { 47314564Sdim BreakpointSP bp_sp(*pos); 48314564Sdim m_breakpoints.erase(pos); 49314564Sdim if (notify) { 50314564Sdim if (bp_sp->GetTarget().EventTypeHasListeners( 51314564Sdim Target::eBroadcastBitBreakpointChanged)) 52314564Sdim bp_sp->GetTarget().BroadcastEvent( 53314564Sdim Target::eBroadcastBitBreakpointChanged, 54314564Sdim new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved, 55314564Sdim bp_sp)); 56254721Semaste } 57314564Sdim return true; 58314564Sdim } 59314564Sdim return false; 60254721Semaste} 61254721Semaste 62314564Sdimvoid BreakpointList::RemoveInvalidLocations(const ArchSpec &arch) { 63314564Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 64314564Sdim for (const auto &bp_sp : m_breakpoints) 65314564Sdim bp_sp->RemoveInvalidLocations(arch); 66258884Semaste} 67258884Semaste 68314564Sdimvoid BreakpointList::SetEnabledAll(bool enabled) { 69314564Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 70314564Sdim for (const auto &bp_sp : m_breakpoints) 71314564Sdim bp_sp->SetEnabled(enabled); 72254721Semaste} 73254721Semaste 74327952Sdimvoid BreakpointList::SetEnabledAllowed(bool enabled) { 75327952Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 76327952Sdim for (const auto &bp_sp : m_breakpoints) 77327952Sdim if (bp_sp->AllowDisable()) 78327952Sdim bp_sp->SetEnabled(enabled); 79327952Sdim} 80327952Sdim 81314564Sdimvoid BreakpointList::RemoveAll(bool notify) { 82314564Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 83314564Sdim ClearAllBreakpointSites(); 84254721Semaste 85314564Sdim if (notify) { 86314564Sdim bp_collection::iterator pos, end = m_breakpoints.end(); 87314564Sdim for (pos = m_breakpoints.begin(); pos != end; ++pos) { 88314564Sdim if ((*pos)->GetTarget().EventTypeHasListeners( 89314564Sdim Target::eBroadcastBitBreakpointChanged)) { 90314564Sdim (*pos)->GetTarget().BroadcastEvent( 91314564Sdim Target::eBroadcastBitBreakpointChanged, 92314564Sdim new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved, 93314564Sdim *pos)); 94314564Sdim } 95254721Semaste } 96314564Sdim } 97314564Sdim m_breakpoints.erase(m_breakpoints.begin(), m_breakpoints.end()); 98254721Semaste} 99254721Semaste 100327952Sdimvoid BreakpointList::RemoveAllowed(bool notify) { 101327952Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 102341825Sdim 103327952Sdim bp_collection::iterator pos, end = m_breakpoints.end(); 104327952Sdim if (notify) { 105327952Sdim for (pos = m_breakpoints.begin(); pos != end; ++pos) { 106327952Sdim if(!(*pos)->AllowDelete()) 107327952Sdim continue; 108327952Sdim if ((*pos)->GetTarget().EventTypeHasListeners( 109327952Sdim Target::eBroadcastBitBreakpointChanged)) { 110327952Sdim (*pos)->GetTarget().BroadcastEvent( 111327952Sdim Target::eBroadcastBitBreakpointChanged, 112327952Sdim new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved, 113327952Sdim *pos)); 114327952Sdim } 115327952Sdim } 116327952Sdim } 117327952Sdim pos = m_breakpoints.begin(); 118327952Sdim while ( pos != end) { 119341825Sdim auto bp = *pos; 120341825Sdim if (bp->AllowDelete()) { 121341825Sdim bp->ClearAllBreakpointSites(); 122341825Sdim pos = m_breakpoints.erase(pos); 123341825Sdim } else 124341825Sdim pos++; 125327952Sdim } 126327952Sdim} 127327952Sdim 128314564Sdimclass BreakpointIDMatches { 129254721Semastepublic: 130314564Sdim BreakpointIDMatches(break_id_t break_id) : m_break_id(break_id) {} 131254721Semaste 132314564Sdim bool operator()(const BreakpointSP &bp) const { 133314564Sdim return m_break_id == bp->GetID(); 134314564Sdim } 135254721Semaste 136254721Semasteprivate: 137314564Sdim const break_id_t m_break_id; 138254721Semaste}; 139254721Semaste 140254721SemasteBreakpointList::bp_collection::iterator 141314564SdimBreakpointList::GetBreakpointIDIterator(break_id_t break_id) { 142314564Sdim return std::find_if(m_breakpoints.begin(), 143314564Sdim m_breakpoints.end(), // Search full range 144314564Sdim BreakpointIDMatches(break_id)); // Predicate 145254721Semaste} 146254721Semaste 147254721SemasteBreakpointList::bp_collection::const_iterator 148314564SdimBreakpointList::GetBreakpointIDConstIterator(break_id_t break_id) const { 149314564Sdim return std::find_if(m_breakpoints.begin(), 150314564Sdim m_breakpoints.end(), // Search full range 151314564Sdim BreakpointIDMatches(break_id)); // Predicate 152254721Semaste} 153254721Semaste 154314564SdimBreakpointSP BreakpointList::FindBreakpointByID(break_id_t break_id) { 155314564Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 156314564Sdim BreakpointSP stop_sp; 157314564Sdim bp_collection::iterator pos = GetBreakpointIDIterator(break_id); 158314564Sdim if (pos != m_breakpoints.end()) 159314564Sdim stop_sp = *pos; 160254721Semaste 161314564Sdim return stop_sp; 162254721Semaste} 163254721Semaste 164254721Semasteconst BreakpointSP 165314564SdimBreakpointList::FindBreakpointByID(break_id_t break_id) const { 166314564Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 167314564Sdim BreakpointSP stop_sp; 168314564Sdim bp_collection::const_iterator pos = GetBreakpointIDConstIterator(break_id); 169314564Sdim if (pos != m_breakpoints.end()) 170314564Sdim stop_sp = *pos; 171254721Semaste 172314564Sdim return stop_sp; 173254721Semaste} 174254721Semaste 175314564Sdimbool BreakpointList::FindBreakpointsByName(const char *name, 176314564Sdim BreakpointList &matching_bps) { 177321369Sdim Status error; 178314564Sdim if (!name) 179314564Sdim return false; 180254721Semaste 181314564Sdim if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(name), error)) 182314564Sdim return false; 183254721Semaste 184314564Sdim for (BreakpointSP bkpt_sp : Breakpoints()) { 185314564Sdim if (bkpt_sp->MatchesName(name)) { 186314564Sdim matching_bps.Add(bkpt_sp, false); 187254721Semaste } 188314564Sdim } 189314564Sdim return true; 190254721Semaste} 191254721Semaste 192314564Sdimvoid BreakpointList::Dump(Stream *s) const { 193314564Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 194314564Sdim s->Printf("%p: ", static_cast<const void *>(this)); 195314564Sdim s->Indent(); 196314564Sdim s->Printf("BreakpointList with %u Breakpoints:\n", 197314564Sdim (uint32_t)m_breakpoints.size()); 198314564Sdim s->IndentMore(); 199314564Sdim for (const auto &bp_sp : m_breakpoints) 200314564Sdim bp_sp->Dump(s); 201314564Sdim s->IndentLess(); 202254721Semaste} 203254721Semaste 204314564SdimBreakpointSP BreakpointList::GetBreakpointAtIndex(size_t i) { 205314564Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 206314564Sdim BreakpointSP stop_sp; 207314564Sdim bp_collection::iterator end = m_breakpoints.end(); 208314564Sdim bp_collection::iterator pos; 209314564Sdim size_t curr_i = 0; 210314564Sdim for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) { 211314564Sdim if (curr_i == i) 212314564Sdim stop_sp = *pos; 213314564Sdim } 214314564Sdim return stop_sp; 215314564Sdim} 216254721Semaste 217314564Sdimconst BreakpointSP BreakpointList::GetBreakpointAtIndex(size_t i) const { 218314564Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 219314564Sdim BreakpointSP stop_sp; 220314564Sdim bp_collection::const_iterator end = m_breakpoints.end(); 221314564Sdim bp_collection::const_iterator pos; 222314564Sdim size_t curr_i = 0; 223314564Sdim for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) { 224314564Sdim if (curr_i == i) 225314564Sdim stop_sp = *pos; 226314564Sdim } 227314564Sdim return stop_sp; 228254721Semaste} 229254721Semaste 230314564Sdimvoid BreakpointList::UpdateBreakpoints(ModuleList &module_list, bool added, 231314564Sdim bool delete_locations) { 232314564Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 233314564Sdim for (const auto &bp_sp : m_breakpoints) 234314564Sdim bp_sp->ModulesChanged(module_list, added, delete_locations); 235314564Sdim} 236254721Semaste 237314564Sdimvoid BreakpointList::UpdateBreakpointsWhenModuleIsReplaced( 238314564Sdim ModuleSP old_module_sp, ModuleSP new_module_sp) { 239314564Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 240314564Sdim for (const auto &bp_sp : m_breakpoints) 241314564Sdim bp_sp->ModuleReplaced(old_module_sp, new_module_sp); 242254721Semaste} 243254721Semaste 244314564Sdimvoid BreakpointList::ClearAllBreakpointSites() { 245314564Sdim std::lock_guard<std::recursive_mutex> guard(m_mutex); 246314564Sdim for (const auto &bp_sp : m_breakpoints) 247314564Sdim bp_sp->ClearAllBreakpointSites(); 248254721Semaste} 249254721Semaste 250314564Sdimvoid BreakpointList::GetListMutex( 251314564Sdim std::unique_lock<std::recursive_mutex> &lock) { 252314564Sdim lock = std::unique_lock<std::recursive_mutex>(m_mutex); 253254721Semaste} 254