1 //===-- WatchpointList.h ----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef liblldb_WatchpointList_h_
10 #define liblldb_WatchpointList_h_
11 
12 #include <list>
13 #include <mutex>
14 #include <vector>
15 
16 #include "lldb/Core/Address.h"
17 #include "lldb/lldb-private.h"
18 
19 namespace lldb_private {
20 
21 /// \class WatchpointList WatchpointList.h "lldb/Breakpoint/WatchpointList.h"
22 /// This class is used by Watchpoint to manage a list of watchpoints,
23 //  each watchpoint in the list has a unique ID, and is unique by Address as
24 //  well.
25 
26 class WatchpointList {
27   // Only Target can make the watchpoint list, or add elements to it. This is
28   // not just some random collection of watchpoints.  Rather, the act of adding
29   // the watchpoint to this list sets its ID.
30   friend class Watchpoint;
31   friend class Target;
32 
33 public:
34   /// Default constructor makes an empty list.
35   WatchpointList();
36 
37   /// Destructor, currently does nothing.
38   ~WatchpointList();
39 
40   /// Add a Watchpoint to the list.
41   ///
42   /// \param[in] wp_sp
43   ///    A shared pointer to a watchpoint being added to the list.
44   ///
45   /// \return
46   ///    The ID of the Watchpoint in the list.
47   lldb::watch_id_t Add(const lldb::WatchpointSP &wp_sp, bool notify);
48 
49   /// Standard "Dump" method.
50   void Dump(Stream *s) const;
51 
52   /// Dump with lldb::DescriptionLevel.
53   void DumpWithLevel(Stream *s, lldb::DescriptionLevel description_level) const;
54 
55   /// Returns a shared pointer to the watchpoint at address \a addr - const
56   /// version.
57   ///
58   /// \param[in] addr
59   ///     The address to look for.
60   ///
61   /// \result
62   ///     A shared pointer to the watchpoint.  May contain a NULL
63   ///     pointer if the watchpoint doesn't exist.
64   const lldb::WatchpointSP FindByAddress(lldb::addr_t addr) const;
65 
66   /// Returns a shared pointer to the watchpoint with watchpoint spec \a spec
67   /// - const version.
68   ///
69   /// \param[in] spec
70   ///     The watchpoint spec to look for.
71   ///
72   /// \result
73   ///     A shared pointer to the watchpoint.  May contain a NULL
74   ///     pointer if the watchpoint doesn't exist.
75   const lldb::WatchpointSP FindBySpec(std::string spec) const;
76 
77   /// Returns a shared pointer to the watchpoint with id \a watchID, const
78   /// version.
79   ///
80   /// \param[in] watchID
81   ///     The watchpoint location ID to seek for.
82   ///
83   /// \result
84   ///     A shared pointer to the watchpoint.  May contain a NULL
85   ///     pointer if the watchpoint doesn't exist.
86   lldb::WatchpointSP FindByID(lldb::watch_id_t watchID) const;
87 
88   /// Returns the watchpoint id to the watchpoint at address \a addr.
89   ///
90   /// \param[in] addr
91   ///     The address to match.
92   ///
93   /// \result
94   ///     The ID of the watchpoint, or LLDB_INVALID_WATCH_ID.
95   lldb::watch_id_t FindIDByAddress(lldb::addr_t addr);
96 
97   /// Returns the watchpoint id to the watchpoint with watchpoint spec \a
98   /// spec.
99   ///
100   /// \param[in] spec
101   ///     The watchpoint spec to match.
102   ///
103   /// \result
104   ///     The ID of the watchpoint, or LLDB_INVALID_WATCH_ID.
105   lldb::watch_id_t FindIDBySpec(std::string spec);
106 
107   /// Returns a shared pointer to the watchpoint with index \a i.
108   ///
109   /// \param[in] i
110   ///     The watchpoint index to seek for.
111   ///
112   /// \result
113   ///     A shared pointer to the watchpoint.  May contain a NULL pointer if
114   ///     the watchpoint doesn't exist.
115   lldb::WatchpointSP GetByIndex(uint32_t i);
116 
117   /// Returns a shared pointer to the watchpoint with index \a i, const
118   /// version.
119   ///
120   /// \param[in] i
121   ///     The watchpoint index to seek for.
122   ///
123   /// \result
124   ///     A shared pointer to the watchpoint.  May contain a NULL pointer if
125   ///     the watchpoint location doesn't exist.
126   const lldb::WatchpointSP GetByIndex(uint32_t i) const;
127 
128   /// Removes the watchpoint given by \b watchID from this list.
129   ///
130   /// \param[in] watchID
131   ///   The watchpoint ID to remove.
132   ///
133   /// \result
134   ///   \b true if the watchpoint \a watchID was in the list.
135   bool Remove(lldb::watch_id_t watchID, bool notify);
136 
137   /// Returns the number hit count of all watchpoints in this list.
138   ///
139   /// \result
140   ///     Hit count of all watchpoints in this list.
141   uint32_t GetHitCount() const;
142 
143   /// Enquires of the watchpoint in this list with ID \a watchID whether we
144   /// should stop.
145   ///
146   /// \param[in] context
147   ///     This contains the information about this stop.
148   ///
149   /// \param[in] watchID
150   ///     This watch ID that we hit.
151   ///
152   /// \return
153   ///     \b true if we should stop, \b false otherwise.
154   bool ShouldStop(StoppointCallbackContext *context, lldb::watch_id_t watchID);
155 
156   /// Returns the number of elements in this watchpoint list.
157   ///
158   /// \result
159   ///     The number of elements.
160   size_t GetSize() const {
161     std::lock_guard<std::recursive_mutex> guard(m_mutex);
162     return m_watchpoints.size();
163   }
164 
165   /// Print a description of the watchpoints in this list to the stream \a s.
166   ///
167   /// \param[in] s
168   ///     The stream to which to print the description.
169   ///
170   /// \param[in] level
171   ///     The description level that indicates the detail level to
172   ///     provide.
173   ///
174   /// \see lldb::DescriptionLevel
175   void GetDescription(Stream *s, lldb::DescriptionLevel level);
176 
177   void SetEnabledAll(bool enabled);
178 
179   void RemoveAll(bool notify);
180 
181   /// Sets the passed in Locker to hold the Watchpoint List mutex.
182   ///
183   /// \param[in] locker
184   ///   The locker object that is set.
185   void GetListMutex(std::unique_lock<std::recursive_mutex> &lock);
186 
187 protected:
188   typedef std::list<lldb::WatchpointSP> wp_collection;
189   typedef std::vector<lldb::watch_id_t> id_vector;
190 
191   id_vector GetWatchpointIDs() const;
192 
193   wp_collection::iterator GetIDIterator(lldb::watch_id_t watchID);
194 
195   wp_collection::const_iterator
196   GetIDConstIterator(lldb::watch_id_t watchID) const;
197 
198   wp_collection m_watchpoints;
199   mutable std::recursive_mutex m_mutex;
200 
201   lldb::watch_id_t m_next_wp_id;
202 };
203 
204 } // namespace lldb_private
205 
206 #endif // liblldb_WatchpointList_h_
207