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 BreakpointLocationSP break_loc = (*pos); 99 const Section *section = break_loc->GetAddress().GetSection(); 100 if (section && section->GetModule() == module) 101 { 102 bp_loc_list.Add (break_loc); 103 } 104 } 105 return bp_loc_list.GetSize() - orig_size; 106 } 107 108 const BreakpointLocationSP 109 BreakpointLocationList::FindByAddress (const Address &addr) const 110 { 111 Mutex::Locker locker (m_mutex); 112 BreakpointLocationSP bp_loc_sp; 113 if (!m_locations.empty()) 114 { 115 addr_map::const_iterator pos = m_address_to_location.find (addr); 116 if (pos != m_address_to_location.end()) 117 bp_loc_sp = pos->second; 118 } 119 120 return bp_loc_sp; 121 } 122 123 void 124 BreakpointLocationList::Dump (Stream *s) const 125 { 126 s->Printf("%p: ", this); 127 //s->Indent(); 128 Mutex::Locker locker (m_mutex); 129 s->Printf("BreakpointLocationList with %zu BreakpointLocations:\n", m_locations.size()); 130 s->IndentMore(); 131 collection::const_iterator pos, end = m_locations.end(); 132 for (pos = m_locations.begin(); pos != end; ++pos) 133 (*pos).get()->Dump(s); 134 s->IndentLess(); 135 } 136 137 138 BreakpointLocationSP 139 BreakpointLocationList::GetByIndex (uint32_t i) 140 { 141 Mutex::Locker locker (m_mutex); 142 BreakpointLocationSP bp_loc_sp; 143 if (i < m_locations.size()) 144 bp_loc_sp = m_locations[i]; 145 146 return bp_loc_sp; 147 } 148 149 const BreakpointLocationSP 150 BreakpointLocationList::GetByIndex (uint32_t i) const 151 { 152 Mutex::Locker locker (m_mutex); 153 BreakpointLocationSP bp_loc_sp; 154 if (i < m_locations.size()) 155 bp_loc_sp = m_locations[i]; 156 157 return bp_loc_sp; 158 } 159 160 void 161 BreakpointLocationList::ClearAllBreakpointSites () 162 { 163 Mutex::Locker locker (m_mutex); 164 collection::iterator pos, end = m_locations.end(); 165 for (pos = m_locations.begin(); pos != end; ++pos) 166 (*pos)->ClearBreakpointSite(); 167 } 168 169 void 170 BreakpointLocationList::ResolveAllBreakpointSites () 171 { 172 Mutex::Locker locker (m_mutex); 173 collection::iterator pos, end = m_locations.end(); 174 175 for (pos = m_locations.begin(); pos != end; ++pos) 176 { 177 if ((*pos)->IsEnabled()) 178 (*pos)->ResolveBreakpointSite(); 179 } 180 } 181 182 uint32_t 183 BreakpointLocationList::GetHitCount () const 184 { 185 uint32_t hit_count = 0; 186 Mutex::Locker locker (m_mutex); 187 collection::const_iterator pos, end = m_locations.end(); 188 for (pos = m_locations.begin(); pos != end; ++pos) 189 hit_count += (*pos)->GetHitCount(); 190 return hit_count; 191 } 192 193 size_t 194 BreakpointLocationList::GetNumResolvedLocations() const 195 { 196 Mutex::Locker locker (m_mutex); 197 size_t resolve_count = 0; 198 collection::const_iterator pos, end = m_locations.end(); 199 for (pos = m_locations.begin(); pos != end; ++pos) 200 { 201 if ((*pos)->IsResolved()) 202 ++resolve_count; 203 } 204 return resolve_count; 205 } 206 207 void 208 BreakpointLocationList::GetDescription (Stream *s, lldb::DescriptionLevel level) 209 { 210 Mutex::Locker locker (m_mutex); 211 collection::iterator pos, end = m_locations.end(); 212 213 for (pos = m_locations.begin(); pos != end; ++pos) 214 { 215 s->Printf(" "); 216 (*pos)->GetDescription(s, level); 217 } 218 } 219 220