diff options
-rw-r--r-- | lldb/include/lldb/Breakpoint/StoppointLocation.h | 6 | ||||
-rw-r--r-- | lldb/include/lldb/Breakpoint/Watchpoint.h | 8 | ||||
-rw-r--r-- | lldb/include/lldb/Breakpoint/WatchpointList.h | 58 | ||||
-rw-r--r-- | lldb/include/lldb/Target/Target.h | 3 | ||||
-rw-r--r-- | lldb/source/Breakpoint/Watchpoint.cpp | 23 | ||||
-rw-r--r-- | lldb/source/Breakpoint/WatchpointList.cpp | 137 | ||||
-rw-r--r-- | lldb/source/Target/Target.cpp | 23 |
7 files changed, 182 insertions, 76 deletions
diff --git a/lldb/include/lldb/Breakpoint/StoppointLocation.h b/lldb/include/lldb/Breakpoint/StoppointLocation.h index 6e936f3e509..307ddccca20 100644 --- a/lldb/include/lldb/Breakpoint/StoppointLocation.h +++ b/lldb/include/lldb/Breakpoint/StoppointLocation.h @@ -51,10 +51,10 @@ public: return m_addr; } - virtual lldb::addr_t - SetLoadAddress () const + virtual void + SetLoadAddress (lldb::addr_t addr) { - return m_addr; + m_addr = addr; } uint32_t diff --git a/lldb/include/lldb/Breakpoint/Watchpoint.h b/lldb/include/lldb/Breakpoint/Watchpoint.h index 1478bfd70c1..3b69b987205 100644 --- a/lldb/include/lldb/Breakpoint/Watchpoint.h +++ b/lldb/include/lldb/Breakpoint/Watchpoint.h @@ -55,6 +55,7 @@ public: bool SetCallback (WatchpointHitCallback callback, void *callback_baton); void ClearCallback(); void SetDeclInfo (std::string &str); + void SetWatchSpec (std::string &str); void GetDescription (Stream *s, lldb::DescriptionLevel level); void Dump (Stream *s) const; void DumpWithLevel (Stream *s, lldb::DescriptionLevel description_level) const; @@ -96,8 +97,11 @@ public: private: friend class Target; + friend class WatchpointList; void SetTarget(Target *target_ptr) { m_target = target_ptr; } + std::string GetWatchSpec() { return m_watch_spec_str; } + void ResetHitCount() { m_hit_count = 0; } Target *m_target; bool m_enabled; // Is this watchpoint enabled @@ -110,12 +114,12 @@ private: WatchpointHitCallback m_callback; void * m_callback_baton; // Callback user data to pass to callback std::string m_decl_str; // Declaration information, if any. + std::string m_watch_spec_str; // Spec for the watchpoint (for future use). Error m_error; // An error object describing errors creating watchpoint. std::auto_ptr<ClangUserExpression> m_condition_ap; // The condition to test. - static lldb::break_id_t - GetNextID(); + void SetID(lldb::watch_id_t id) { m_loc_id = id; } DISALLOW_COPY_AND_ASSIGN (Watchpoint); }; diff --git a/lldb/include/lldb/Breakpoint/WatchpointList.h b/lldb/include/lldb/Breakpoint/WatchpointList.h index 396d63caddb..92ae7bf41f6 100644 --- a/lldb/include/lldb/Breakpoint/WatchpointList.h +++ b/lldb/include/lldb/Breakpoint/WatchpointList.h @@ -12,8 +12,8 @@ // C Includes // C++ Includes +#include <list> #include <vector> -#include <map> // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" @@ -35,6 +35,7 @@ class WatchpointList // This is not just some random collection of watchpoints. Rather, the act of // adding the watchpoint to this list sets its ID. friend class Watchpoint; +friend class Target; public: //------------------------------------------------------------------ @@ -72,7 +73,8 @@ public: DumpWithLevel (Stream *s, lldb::DescriptionLevel description_level) const; //------------------------------------------------------------------ - /// Returns a shared pointer to the watchpoint at address /// \a addr - + /// Returns a shared pointer to the watchpoint at address + /// \a addr - /// const version. /// /// @param[in] addr @@ -86,10 +88,26 @@ public: FindByAddress (lldb::addr_t addr) const; //------------------------------------------------------------------ - /// Returns a shared pointer to the watchpoint with id /// \a breakID, const + /// Returns a shared pointer to the watchpoint with watchpoint spec + /// \a spec - + /// const version. + /// + /// @param[in] spec + /// The watchpoint spec to look for. + /// + /// @result + /// A shared pointer to the watchpoint. May contain a NULL + /// pointer if the watchpoint doesn't exist. + //------------------------------------------------------------------ + const lldb::WatchpointSP + FindBySpec (std::string spec) const; + + //------------------------------------------------------------------ + /// Returns a shared pointer to the watchpoint with id + /// \a watchID, const /// version. /// - /// @param[in] breakID + /// @param[in] watchID /// The watchpoint location ID to seek for. /// /// @result @@ -100,7 +118,8 @@ public: FindByID (lldb::watch_id_t watchID) const; //------------------------------------------------------------------ - /// Returns the watchpoint id to the watchpoint /// at address \a addr. + /// Returns the watchpoint id to the watchpoint + /// at address \a addr. /// /// @param[in] addr /// The address to match. @@ -112,6 +131,19 @@ public: FindIDByAddress (lldb::addr_t addr); //------------------------------------------------------------------ + /// Returns the watchpoint id to the watchpoint + /// with watchpoint spec \a spec. + /// + /// @param[in] spec + /// The watchpoint spec to match. + /// + /// @result + /// The ID of the watchpoint, or LLDB_INVALID_WATCH_ID. + //------------------------------------------------------------------ + lldb::watch_id_t + FindIDBySpec (std::string spec); + + //------------------------------------------------------------------ /// Returns a shared pointer to the watchpoint with index \a i. /// /// @param[in] i @@ -186,7 +218,7 @@ public: GetSize() const { Mutex::Locker locker(m_mutex); - return m_address_to_watchpoint.size(); + return m_watchpoints.size(); } //------------------------------------------------------------------ @@ -221,16 +253,22 @@ public: GetListMutex (lldb_private::Mutex::Locker &locker); protected: - typedef std::map<lldb::addr_t, lldb::WatchpointSP> addr_map; + typedef std::list<lldb::WatchpointSP> wp_collection; + typedef std::vector<lldb::watch_id_t> id_vector; - addr_map::iterator + id_vector + GetWatchpointIDs() const; + + wp_collection::iterator GetIDIterator(lldb::watch_id_t watchID); - addr_map::const_iterator + wp_collection::const_iterator GetIDConstIterator(lldb::watch_id_t watchID) const; - addr_map m_address_to_watchpoint; + wp_collection m_watchpoints; mutable Mutex m_mutex; + + lldb::watch_id_t m_next_wp_id; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 3979565f9ec..352ec600404 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -528,6 +528,9 @@ public: EnableAllWatchpoints (bool end_to_end = true); bool + ClearAllWatchpointHitCounts (); + + bool IgnoreAllWatchpoints (uint32_t ignore_count); bool diff --git a/lldb/source/Breakpoint/Watchpoint.cpp b/lldb/source/Breakpoint/Watchpoint.cpp index 02ae8b8b4bc..a0b47568594 100644 --- a/lldb/source/Breakpoint/Watchpoint.cpp +++ b/lldb/source/Breakpoint/Watchpoint.cpp @@ -24,9 +24,9 @@ using namespace lldb; using namespace lldb_private; Watchpoint::Watchpoint (lldb::addr_t addr, size_t size, bool hardware) : - StoppointLocation (GetNextID(), addr, size, hardware), + StoppointLocation (0, addr, size, hardware), m_target(NULL), - m_enabled(0), + m_enabled(false), m_is_hardware(hardware), m_watch_read(0), m_watch_write(0), @@ -36,6 +36,7 @@ Watchpoint::Watchpoint (lldb::addr_t addr, size_t size, bool hardware) : m_callback(NULL), m_callback_baton(NULL), m_decl_str(), + m_watch_spec_str(), m_error() { } @@ -44,13 +45,6 @@ Watchpoint::~Watchpoint() { } -break_id_t -Watchpoint::GetNextID() -{ - static break_id_t g_next_ID = 0; - return ++g_next_ID; -} - bool Watchpoint::SetCallback (WatchpointHitCallback callback, void *callback_baton) { @@ -66,6 +60,13 @@ Watchpoint::SetDeclInfo (std::string &str) return; } +void +Watchpoint::SetWatchSpec (std::string &str) +{ + m_watch_spec_str = str; + return; +} + // Override default impl of StoppointLocation::IsHardware() since m_is_hardware // member field is more accurate. bool @@ -117,13 +118,15 @@ Watchpoint::DumpWithLevel(Stream *s, lldb::DescriptionLevel description_level) c GetID(), GetLoadAddress(), m_byte_size, - m_enabled ? "enabled" : "disabled", + IsEnabled() ? "enabled" : "disabled", m_watch_read ? "r" : "", m_watch_write ? "w" : ""); if (description_level >= lldb::eDescriptionLevelFull) { if (!m_decl_str.empty()) s->Printf("\n declare @ '%s'", m_decl_str.c_str()); + if (!m_watch_spec_str.empty()) + s->Printf("\n static watchpoint spec = '%s'", m_watch_spec_str.c_str()); if (GetConditionText()) s->Printf("\n condition = '%s'", GetConditionText()); } diff --git a/lldb/source/Breakpoint/WatchpointList.cpp b/lldb/source/Breakpoint/WatchpointList.cpp index 9721b085e2e..a3f2bbb57e5 100644 --- a/lldb/source/Breakpoint/WatchpointList.cpp +++ b/lldb/source/Breakpoint/WatchpointList.cpp @@ -19,8 +19,9 @@ using namespace lldb; using namespace lldb_private; WatchpointList::WatchpointList() : - m_address_to_watchpoint (), - m_mutex (Mutex::eMutexTypeRecursive) + m_watchpoints (), + m_mutex (Mutex::eMutexTypeRecursive), + m_next_wp_id (0) { } @@ -28,21 +29,13 @@ WatchpointList::~WatchpointList() { } -// Add watchpoint loc to the list. However, if the element already exists in the -// list, then replace it with the input one. - +// Add a watchpoint to the list. lldb::watch_id_t WatchpointList::Add (const WatchpointSP &wp_sp) { Mutex::Locker locker (m_mutex); - lldb::addr_t wp_addr = wp_sp->GetLoadAddress(); - addr_map::iterator iter = m_address_to_watchpoint.find(wp_addr); - - if (iter == m_address_to_watchpoint.end()) - m_address_to_watchpoint.insert(iter, addr_map::value_type(wp_addr, wp_sp)); - else - m_address_to_watchpoint[wp_addr] = wp_sp; - + wp_sp->SetID(++m_next_wp_id); + m_watchpoints.push_back(wp_sp); return wp_sp->GetID(); } @@ -59,11 +52,11 @@ WatchpointList::DumpWithLevel (Stream *s, lldb::DescriptionLevel description_lev s->Printf("%p: ", this); //s->Indent(); s->Printf("WatchpointList with %zu Watchpoints:\n", - m_address_to_watchpoint.size()); + m_watchpoints.size()); s->IndentMore(); - addr_map::const_iterator pos, end = m_address_to_watchpoint.end(); - for (pos = m_address_to_watchpoint.begin(); pos != end; ++pos) - pos->second->DumpWithLevel(s, description_level); + wp_collection::const_iterator pos, end = m_watchpoints.end(); + for (pos = m_watchpoints.begin(); pos != end; ++pos) + (*pos)->DumpWithLevel(s, description_level); s->IndentLess(); } @@ -72,11 +65,32 @@ WatchpointList::FindByAddress (lldb::addr_t addr) const { WatchpointSP wp_sp; Mutex::Locker locker (m_mutex); - if (!m_address_to_watchpoint.empty()) + if (!m_watchpoints.empty()) + { + wp_collection::const_iterator pos, end = m_watchpoints.end(); + for (pos = m_watchpoints.begin(); pos != end; ++pos) + if ((*pos)->GetLoadAddress() == addr) { + wp_sp = *pos; + break; + } + } + + return wp_sp; +} + +const WatchpointSP +WatchpointList::FindBySpec (std::string spec) const +{ + WatchpointSP wp_sp; + Mutex::Locker locker (m_mutex); + if (!m_watchpoints.empty()) { - addr_map::const_iterator pos = m_address_to_watchpoint.find (addr); - if (pos != m_address_to_watchpoint.end()) - wp_sp = pos->second; + wp_collection::const_iterator pos, end = m_watchpoints.end(); + for (pos = m_watchpoints.begin(); pos != end; ++pos) + if ((*pos)->GetWatchSpec() == spec) { + wp_sp = *pos; + break; + } } return wp_sp; @@ -90,27 +104,27 @@ public: { } - bool operator() (std::pair <lldb::addr_t, WatchpointSP> val_pair) const + bool operator() (const WatchpointSP &wp) const { - return m_watch_id == val_pair.second.get()->GetID(); + return m_watch_id == wp->GetID(); } private: const lldb::watch_id_t m_watch_id; }; -WatchpointList::addr_map::iterator +WatchpointList::wp_collection::iterator WatchpointList::GetIDIterator (lldb::watch_id_t watch_id) { - return std::find_if(m_address_to_watchpoint.begin(), m_address_to_watchpoint.end(), // Search full range - WatchpointIDMatches(watch_id)); // Predicate + return std::find_if(m_watchpoints.begin(), m_watchpoints.end(), // Search full range + WatchpointIDMatches(watch_id)); // Predicate } -WatchpointList::addr_map::const_iterator +WatchpointList::wp_collection::const_iterator WatchpointList::GetIDConstIterator (lldb::watch_id_t watch_id) const { - return std::find_if(m_address_to_watchpoint.begin(), m_address_to_watchpoint.end(), // Search full range - WatchpointIDMatches(watch_id)); // Predicate + return std::find_if(m_watchpoints.begin(), m_watchpoints.end(), // Search full range + WatchpointIDMatches(watch_id)); // Predicate } WatchpointSP @@ -118,9 +132,9 @@ WatchpointList::FindByID (lldb::watch_id_t watch_id) const { WatchpointSP wp_sp; Mutex::Locker locker (m_mutex); - addr_map::const_iterator pos = GetIDConstIterator(watch_id); - if (pos != m_address_to_watchpoint.end()) - wp_sp = pos->second; + wp_collection::const_iterator pos = GetIDConstIterator(watch_id); + if (pos != m_watchpoints.end()) + wp_sp = *pos; return wp_sp; } @@ -136,16 +150,27 @@ WatchpointList::FindIDByAddress (lldb::addr_t addr) return LLDB_INVALID_WATCH_ID; } +lldb::watch_id_t +WatchpointList::FindIDBySpec (std::string spec) +{ + WatchpointSP wp_sp = FindBySpec (spec); + if (wp_sp) + { + return wp_sp->GetID(); + } + return LLDB_INVALID_WATCH_ID; +} + WatchpointSP WatchpointList::GetByIndex (uint32_t i) { Mutex::Locker locker (m_mutex); WatchpointSP wp_sp; - if (i < m_address_to_watchpoint.size()) + if (i < m_watchpoints.size()) { - addr_map::const_iterator pos = m_address_to_watchpoint.begin(); + wp_collection::const_iterator pos = m_watchpoints.begin(); std::advance(pos, i); - wp_sp = pos->second; + wp_sp = *pos; } return wp_sp; } @@ -155,23 +180,33 @@ WatchpointList::GetByIndex (uint32_t i) const { Mutex::Locker locker (m_mutex); WatchpointSP wp_sp; - if (i < m_address_to_watchpoint.size()) + if (i < m_watchpoints.size()) { - addr_map::const_iterator pos = m_address_to_watchpoint.begin(); + wp_collection::const_iterator pos = m_watchpoints.begin(); std::advance(pos, i); - wp_sp = pos->second; + wp_sp = *pos; } return wp_sp; } +std::vector<lldb::watch_id_t> +WatchpointList::GetWatchpointIDs() const +{ + std::vector<lldb::watch_id_t> IDs; + wp_collection::const_iterator pos, end = m_watchpoints.end(); + for (pos = m_watchpoints.begin(); pos != end; ++pos) + IDs.push_back((*pos)->GetID()); + return IDs; +} + bool WatchpointList::Remove (lldb::watch_id_t watch_id) { Mutex::Locker locker (m_mutex); - addr_map::iterator pos = GetIDIterator(watch_id); - if (pos != m_address_to_watchpoint.end()) + wp_collection::iterator pos = GetIDIterator(watch_id); + if (pos != m_watchpoints.end()) { - m_address_to_watchpoint.erase(pos); + m_watchpoints.erase(pos); return true; } return false; @@ -182,9 +217,9 @@ WatchpointList::GetHitCount () const { uint32_t hit_count = 0; Mutex::Locker locker (m_mutex); - addr_map::const_iterator pos, end = m_address_to_watchpoint.end(); - for (pos = m_address_to_watchpoint.begin(); pos != end; ++pos) - hit_count += pos->second->GetHitCount(); + wp_collection::const_iterator pos, end = m_watchpoints.end(); + for (pos = m_watchpoints.begin(); pos != end; ++pos) + hit_count += (*pos)->GetHitCount(); return hit_count; } @@ -209,12 +244,12 @@ void WatchpointList::GetDescription (Stream *s, lldb::DescriptionLevel level) { Mutex::Locker locker (m_mutex); - addr_map::iterator pos, end = m_address_to_watchpoint.end(); + wp_collection::iterator pos, end = m_watchpoints.end(); - for (pos = m_address_to_watchpoint.begin(); pos != end; ++pos) + for (pos = m_watchpoints.begin(); pos != end; ++pos) { s->Printf(" "); - pos->second->Dump(s); + (*pos)->Dump(s); } } @@ -223,16 +258,16 @@ WatchpointList::SetEnabledAll (bool enabled) { Mutex::Locker locker(m_mutex); - addr_map::iterator pos, end = m_address_to_watchpoint.end(); - for (pos = m_address_to_watchpoint.begin(); pos != end; ++pos) - pos->second->SetEnabled (enabled); + wp_collection::iterator pos, end = m_watchpoints.end(); + for (pos = m_watchpoints.begin(); pos != end; ++pos) + (*pos)->SetEnabled (enabled); } void WatchpointList::RemoveAll () { Mutex::Locker locker(m_mutex); - m_address_to_watchpoint.clear(); + m_watchpoints.clear(); } void diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 88976ef90e6..3a26b77ed30 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -138,7 +138,10 @@ Target::DeleteCurrentProcess () m_breakpoint_list.ClearAllBreakpointSites(); m_internal_breakpoint_list.ClearAllBreakpointSites(); // Disable watchpoints just on the debugger side. + Mutex::Locker locker; + this->GetWatchpointList().GetListMutex(locker); DisableAllWatchpoints(false); + ClearAllWatchpointHitCounts(); m_process_sp.reset(); } } @@ -672,6 +675,26 @@ Target::EnableAllWatchpoints (bool end_to_end) return true; // Success! } +// Assumption: Caller holds the list mutex lock for m_watchpoint_list. +bool +Target::ClearAllWatchpointHitCounts () +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); + if (log) + log->Printf ("Target::%s\n", __FUNCTION__); + + size_t num_watchpoints = m_watchpoint_list.GetSize(); + for (size_t i = 0; i < num_watchpoints; ++i) + { + WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i); + if (!wp_sp) + return false; + + wp_sp->ResetHitCount(); + } + return true; // Success! +} + // Assumption: Caller holds the list mutex lock for m_watchpoint_list // during these operations. bool |