aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Breakpoint/BreakpointOptions.h
blob: eb374ad69603a22516859371958ca486e90af1bf (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
//===-- BreakpointOptions.h -------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_BreakpointOptions_h_
#define liblldb_BreakpointOptions_h_

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Core/Baton.h"
#include "lldb/Core/StringList.h"

namespace lldb_private {

//----------------------------------------------------------------------
/// @class BreakpointOptions BreakpointOptions.h "lldb/Breakpoint/BreakpointOptions.h"
/// @brief Class that manages the options on a breakpoint or breakpoint location.
//----------------------------------------------------------------------

class BreakpointOptions
{
public:
    //------------------------------------------------------------------
    // Constructors and Destructors
    //------------------------------------------------------------------
    //------------------------------------------------------------------
    /// Default constructor.  The breakpoint is enabled, and has no condition,
    /// callback, ignore count, etc...
    //------------------------------------------------------------------
    BreakpointOptions();
    BreakpointOptions(const BreakpointOptions& rhs);

    static BreakpointOptions *
    CopyOptionsNoCallback (BreakpointOptions &rhs);
    //------------------------------------------------------------------
    /// This constructor allows you to specify all the breakpoint options.
    ///
    /// @param[in] condition
    ///    The expression which if it evaluates to \b true if we are to stop
    ///
    /// @param[in] callback
    ///    This is the plugin for some code that gets run, returns \b true if we are to stop.
    ///
    /// @param[in] baton
    ///    Client data that will get passed to the callback.
    ///
    /// @param[in] enabled
    ///    Is this breakpoint enabled.
    ///
    /// @param[in] ignore
    ///    How many breakpoint hits we should ignore before stopping.
    ///
    /// @param[in] thread_id
    ///    Only stop if \a thread_id hits the breakpoint.
    //------------------------------------------------------------------
    BreakpointOptions(void *condition,
                      BreakpointHitCallback callback,
                      void *baton,
                      bool enabled = true,
                      int32_t ignore = 0,
                      lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID,
                      bool one_shot = false);

    virtual ~BreakpointOptions();

    //------------------------------------------------------------------
    // Operators
    //------------------------------------------------------------------
    const BreakpointOptions&
    operator=(const BreakpointOptions& rhs);

    //------------------------------------------------------------------
    // Callbacks
    //
    // Breakpoint callbacks come in two forms, synchronous and asynchronous.  Synchronous callbacks will get
    // run before any of the thread plans are consulted, and if they return false the target will continue
    // "under the radar" of the thread plans.  There are a couple of restrictions to synchronous callbacks:
    // 1) They should NOT resume the target themselves.  Just return false if you want the target to restart.
    // 2) Breakpoints with synchronous callbacks can't have conditions (or rather, they can have them, but they
    //    won't do anything.  Ditto with ignore counts, etc...  You are supposed to control that all through the
    //    callback.
    // Asynchronous callbacks get run as part of the "ShouldStop" logic in the thread plan.  The logic there is:
    //   a) If the breakpoint is thread specific and not for this thread, continue w/o running the callback.
    //   b) If the ignore count says we shouldn't stop, then ditto.
    //   c) If the condition says we shouldn't stop, then ditto.
    //   d) Otherwise, the callback will get run, and if it returns true we will stop, and if false we won't.
    //  The asynchronous callback can run the target itself, but at present that should be the last action the
    //  callback does.  We will relax this condition at some point, but it will take a bit of plumbing to get
    //  that to work.
    // 
    //------------------------------------------------------------------
    
    //------------------------------------------------------------------
    /// Adds a callback to the breakpoint option set.
    ///
    /// @param[in] callback
    ///    The function to be called when the breakpoint gets hit.
    ///
    /// @param[in] baton_sp
    ///    A baton which will get passed back to the callback when it is invoked.
    ///
    /// @param[in] synchronous
    ///    Whether this is a synchronous or asynchronous callback.  See discussion above.
    //------------------------------------------------------------------
    void SetCallback (BreakpointHitCallback callback, const lldb::BatonSP &baton_sp, bool synchronous = false);
    
    
    //------------------------------------------------------------------
    /// Remove the callback from this option set.
    //------------------------------------------------------------------
    void ClearCallback ();

    // The rest of these functions are meant to be used only within the breakpoint handling mechanism.
    
    //------------------------------------------------------------------
    /// Use this function to invoke the callback for a specific stop.
    ///
    /// @param[in] context
    ///    The context in which the callback is to be invoked.  This includes the stop event, the
    ///    execution context of the stop (since you might hit the same breakpoint on multiple threads) and
    ///    whether we are currently executing synchronous or asynchronous callbacks.
    /// 
    /// @param[in] break_id
    ///    The breakpoint ID that owns this option set.
    ///
    /// @param[in] break_loc_id
    ///    The breakpoint location ID that owns this option set.
    ///
    /// @return
    ///     The callback return value.
    //------------------------------------------------------------------
    bool InvokeCallback (StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
    
    //------------------------------------------------------------------
    /// Used in InvokeCallback to tell whether it is the right time to run this kind of callback.
    ///
    /// @return
    ///     The synchronicity of our callback.
    //------------------------------------------------------------------
    bool IsCallbackSynchronous () const
    {
        return m_callback_is_synchronous;
    }
    
    //------------------------------------------------------------------
    /// Fetch the baton from the callback.
    ///
    /// @return
    ///     The baton.
    //------------------------------------------------------------------
    Baton *GetBaton ();
    
    //------------------------------------------------------------------
    /// Fetch  a const version of the baton from the callback.
    ///
    /// @return
    ///     The baton.
    //------------------------------------------------------------------
    const Baton *GetBaton () const;
    
    //------------------------------------------------------------------
    // Condition
    //------------------------------------------------------------------
    //------------------------------------------------------------------
    /// Set the breakpoint option's condition.
    ///
    /// @param[in] condition
    ///    The condition expression to evaluate when the breakpoint is hit.
    //------------------------------------------------------------------
    void SetCondition (const char *condition);
    
    //------------------------------------------------------------------
    /// Return a pointer to the text of the condition expression.
    ///
    /// @return
    ///    A pointer to the condition expression text, or NULL if no
    //     condition has been set.
    //------------------------------------------------------------------
    const char *GetConditionText (size_t *hash = NULL) const;
    
    //------------------------------------------------------------------
    // Enabled/Ignore Count
    //------------------------------------------------------------------

    //------------------------------------------------------------------
    /// Check the Enable/Disable state.
    /// @return
    ///     \b true if the breakpoint is enabled, \b false if disabled.
    //------------------------------------------------------------------
    bool         
    IsEnabled () const
    {
        return m_enabled;
    }

    //------------------------------------------------------------------
    /// If \a enable is \b true, enable the breakpoint, if \b false disable it.
    //------------------------------------------------------------------
    void
    SetEnabled (bool enabled)
    {
        m_enabled = enabled;
    }

    //------------------------------------------------------------------
    /// Check the One-shot state.
    /// @return
    ///     \b true if the breakpoint is one-shot, \b false otherwise.
    //------------------------------------------------------------------
    bool         
    IsOneShot () const
    {
        return m_one_shot;
    }

    //------------------------------------------------------------------
    /// If \a enable is \b true, enable the breakpoint, if \b false disable it.
    //------------------------------------------------------------------
    void
    SetOneShot (bool one_shot)
    {
        m_one_shot = one_shot;
    }

    //------------------------------------------------------------------
    /// Set the breakpoint to ignore the next \a count breakpoint hits.
    /// @param[in] count
    ///    The number of breakpoint hits to ignore.
    //------------------------------------------------------------------

    void
    SetIgnoreCount (uint32_t n)
    {
        m_ignore_count = n;
    }

    //------------------------------------------------------------------
    /// Return the current Ignore Count.
    /// @return
    ///     The number of breakpoint hits to be ignored.
    //------------------------------------------------------------------
    uint32_t
    GetIgnoreCount () const
    {
        return m_ignore_count;
    }

    //------------------------------------------------------------------
    /// Return the current thread spec for this option.  This will return NULL if the no thread
    /// specifications have been set for this Option yet.     
    /// @return
    ///     The thread specification pointer for this option, or NULL if none has
    ///     been set yet.
    //------------------------------------------------------------------
    const ThreadSpec *
    GetThreadSpecNoCreate () const;

    //------------------------------------------------------------------
    /// Returns a pointer to the ThreadSpec for this option, creating it.
    /// if it hasn't been created already.   This API is used for setting the
    /// ThreadSpec items for this option.
    //------------------------------------------------------------------
    ThreadSpec *
    GetThreadSpec ();
    
    void
    SetThreadID(lldb::tid_t thread_id);
    
    void
    GetDescription (Stream *s, lldb::DescriptionLevel level) const;
    
    //------------------------------------------------------------------
    /// Returns true if the breakpoint option has a callback set.
    //------------------------------------------------------------------
    bool
    HasCallback() const;

    //------------------------------------------------------------------
    /// This is the default empty callback.
    /// @return
    ///     The thread id for which the breakpoint hit will stop, 
    ///     LLDB_INVALID_THREAD_ID for all threads.
    //------------------------------------------------------------------
    static bool 
    NullCallback (void *baton, 
                  StoppointCallbackContext *context, 
                  lldb::user_id_t break_id,
                  lldb::user_id_t break_loc_id);
    
    
    struct CommandData
    {
        CommandData () :
            user_source(),
            script_source(),
            stop_on_error(true)
        {
        }

        ~CommandData ()
        {
        }
        
        StringList user_source;
        std::string script_source;
        bool stop_on_error;
    };

    class CommandBaton : public Baton
    {
    public:
        CommandBaton (CommandData *data) :
            Baton (data)
        {
        }

        virtual
        ~CommandBaton ()
        {
            delete ((CommandData *)m_data);
            m_data = NULL;
        }
        
        virtual void
        GetDescription (Stream *s, lldb::DescriptionLevel level) const;

    };

protected:
    //------------------------------------------------------------------
    // Classes that inherit from BreakpointOptions can see and modify these
    //------------------------------------------------------------------

private:
    //------------------------------------------------------------------
    // For BreakpointOptions only
    //------------------------------------------------------------------
    BreakpointHitCallback m_callback; // This is the callback function pointer
    lldb::BatonSP m_callback_baton_sp; // This is the client data for the callback
    bool m_callback_is_synchronous;
    bool m_enabled;
    bool m_one_shot;
    uint32_t m_ignore_count; // Number of times to ignore this breakpoint
    std::unique_ptr<ThreadSpec> m_thread_spec_ap; // Thread for which this breakpoint will take
    std::string m_condition_text;  // The condition to test.
    size_t m_condition_text_hash; // Its hash, so that locations know when the condition is updated.
};

} // namespace lldb_private

#endif  // liblldb_BreakpointOptions_h_