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