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