1 //===-- BreakpointLocationList.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/BreakpointLocationList.h" 16 #include "lldb/Breakpoint/BreakpointLocation.h" 17 #include "lldb/Core/ModuleList.h" 18 #include "lldb/Target/Target.h" 19 20 using namespace lldb; 21 using namespace lldb_private; 22 23 BreakpointLocationList::BreakpointLocationList() : 24 m_locations(), 25 m_address_to_location (), 26 m_mutex (Mutex::eMutexTypeRecursive) 27 { 28 } 29 30 BreakpointLocationList::~BreakpointLocationList() 31 { 32 } 33 34 BreakpointLocationSP 35 BreakpointLocationList::Create (Breakpoint &bp, const Address &addr) 36 { 37 Mutex::Locker locker (m_mutex); 38 // The location ID is just the size of the location list + 1 39 lldb::break_id_t bp_loc_id = m_locations.size() + 1; 40 BreakpointLocationSP bp_loc_sp (new BreakpointLocation (bp_loc_id, bp, addr)); 41 m_locations.push_back (bp_loc_sp); 42 m_address_to_location[addr] = bp_loc_sp; 43 return bp_loc_sp; 44 } 45 46 bool 47 BreakpointLocationList::ShouldStop (StoppointCallbackContext *context, lldb::break_id_t break_id) 48 { 49 BreakpointLocationSP bp = FindByID (break_id); 50 if (bp) 51 { 52 // Let the BreakpointLocation decide if it should stop here (could not have 53 // reached it's target hit count yet, or it could have a callback 54 // that decided it shouldn't stop (shared library loads/unloads). 55 return bp->ShouldStop (context); 56 } 57 // We should stop here since this BreakpointLocation isn't valid anymore or it 58 // doesn't exist. 59 return true; 60 } 61 62 lldb::break_id_t 63 BreakpointLocationList::FindIDByAddress (const Address &addr) 64 { 65 BreakpointLocationSP bp_loc_sp = FindByAddress (addr); 66 if (bp_loc_sp) 67 { 68 return bp_loc_sp->GetID(); 69 } 70 return LLDB_INVALID_BREAK_ID; 71 } 72 73 BreakpointLocationSP 74 BreakpointLocationList::FindByID (lldb::break_id_t break_id) const 75 { 76 BreakpointLocationSP bp_loc_sp; 77 Mutex::Locker locker (m_mutex); 78 // We never remove a breakpoint locations, so the ID can be translated into 79 // the location index by subtracting 1 80 uint32_t idx = break_id - 1; 81 if (idx <= m_locations.size()) 82 { 83 bp_loc_sp = m_locations[idx]; 84 } 85 return bp_loc_sp; 86 } 87 88 size_t 89 BreakpointLocationList::FindInModule (Module *module, 90 BreakpointLocationCollection& bp_loc_list) 91 { 92 Mutex::Locker locker (m_mutex); 93 const size_t orig_size = bp_loc_list.GetSize(); 94 collection::iterator pos, end = m_locations.end(); 95 96 for (pos = m_locations.begin(); pos != end; ++pos) 97 { 98 bool seen = false; 99 BreakpointLocationSP break_loc = (*pos); 100 const Section *section = break_loc->GetAddress().GetSection(); 101 if (section) 102 { 103 if (section->GetModule() == module) 104 { 105 if (!seen) 106 { 107 seen = true; 108 bp_loc_list.Add (break_loc); 109 } 110 111 } 112 } 113 } 114 return bp_loc_list.GetSize() - orig_size; 115 } 116 117 const BreakpointLocationSP 118 BreakpointLocationList::FindByAddress (const Address &addr) const 119 { 120 Mutex::Locker locker (m_mutex); 121 BreakpointLocationSP bp_loc_sp; 122 if (!m_locations.empty()) 123 { 124 addr_map::const_iterator pos = m_address_to_location.find (addr); 125 if (pos != m_address_to_location.end()) 126 bp_loc_sp = pos->second; 127 } 128 129 return bp_loc_sp; 130 } 131 132 void 133 BreakpointLocationList::Dump (Stream *s) const 134 { 135 s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 136 //s->Indent(); 137 Mutex::Locker locker (m_mutex); 138 s->Printf("BreakpointLocationList with %zu BreakpointLocations:\n", m_locations.size()); 139 s->IndentMore(); 140 collection::const_iterator pos, end = m_locations.end(); 141 for (pos = m_locations.begin(); pos != end; ++pos) 142 (*pos).get()->Dump(s); 143 s->IndentLess(); 144 } 145 146 147 BreakpointLocationSP 148 BreakpointLocationList::GetByIndex (uint32_t i) 149 { 150 Mutex::Locker locker (m_mutex); 151 BreakpointLocationSP bp_loc_sp; 152 if (i < m_locations.size()) 153 bp_loc_sp = m_locations[i]; 154 155 return bp_loc_sp; 156 } 157 158 const BreakpointLocationSP 159 BreakpointLocationList::GetByIndex (uint32_t i) const 160 { 161 Mutex::Locker locker (m_mutex); 162 BreakpointLocationSP bp_loc_sp; 163 if (i < m_locations.size()) 164 bp_loc_sp = m_locations[i]; 165 166 return bp_loc_sp; 167 } 168 169 void 170 BreakpointLocationList::ClearAllBreakpointSites () 171 { 172 Mutex::Locker locker (m_mutex); 173 collection::iterator pos, end = m_locations.end(); 174 for (pos = m_locations.begin(); pos != end; ++pos) 175 (*pos)->ClearBreakpointSite(); 176 } 177 178 void 179 BreakpointLocationList::ResolveAllBreakpointSites () 180 { 181 Mutex::Locker locker (m_mutex); 182 collection::iterator pos, end = m_locations.end(); 183 184 for (pos = m_locations.begin(); pos != end; ++pos) 185 { 186 if ((*pos)->IsEnabled()) 187 (*pos)->ResolveBreakpointSite(); 188 } 189 } 190 191 uint32_t 192 BreakpointLocationList::GetHitCount () const 193 { 194 uint32_t hit_count = 0; 195 Mutex::Locker locker (m_mutex); 196 collection::const_iterator pos, end = m_locations.end(); 197 for (pos = m_locations.begin(); pos != end; ++pos) 198 hit_count += (*pos)->GetHitCount(); 199 return hit_count; 200 } 201 202 size_t 203 BreakpointLocationList::GetNumResolvedLocations() const 204 { 205 Mutex::Locker locker (m_mutex); 206 size_t resolve_count = 0; 207 collection::const_iterator pos, end = m_locations.end(); 208 for (pos = m_locations.begin(); pos != end; ++pos) 209 { 210 if ((*pos)->IsResolved()) 211 ++resolve_count; 212 } 213 return resolve_count; 214 } 215 216 void 217 BreakpointLocationList::GetDescription (Stream *s, lldb::DescriptionLevel level) 218 { 219 Mutex::Locker locker (m_mutex); 220 collection::iterator pos, end = m_locations.end(); 221 222 for (pos = m_locations.begin(); pos != end; ++pos) 223 { 224 s->Printf(" "); 225 (*pos)->GetDescription(s, level); 226 } 227 } 228 229