1 //===-- WatchpointOptions.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 LLDB_BREAKPOINT_WATCHPOINTOPTIONS_H
10 #define LLDB_BREAKPOINT_WATCHPOINTOPTIONS_H
11 
12 #include <memory>
13 #include <string>
14 
15 #include "lldb/Utility/Baton.h"
16 #include "lldb/Utility/StringList.h"
17 #include "lldb/lldb-private.h"
18 
19 namespace lldb_private {
20 
21 /// \class WatchpointOptions WatchpointOptions.h
22 /// "lldb/Breakpoint/WatchpointOptions.h" Class that manages the options on a
23 /// watchpoint.
24 
25 class WatchpointOptions {
26 public:
27   // Constructors and Destructors
28   /// Default constructor.  The watchpoint is enabled, and has no condition,
29   /// callback, ignore count, etc...
30   WatchpointOptions();
31   WatchpointOptions(const WatchpointOptions &rhs);
32 
33   static WatchpointOptions *CopyOptionsNoCallback(WatchpointOptions &rhs);
34   /// This constructor allows you to specify all the watchpoint options.
35   ///
36   /// \param[in] callback
37   ///    This is the plugin for some code that gets run, returns \b true if we
38   ///    are to stop.
39   ///
40   /// \param[in] baton
41   ///    Client data that will get passed to the callback.
42   ///
43   /// \param[in] thread_id
44   ///    Only stop if \a thread_id hits the watchpoint.
45   WatchpointOptions(WatchpointHitCallback callback, void *baton,
46                     lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID);
47 
48   virtual ~WatchpointOptions();
49 
50   // Operators
51   const WatchpointOptions &operator=(const WatchpointOptions &rhs);
52 
53   // Callbacks
54   //
55   // Watchpoint callbacks come in two forms, synchronous and asynchronous.
56   // Synchronous callbacks will get run before any of the thread plans are
57   // consulted, and if they return false the target will continue "under the
58   // radar" of the thread plans.  There are a couple of restrictions to
59   // synchronous callbacks: 1) They should NOT resume the target themselves.
60   // Just return false if you want the target to restart. 2) Watchpoints with
61   // synchronous callbacks can't have conditions (or rather, they can have
62   // them, but they won't do anything.  Ditto with ignore counts, etc...
63   // You are supposed to control that all through the callback.
64   // Asynchronous callbacks get run as part of the "ShouldStop" logic in the
65   // thread plan.  The logic there is:
66   //   a) If the watchpoint is thread specific and not for this thread, continue
67   //      w/o running the callback.
68   //   b) If the ignore count says we shouldn't stop, then ditto.
69   //   c) If the condition says we shouldn't stop, then ditto.
70   //   d) Otherwise, the callback will get run, and if it returns true we will
71   //      stop, and if false we won't.
72   //  The asynchronous callback can run the target itself, but at present that
73   //  should be the last action the callback does.  We will relax this
74   //  condition at some point, but it will take a bit of plumbing to get
75   //  that to work.
76 
77   /// Adds a callback to the watchpoint option set.
78   ///
79   /// \param[in] callback
80   ///    The function to be called when the watchpoint gets hit.
81   ///
82   /// \param[in] baton_sp
83   ///    A baton which will get passed back to the callback when it is invoked.
84   ///
85   /// \param[in] synchronous
86   ///    Whether this is a synchronous or asynchronous callback.
87   ///    See discussion above.
88   void SetCallback(WatchpointHitCallback callback,
89                    const lldb::BatonSP &baton_sp, bool synchronous = false);
90 
91   /// Remove the callback from this option set.
92   void ClearCallback();
93 
94   // The rest of these functions are meant to be used only within the
95   // watchpoint handling mechanism.
96 
97   /// Use this function to invoke the callback for a specific stop.
98   ///
99   /// \param[in] context
100   ///    The context in which the callback is to be invoked.  This includes the
101   ///    stop event, the execution context of the stop (since you might hit
102   ///    the same watchpoint on multiple threads) and whether we are currently
103   ///    executing synchronous or asynchronous callbacks.
104   ///
105   /// \param[in] watch_id
106   ///    The watchpoint ID that owns this option set.
107   ///
108   /// \return
109   ///     The callback return value.
110   bool InvokeCallback(StoppointCallbackContext *context,
111                       lldb::user_id_t watch_id);
112 
113   /// Used in InvokeCallback to tell whether it is the right time to run this
114   /// kind of callback.
115   ///
116   /// \return
117   ///     The synchronicity of our callback.
IsCallbackSynchronous()118   bool IsCallbackSynchronous() { return m_callback_is_synchronous; }
119 
120   /// Fetch the baton from the callback.
121   ///
122   /// \return
123   ///     The baton.
124   Baton *GetBaton();
125 
126   /// Fetch a const version of the baton from the callback.
127   ///
128   /// \return
129   ///     The baton.
130   const Baton *GetBaton() const;
131 
132   /// Return the current thread spec for this option. This will return nullptr
133   /// if the no thread specifications have been set for this WatchpointOptions
134   /// yet.
135   ///
136   /// \return
137   ///     The thread specification pointer for this option, or nullptr if none
138   ///     has been set yet.
139   const ThreadSpec *GetThreadSpecNoCreate() const;
140 
141   /// Returns a pointer to the ThreadSpec for this option, creating it if it
142   /// hasn't been created already. This API is used for setting the
143   /// ThreadSpec items for this WatchpointOptions.
144   ThreadSpec *GetThreadSpec();
145 
146   void SetThreadID(lldb::tid_t thread_id);
147 
148   void GetDescription(Stream *s, lldb::DescriptionLevel level) const;
149 
150   /// Get description for callback only.
151   void GetCallbackDescription(Stream *s, lldb::DescriptionLevel level) const;
152 
153   /// Returns true if the watchpoint option has a callback set.
154   bool HasCallback();
155 
156   /// This is the default empty callback.
157   /// \return
158   ///     The thread id for which the watchpoint hit will stop,
159   ///     LLDB_INVALID_THREAD_ID for all threads.
160   static bool NullCallback(void *baton, StoppointCallbackContext *context,
161                            lldb::user_id_t watch_id);
162 
163   struct CommandData {
164     CommandData() = default;
165 
166     ~CommandData() = default;
167 
168     StringList user_source;
169     std::string script_source;
170     bool stop_on_error = true;
171   };
172 
173   class CommandBaton : public TypedBaton<CommandData> {
174   public:
CommandBaton(std::unique_ptr<CommandData> Data)175     CommandBaton(std::unique_ptr<CommandData> Data)
176         : TypedBaton(std::move(Data)) {}
177 
178     void GetDescription(llvm::raw_ostream &s, lldb::DescriptionLevel level,
179                         unsigned indentation) const override;
180   };
181 
182 private:
183   WatchpointHitCallback m_callback;  // This is the callback function pointer
184   lldb::BatonSP m_callback_baton_sp; // This is the client data for the callback
185   bool m_callback_is_synchronous = false;
186   std::unique_ptr<ThreadSpec>
187       m_thread_spec_up; // Thread for which this watchpoint will take
188 };
189 
190 } // namespace lldb_private
191 
192 #endif // LLDB_BREAKPOINT_WATCHPOINTOPTIONS_H
193