1 //===-- Watchpoint.h --------------------------------------------*- 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 #ifndef liblldb_Watchpoint_h_
11 #define liblldb_Watchpoint_h_
12 
13 #include <memory>
14 #include <string>
15 
16 #include "lldb/Breakpoint/StoppointLocation.h"
17 #include "lldb/Breakpoint/WatchpointOptions.h"
18 #include "lldb/Symbol/CompilerType.h"
19 #include "lldb/Target/Target.h"
20 #include "lldb/Utility/UserID.h"
21 #include "lldb/lldb-private.h"
22 
23 namespace lldb_private {
24 
25 class Watchpoint : public std::enable_shared_from_this<Watchpoint>,
26                    public StoppointLocation {
27 public:
28   class WatchpointEventData : public EventData {
29   public:
30     WatchpointEventData(lldb::WatchpointEventType sub_type,
31                         const lldb::WatchpointSP &new_watchpoint_sp);
32 
33     ~WatchpointEventData() override;
34 
35     static const ConstString &GetFlavorString();
36 
37     const ConstString &GetFlavor() const override;
38 
39     lldb::WatchpointEventType GetWatchpointEventType() const;
40 
41     lldb::WatchpointSP &GetWatchpoint();
42 
43     void Dump(Stream *s) const override;
44 
45     static lldb::WatchpointEventType
46     GetWatchpointEventTypeFromEvent(const lldb::EventSP &event_sp);
47 
48     static lldb::WatchpointSP
49     GetWatchpointFromEvent(const lldb::EventSP &event_sp);
50 
51     static const WatchpointEventData *
52     GetEventDataFromEvent(const Event *event_sp);
53 
54   private:
55     lldb::WatchpointEventType m_watchpoint_event;
56     lldb::WatchpointSP m_new_watchpoint_sp;
57 
58     DISALLOW_COPY_AND_ASSIGN(WatchpointEventData);
59   };
60 
61   Watchpoint(Target &target, lldb::addr_t addr, uint32_t size,
62              const CompilerType *type, bool hardware = true);
63 
64   ~Watchpoint() override;
65 
66   void IncrementFalseAlarmsAndReviseHitCount();
67 
68   bool IsEnabled() const;
69 
70   // This doesn't really enable/disable the watchpoint.   It is currently just
71   // for use in the Process plugin's {Enable,Disable}Watchpoint, which should
72   // be used instead.
73 
74   void SetEnabled(bool enabled, bool notify = true);
75 
76   bool IsHardware() const override;
77 
78   bool ShouldStop(StoppointCallbackContext *context) override;
79 
80   bool WatchpointRead() const;
81   bool WatchpointWrite() const;
82   uint32_t GetIgnoreCount() const;
83   void SetIgnoreCount(uint32_t n);
84   void SetWatchpointType(uint32_t type, bool notify = true);
85   void SetDeclInfo(const std::string &str);
86   std::string GetWatchSpec();
87   void SetWatchSpec(const std::string &str);
88 
89   // Snapshot management interface.
90   bool IsWatchVariable() const;
91   void SetWatchVariable(bool val);
92   bool CaptureWatchedValue(const ExecutionContext &exe_ctx);
93 
94   void GetDescription(Stream *s, lldb::DescriptionLevel level);
95   void Dump(Stream *s) const override;
96   void DumpSnapshots(Stream *s, const char *prefix = nullptr) const;
97   void DumpWithLevel(Stream *s, lldb::DescriptionLevel description_level) const;
GetTarget()98   Target &GetTarget() { return m_target; }
GetError()99   const Status &GetError() { return m_error; }
100 
101   //------------------------------------------------------------------
102   /// Returns the WatchpointOptions structure set for this watchpoint.
103   ///
104   /// @return
105   ///     A pointer to this watchpoint's WatchpointOptions.
106   //------------------------------------------------------------------
GetOptions()107   WatchpointOptions *GetOptions() { return &m_options; }
108 
109   //------------------------------------------------------------------
110   /// Set the callback action invoked when the watchpoint is hit.
111   ///
112   /// @param[in] callback
113   ///    The method that will get called when the watchpoint is hit.
114   /// @param[in] callback_baton
115   ///    A void * pointer that will get passed back to the callback function.
116   /// @param[in] is_synchronous
117   ///    If \b true the callback will be run on the private event thread
118   ///    before the stop event gets reported.  If false, the callback will get
119   ///    handled on the public event thread after the stop has been posted.
120   ///
121   /// @return
122   ///    \b true if the process should stop when you hit the watchpoint.
123   ///    \b false if it should continue.
124   //------------------------------------------------------------------
125   void SetCallback(WatchpointHitCallback callback, void *callback_baton,
126                    bool is_synchronous = false);
127 
128   void SetCallback(WatchpointHitCallback callback,
129                    const lldb::BatonSP &callback_baton_sp,
130                    bool is_synchronous = false);
131 
132   void ClearCallback();
133 
134   //------------------------------------------------------------------
135   /// Invoke the callback action when the watchpoint is hit.
136   ///
137   /// @param[in] context
138   ///     Described the watchpoint event.
139   ///
140   /// @return
141   ///     \b true if the target should stop at this watchpoint and \b false not.
142   //------------------------------------------------------------------
143   bool InvokeCallback(StoppointCallbackContext *context);
144 
145   //------------------------------------------------------------------
146   // Condition
147   //------------------------------------------------------------------
148   //------------------------------------------------------------------
149   /// Set the watchpoint's condition.
150   ///
151   /// @param[in] condition
152   ///    The condition expression to evaluate when the watchpoint is hit.
153   ///    Pass in nullptr to clear the condition.
154   //------------------------------------------------------------------
155   void SetCondition(const char *condition);
156 
157   //------------------------------------------------------------------
158   /// Return a pointer to the text of the condition expression.
159   ///
160   /// @return
161   ///    A pointer to the condition expression text, or nullptr if no
162   //     condition has been set.
163   //------------------------------------------------------------------
164   const char *GetConditionText() const;
165 
166   void TurnOnEphemeralMode();
167 
168   void TurnOffEphemeralMode();
169 
170   bool IsDisabledDuringEphemeralMode();
171 
GetCompilerType()172   const CompilerType &GetCompilerType() { return m_type; }
173 
174 private:
175   friend class Target;
176   friend class WatchpointList;
177 
ResetHitCount()178   void ResetHitCount() { m_hit_count = 0; }
179 
ResetHistoricValues()180   void ResetHistoricValues() {
181     m_old_value_sp.reset(nullptr);
182     m_new_value_sp.reset(nullptr);
183   }
184 
185   Target &m_target;
186   bool m_enabled;           // Is this watchpoint enabled
187   bool m_is_hardware;       // Is this a hardware watchpoint
188   bool m_is_watch_variable; // True if set via 'watchpoint set variable'.
189   bool m_is_ephemeral;      // True if the watchpoint is in the ephemeral mode,
190                             // meaning that it is
191   // undergoing a pair of temporary disable/enable actions to avoid recursively
192   // triggering further watchpoint events.
193   uint32_t m_disabled_count; // Keep track of the count that the watchpoint is
194                              // disabled while in ephemeral mode.
195   // At the end of the ephemeral mode when the watchpoint is to be enabled
196   // again, we check the count, if it is more than 1, it means the user-
197   // supplied actions actually want the watchpoint to be disabled!
198   uint32_t m_watch_read : 1, // 1 if we stop when the watched data is read from
199       m_watch_write : 1,     // 1 if we stop when the watched data is written to
200       m_watch_was_read : 1, // Set to 1 when watchpoint is hit for a read access
201       m_watch_was_written : 1;  // Set to 1 when watchpoint is hit for a write
202                                 // access
203   uint32_t m_ignore_count;      // Number of times to ignore this watchpoint
204   uint32_t m_false_alarms;      // Number of false alarms.
205   std::string m_decl_str;       // Declaration information, if any.
206   std::string m_watch_spec_str; // Spec for the watchpoint.
207   lldb::ValueObjectSP m_old_value_sp;
208   lldb::ValueObjectSP m_new_value_sp;
209   CompilerType m_type;
210   Status m_error; // An error object describing errors associated with this
211                   // watchpoint.
212   WatchpointOptions
213       m_options; // Settable watchpoint options, which is a delegate to handle
214                  // the callback machinery.
215   bool m_being_created;
216 
217   std::unique_ptr<UserExpression> m_condition_ap; // The condition to test.
218 
SetID(lldb::watch_id_t id)219   void SetID(lldb::watch_id_t id) { m_loc_id = id; }
220 
221   void SendWatchpointChangedEvent(lldb::WatchpointEventType eventKind);
222 
223   void SendWatchpointChangedEvent(WatchpointEventData *data);
224 
225   DISALLOW_COPY_AND_ASSIGN(Watchpoint);
226 };
227 
228 } // namespace lldb_private
229 
230 #endif // liblldb_Watchpoint_h_
231