WatchpointList.cpp revision 516f0849819d094d4eab39a1f27b770259103ff8
1//===-- WatchpointList.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/WatchpointList.h" 16#include "lldb/Breakpoint/Watchpoint.h" 17 18using namespace lldb; 19using namespace lldb_private; 20 21WatchpointList::WatchpointList() : 22 m_watchpoints (), 23 m_mutex (Mutex::eMutexTypeRecursive), 24 m_next_wp_id (0) 25{ 26} 27 28WatchpointList::~WatchpointList() 29{ 30} 31 32// Add a watchpoint to the list. 33lldb::watch_id_t 34WatchpointList::Add (const WatchpointSP &wp_sp) 35{ 36 Mutex::Locker locker (m_mutex); 37 wp_sp->SetID(++m_next_wp_id); 38 m_watchpoints.push_back(wp_sp); 39 return wp_sp->GetID(); 40} 41 42void 43WatchpointList::Dump (Stream *s) const 44{ 45 DumpWithLevel(s, lldb::eDescriptionLevelBrief); 46} 47 48void 49WatchpointList::DumpWithLevel (Stream *s, lldb::DescriptionLevel description_level) const 50{ 51 Mutex::Locker locker (m_mutex); 52 s->Printf("%p: ", this); 53 //s->Indent(); 54 s->Printf("WatchpointList with %zu Watchpoints:\n", 55 m_watchpoints.size()); 56 s->IndentMore(); 57 wp_collection::const_iterator pos, end = m_watchpoints.end(); 58 for (pos = m_watchpoints.begin(); pos != end; ++pos) 59 (*pos)->DumpWithLevel(s, description_level); 60 s->IndentLess(); 61} 62 63const WatchpointSP 64WatchpointList::FindByAddress (lldb::addr_t addr) const 65{ 66 WatchpointSP wp_sp; 67 Mutex::Locker locker (m_mutex); 68 if (!m_watchpoints.empty()) 69 { 70 wp_collection::const_iterator pos, end = m_watchpoints.end(); 71 for (pos = m_watchpoints.begin(); pos != end; ++pos) 72 if ((*pos)->GetLoadAddress() == addr) { 73 wp_sp = *pos; 74 break; 75 } 76 } 77 78 return wp_sp; 79} 80 81const WatchpointSP 82WatchpointList::FindBySpec (std::string spec) const 83{ 84 WatchpointSP wp_sp; 85 Mutex::Locker locker (m_mutex); 86 if (!m_watchpoints.empty()) 87 { 88 wp_collection::const_iterator pos, end = m_watchpoints.end(); 89 for (pos = m_watchpoints.begin(); pos != end; ++pos) 90 if ((*pos)->GetWatchSpec() == spec) { 91 wp_sp = *pos; 92 break; 93 } 94 } 95 96 return wp_sp; 97} 98 99class WatchpointIDMatches 100{ 101public: 102 WatchpointIDMatches (lldb::watch_id_t watch_id) : 103 m_watch_id(watch_id) 104 { 105 } 106 107 bool operator() (const WatchpointSP &wp) const 108 { 109 return m_watch_id == wp->GetID(); 110 } 111 112private: 113 const lldb::watch_id_t m_watch_id; 114}; 115 116WatchpointList::wp_collection::iterator 117WatchpointList::GetIDIterator (lldb::watch_id_t watch_id) 118{ 119 return std::find_if(m_watchpoints.begin(), m_watchpoints.end(), // Search full range 120 WatchpointIDMatches(watch_id)); // Predicate 121} 122 123WatchpointList::wp_collection::const_iterator 124WatchpointList::GetIDConstIterator (lldb::watch_id_t watch_id) const 125{ 126 return std::find_if(m_watchpoints.begin(), m_watchpoints.end(), // Search full range 127 WatchpointIDMatches(watch_id)); // Predicate 128} 129 130WatchpointSP 131WatchpointList::FindByID (lldb::watch_id_t watch_id) const 132{ 133 WatchpointSP wp_sp; 134 Mutex::Locker locker (m_mutex); 135 wp_collection::const_iterator pos = GetIDConstIterator(watch_id); 136 if (pos != m_watchpoints.end()) 137 wp_sp = *pos; 138 139 return wp_sp; 140} 141 142lldb::watch_id_t 143WatchpointList::FindIDByAddress (lldb::addr_t addr) 144{ 145 WatchpointSP wp_sp = FindByAddress (addr); 146 if (wp_sp) 147 { 148 return wp_sp->GetID(); 149 } 150 return LLDB_INVALID_WATCH_ID; 151} 152 153lldb::watch_id_t 154WatchpointList::FindIDBySpec (std::string spec) 155{ 156 WatchpointSP wp_sp = FindBySpec (spec); 157 if (wp_sp) 158 { 159 return wp_sp->GetID(); 160 } 161 return LLDB_INVALID_WATCH_ID; 162} 163 164WatchpointSP 165WatchpointList::GetByIndex (uint32_t i) 166{ 167 Mutex::Locker locker (m_mutex); 168 WatchpointSP wp_sp; 169 if (i < m_watchpoints.size()) 170 { 171 wp_collection::const_iterator pos = m_watchpoints.begin(); 172 std::advance(pos, i); 173 wp_sp = *pos; 174 } 175 return wp_sp; 176} 177 178const WatchpointSP 179WatchpointList::GetByIndex (uint32_t i) const 180{ 181 Mutex::Locker locker (m_mutex); 182 WatchpointSP wp_sp; 183 if (i < m_watchpoints.size()) 184 { 185 wp_collection::const_iterator pos = m_watchpoints.begin(); 186 std::advance(pos, i); 187 wp_sp = *pos; 188 } 189 return wp_sp; 190} 191 192std::vector<lldb::watch_id_t> 193WatchpointList::GetWatchpointIDs() const 194{ 195 std::vector<lldb::watch_id_t> IDs; 196 wp_collection::const_iterator pos, end = m_watchpoints.end(); 197 for (pos = m_watchpoints.begin(); pos != end; ++pos) 198 IDs.push_back((*pos)->GetID()); 199 return IDs; 200} 201 202bool 203WatchpointList::Remove (lldb::watch_id_t watch_id) 204{ 205 Mutex::Locker locker (m_mutex); 206 wp_collection::iterator pos = GetIDIterator(watch_id); 207 if (pos != m_watchpoints.end()) 208 { 209 m_watchpoints.erase(pos); 210 return true; 211 } 212 return false; 213} 214 215uint32_t 216WatchpointList::GetHitCount () const 217{ 218 uint32_t hit_count = 0; 219 Mutex::Locker locker (m_mutex); 220 wp_collection::const_iterator pos, end = m_watchpoints.end(); 221 for (pos = m_watchpoints.begin(); pos != end; ++pos) 222 hit_count += (*pos)->GetHitCount(); 223 return hit_count; 224} 225 226bool 227WatchpointList::ShouldStop (StoppointCallbackContext *context, lldb::watch_id_t watch_id) 228{ 229 230 WatchpointSP wp_sp = FindByID (watch_id); 231 if (wp_sp) 232 { 233 // Let the Watchpoint decide if it should stop here (could not have 234 // reached it's target hit count yet, or it could have a callback 235 // that decided it shouldn't stop. 236 return wp_sp->ShouldStop (context); 237 } 238 // We should stop here since this Watchpoint isn't valid anymore or it 239 // doesn't exist. 240 return true; 241} 242 243void 244WatchpointList::GetDescription (Stream *s, lldb::DescriptionLevel level) 245{ 246 Mutex::Locker locker (m_mutex); 247 wp_collection::iterator pos, end = m_watchpoints.end(); 248 249 for (pos = m_watchpoints.begin(); pos != end; ++pos) 250 { 251 s->Printf(" "); 252 (*pos)->Dump(s); 253 } 254} 255 256void 257WatchpointList::SetEnabledAll (bool enabled) 258{ 259 Mutex::Locker locker(m_mutex); 260 261 wp_collection::iterator pos, end = m_watchpoints.end(); 262 for (pos = m_watchpoints.begin(); pos != end; ++pos) 263 (*pos)->SetEnabled (enabled); 264} 265 266void 267WatchpointList::RemoveAll () 268{ 269 Mutex::Locker locker(m_mutex); 270 m_watchpoints.clear(); 271} 272 273void 274WatchpointList::GetListMutex (Mutex::Locker &locker) 275{ 276 return locker.Lock (m_mutex.GetMutex()); 277} 278