1 //===-- BreakpointLocationCollection.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 11 // C Includes 12 // C++ Includes 13 // Other libraries and framework includes 14 // Project includes 15 #include "lldb/Breakpoint/BreakpointLocationCollection.h" 16 #include "lldb/Core/ModuleList.h" 17 #include "lldb/Breakpoint/Breakpoint.h" 18 #include "lldb/Breakpoint/BreakpointLocation.h" 19 #include "lldb/Target/Thread.h" 20 #include "lldb/Target/ThreadSpec.h" 21 22 using namespace lldb; 23 using namespace lldb_private; 24 25 //---------------------------------------------------------------------- 26 // BreakpointLocationCollection constructor 27 //---------------------------------------------------------------------- 28 BreakpointLocationCollection::BreakpointLocationCollection() : 29 m_break_loc_collection(), 30 m_collection_mutex() 31 { 32 } 33 34 //---------------------------------------------------------------------- 35 // Destructor 36 //---------------------------------------------------------------------- 37 BreakpointLocationCollection::~BreakpointLocationCollection() 38 { 39 } 40 41 void 42 BreakpointLocationCollection::Add(const BreakpointLocationSP &bp_loc) 43 { 44 std::lock_guard<std::mutex> guard(m_collection_mutex); 45 BreakpointLocationSP old_bp_loc = FindByIDPair (bp_loc->GetBreakpoint().GetID(), bp_loc->GetID()); 46 if (!old_bp_loc.get()) 47 m_break_loc_collection.push_back(bp_loc); 48 } 49 50 bool 51 BreakpointLocationCollection::Remove (lldb::break_id_t bp_id, lldb::break_id_t bp_loc_id) 52 { 53 std::lock_guard<std::mutex> guard(m_collection_mutex); 54 collection::iterator pos = GetIDPairIterator(bp_id, bp_loc_id); // Predicate 55 if (pos != m_break_loc_collection.end()) 56 { 57 m_break_loc_collection.erase(pos); 58 return true; 59 } 60 return false; 61 62 } 63 64 class BreakpointIDPairMatches 65 { 66 public: 67 BreakpointIDPairMatches (lldb::break_id_t break_id, lldb::break_id_t break_loc_id) : 68 m_break_id(break_id), 69 m_break_loc_id (break_loc_id) 70 { 71 } 72 73 bool operator() (const BreakpointLocationSP &bp_loc) const 74 { 75 return m_break_id == bp_loc->GetBreakpoint().GetID() 76 && m_break_loc_id == bp_loc->GetID(); 77 } 78 79 private: 80 const lldb::break_id_t m_break_id; 81 const lldb::break_id_t m_break_loc_id; 82 }; 83 84 BreakpointLocationCollection::collection::iterator 85 BreakpointLocationCollection::GetIDPairIterator (lldb::break_id_t break_id, lldb::break_id_t break_loc_id) 86 { 87 return std::find_if(m_break_loc_collection.begin(), m_break_loc_collection.end(), // Search full range 88 BreakpointIDPairMatches(break_id, break_loc_id)); // Predicate 89 } 90 91 BreakpointLocationCollection::collection::const_iterator 92 BreakpointLocationCollection::GetIDPairConstIterator (lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const 93 { 94 return std::find_if(m_break_loc_collection.begin(), m_break_loc_collection.end(), // Search full range 95 BreakpointIDPairMatches(break_id, break_loc_id)); // Predicate 96 } 97 98 BreakpointLocationSP 99 BreakpointLocationCollection::FindByIDPair (lldb::break_id_t break_id, lldb::break_id_t break_loc_id) 100 { 101 BreakpointLocationSP stop_sp; 102 collection::iterator pos = GetIDPairIterator(break_id, break_loc_id); 103 if (pos != m_break_loc_collection.end()) 104 stop_sp = *pos; 105 106 return stop_sp; 107 } 108 109 const BreakpointLocationSP 110 BreakpointLocationCollection::FindByIDPair (lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const 111 { 112 BreakpointLocationSP stop_sp; 113 collection::const_iterator pos = GetIDPairConstIterator(break_id, break_loc_id); 114 if (pos != m_break_loc_collection.end()) 115 stop_sp = *pos; 116 117 return stop_sp; 118 } 119 120 BreakpointLocationSP 121 BreakpointLocationCollection::GetByIndex (size_t i) 122 { 123 std::lock_guard<std::mutex> guard(m_collection_mutex); 124 BreakpointLocationSP stop_sp; 125 if (i < m_break_loc_collection.size()) 126 stop_sp = m_break_loc_collection[i]; 127 128 return stop_sp; 129 } 130 131 const BreakpointLocationSP 132 BreakpointLocationCollection::GetByIndex (size_t i) const 133 { 134 std::lock_guard<std::mutex> guard(m_collection_mutex); 135 BreakpointLocationSP stop_sp; 136 if (i < m_break_loc_collection.size()) 137 stop_sp = m_break_loc_collection[i]; 138 139 return stop_sp; 140 } 141 142 bool 143 BreakpointLocationCollection::ShouldStop (StoppointCallbackContext *context) 144 { 145 bool shouldStop = false; 146 size_t i = 0; 147 size_t prev_size = GetSize(); 148 while (i < prev_size) 149 { 150 // ShouldStop can remove the breakpoint from the list 151 if (GetByIndex(i)->ShouldStop(context)) 152 shouldStop = true; 153 154 if (prev_size == GetSize()) 155 i++; 156 prev_size = GetSize(); 157 } 158 return shouldStop; 159 } 160 161 bool 162 BreakpointLocationCollection::ValidForThisThread (Thread *thread) 163 { 164 std::lock_guard<std::mutex> guard(m_collection_mutex); 165 collection::iterator pos, 166 begin = m_break_loc_collection.begin(), 167 end = m_break_loc_collection.end(); 168 169 for (pos = begin; pos != end; ++pos) 170 { 171 if ((*pos)->ValidForThisThread (thread)) 172 return true; 173 } 174 return false; 175 } 176 177 bool 178 BreakpointLocationCollection::IsInternal () const 179 { 180 std::lock_guard<std::mutex> guard(m_collection_mutex); 181 collection::const_iterator pos, 182 begin = m_break_loc_collection.begin(), 183 end = m_break_loc_collection.end(); 184 185 bool is_internal = true; 186 187 for (pos = begin; pos != end; ++pos) 188 { 189 if (!(*pos)->GetBreakpoint().IsInternal ()) 190 { 191 is_internal = false; 192 break; 193 } 194 } 195 return is_internal; 196 } 197 198 void 199 BreakpointLocationCollection::GetDescription (Stream *s, lldb::DescriptionLevel level) 200 { 201 std::lock_guard<std::mutex> guard(m_collection_mutex); 202 collection::iterator pos, 203 begin = m_break_loc_collection.begin(), 204 end = m_break_loc_collection.end(); 205 206 for (pos = begin; pos != end; ++pos) 207 { 208 if (pos != begin) 209 s->PutChar(' '); 210 (*pos)->GetDescription(s, level); 211 } 212 } 213 214