File indexing completed on 2026-05-10 08:42:44
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLDB_BREAKPOINT_WATCHPOINT_H
0010 #define LLDB_BREAKPOINT_WATCHPOINT_H
0011
0012 #include <memory>
0013 #include <string>
0014
0015 #include "lldb/Breakpoint/StoppointSite.h"
0016 #include "lldb/Breakpoint/WatchpointOptions.h"
0017 #include "lldb/Symbol/CompilerType.h"
0018 #include "lldb/Target/Target.h"
0019 #include "lldb/Utility/UserID.h"
0020 #include "lldb/lldb-private.h"
0021
0022 namespace lldb_private {
0023
0024 class Watchpoint : public std::enable_shared_from_this<Watchpoint>,
0025 public StoppointSite {
0026 public:
0027 class WatchpointEventData : public EventData {
0028 public:
0029 WatchpointEventData(lldb::WatchpointEventType sub_type,
0030 const lldb::WatchpointSP &new_watchpoint_sp);
0031
0032 ~WatchpointEventData() override;
0033
0034 static llvm::StringRef GetFlavorString();
0035
0036 llvm::StringRef GetFlavor() const override;
0037
0038 lldb::WatchpointEventType GetWatchpointEventType() const;
0039
0040 lldb::WatchpointSP &GetWatchpoint();
0041
0042 void Dump(Stream *s) const override;
0043
0044 static lldb::WatchpointEventType
0045 GetWatchpointEventTypeFromEvent(const lldb::EventSP &event_sp);
0046
0047 static lldb::WatchpointSP
0048 GetWatchpointFromEvent(const lldb::EventSP &event_sp);
0049
0050 static const WatchpointEventData *
0051 GetEventDataFromEvent(const Event *event_sp);
0052
0053 private:
0054 lldb::WatchpointEventType m_watchpoint_event;
0055 lldb::WatchpointSP m_new_watchpoint_sp;
0056
0057 WatchpointEventData(const WatchpointEventData &) = delete;
0058 const WatchpointEventData &operator=(const WatchpointEventData &) = delete;
0059 };
0060
0061 Watchpoint(Target &target, lldb::addr_t addr, uint32_t size,
0062 const CompilerType *type, bool hardware = true);
0063
0064 ~Watchpoint() override;
0065
0066 bool IsEnabled() const;
0067
0068
0069
0070
0071 void SetEnabled(bool enabled, bool notify = true);
0072
0073 bool IsHardware() const override;
0074
0075 bool ShouldStop(StoppointCallbackContext *context) override;
0076
0077 bool WatchpointRead() const;
0078 bool WatchpointWrite() const;
0079 bool WatchpointModify() const;
0080 uint32_t GetIgnoreCount() const;
0081 void SetIgnoreCount(uint32_t n);
0082 void SetWatchpointType(uint32_t type, bool notify = true);
0083 void SetDeclInfo(const std::string &str);
0084 std::string GetWatchSpec();
0085 void SetWatchSpec(const std::string &str);
0086 bool WatchedValueReportable(const ExecutionContext &exe_ctx);
0087
0088
0089 bool IsWatchVariable() const;
0090 void SetWatchVariable(bool val);
0091 bool CaptureWatchedValue(const ExecutionContext &exe_ctx);
0092
0093
0094
0095
0096
0097
0098
0099
0100 struct WatchpointVariableContext {
0101
0102
0103
0104 WatchpointVariableContext(lldb::watch_id_t watch_id,
0105 ExecutionContext exe_ctx)
0106 : watch_id(watch_id), exe_ctx(exe_ctx) {}
0107
0108 lldb::watch_id_t watch_id;
0109 ExecutionContext
0110 exe_ctx;
0111 };
0112
0113 class WatchpointVariableBaton : public TypedBaton<WatchpointVariableContext> {
0114 public:
0115 WatchpointVariableBaton(std::unique_ptr<WatchpointVariableContext> Data)
0116 : TypedBaton(std::move(Data)) {}
0117 };
0118
0119 bool SetupVariableWatchpointDisabler(lldb::StackFrameSP frame_sp) const;
0120
0121
0122
0123 static bool VariableWatchpointDisabler(
0124 void *baton, lldb_private::StoppointCallbackContext *context,
0125 lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
0126
0127 void GetDescription(Stream *s, lldb::DescriptionLevel level);
0128 void Dump(Stream *s) const override;
0129 bool DumpSnapshots(Stream *s, const char *prefix = nullptr) const;
0130 void DumpWithLevel(Stream *s, lldb::DescriptionLevel description_level) const;
0131 Target &GetTarget() { return m_target; }
0132 const Status &GetError() { return m_error; }
0133
0134
0135
0136
0137
0138 WatchpointOptions *GetOptions() { return &m_options; }
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 void SetCallback(WatchpointHitCallback callback, void *callback_baton,
0151 bool is_synchronous = false);
0152
0153 void SetCallback(WatchpointHitCallback callback,
0154 const lldb::BatonSP &callback_baton_sp,
0155 bool is_synchronous = false);
0156
0157 void ClearCallback();
0158
0159
0160
0161
0162
0163
0164
0165
0166 bool InvokeCallback(StoppointCallbackContext *context);
0167
0168
0169
0170
0171
0172
0173
0174 void SetCondition(const char *condition);
0175
0176
0177
0178
0179
0180
0181 const char *GetConditionText() const;
0182
0183 void TurnOnEphemeralMode();
0184
0185 void TurnOffEphemeralMode();
0186
0187 bool IsDisabledDuringEphemeralMode();
0188
0189 const CompilerType &GetCompilerType() { return m_type; }
0190
0191 private:
0192 friend class Target;
0193 friend class WatchpointList;
0194 friend class StopInfoWatchpoint;
0195
0196 void ResetHistoricValues() {
0197 m_old_value_sp.reset();
0198 m_new_value_sp.reset();
0199 }
0200
0201 void UndoHitCount() { m_hit_counter.Decrement(); }
0202
0203 Target &m_target;
0204 bool m_enabled;
0205 bool m_is_hardware;
0206 bool m_is_watch_variable;
0207 bool m_is_ephemeral;
0208
0209
0210
0211 uint32_t m_disabled_count;
0212
0213
0214
0215
0216 uint32_t m_watch_read : 1,
0217 m_watch_write : 1,
0218 m_watch_modify : 1;
0219 uint32_t m_ignore_count;
0220 std::string m_decl_str;
0221 std::string m_watch_spec_str;
0222 lldb::ValueObjectSP m_old_value_sp;
0223 lldb::ValueObjectSP m_new_value_sp;
0224 CompilerType m_type;
0225 Status m_error;
0226
0227 WatchpointOptions m_options;
0228
0229 std::unique_ptr<UserExpression> m_condition_up;
0230
0231 void SetID(lldb::watch_id_t id) { m_id = id; }
0232
0233 void SendWatchpointChangedEvent(lldb::WatchpointEventType eventKind);
0234
0235 Watchpoint(const Watchpoint &) = delete;
0236 const Watchpoint &operator=(const Watchpoint &) = delete;
0237 };
0238
0239 }
0240
0241 #endif