aboutsummaryrefslogtreecommitdiffstats
path: root/include/lldb/Breakpoint/BreakpointLocation.h
blob: 7b27160563a08520b16f576649016066c486bcd4 (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
//===-- BreakpointLocation.h ------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_BreakpointLocation_h_
#define liblldb_BreakpointLocation_h_

#include <memory>
#include <mutex>

#include "lldb/Breakpoint/BreakpointOptions.h"
#include "lldb/Breakpoint/StoppointLocation.h"
#include "lldb/Core/Address.h"
#include "lldb/Utility/UserID.h"
#include "lldb/lldb-private.h"

namespace lldb_private {

/// \class BreakpointLocation BreakpointLocation.h
/// "lldb/Breakpoint/BreakpointLocation.h" Class that manages one unique (by
/// address) instance of a logical breakpoint.

/// General Outline:
/// A breakpoint location is defined by the breakpoint that produces it,
/// and the address that resulted in this particular instantiation. Each
/// breakpoint location also may have a breakpoint site if its address has
/// been loaded into the program. Finally it has a settable options object.
///
/// FIXME: Should we also store some fingerprint for the location, so
/// we can map one location to the "equivalent location" on rerun?  This would
/// be useful if you've set options on the locations.

class BreakpointLocation
    : public std::enable_shared_from_this<BreakpointLocation>,
      public StoppointLocation {
public:
  ~BreakpointLocation() override;

  /// Gets the load address for this breakpoint location \return
  ///     Returns breakpoint location load address, \b
  ///     LLDB_INVALID_ADDRESS if not yet set.
  lldb::addr_t GetLoadAddress() const override;

  /// Gets the Address for this breakpoint location \return
  ///     Returns breakpoint location Address.
  Address &GetAddress();
  /// Gets the Breakpoint that created this breakpoint location \return
  ///     Returns the owning breakpoint.
  Breakpoint &GetBreakpoint();

  Target &GetTarget();

  /// Determines whether we should stop due to a hit at this breakpoint
  /// location.
  ///
  /// Side Effects: This may evaluate the breakpoint condition, and run the
  /// callback.  So this command may do a considerable amount of work.
  ///
  /// \return
  ///     \b true if this breakpoint location thinks we should stop,
  ///     \b false otherwise.
  bool ShouldStop(StoppointCallbackContext *context) override;

  // The next section deals with various breakpoint options.

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

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

  /// If \a auto_continue is \b true, set the breakpoint to continue when hit.
  void SetAutoContinue(bool auto_continue);

  /// Check the AutoContinue state.
  ///
  /// \return
  ///     \b true if the breakpoint is set to auto-continue, \b false if not.
  bool IsAutoContinue() const;

  /// Return the current Ignore Count.
  ///
  /// \return
  ///     The number of breakpoint hits to be ignored.
  uint32_t GetIgnoreCount();

  /// 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);

  /// Set the callback action invoked when the breakpoint is hit.
  ///
  /// The callback will return a bool indicating whether the target should
  /// stop at this breakpoint or not.
  ///
  /// \param[in] callback
  ///     The method that will get called when the breakpoint is hit.
  ///
  /// \param[in] callback_baton_sp
  ///     A shared pointer to a Baton that provides the void * needed
  ///     for the callback.
  ///
  /// \see lldb_private::Baton
  void SetCallback(BreakpointHitCallback callback,
                   const lldb::BatonSP &callback_baton_sp, bool is_synchronous);

  void SetCallback(BreakpointHitCallback callback, void *baton,
                   bool is_synchronous);

  void ClearCallback();

  /// Set the breakpoint location'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 nullptr if no
  //     condition has been set.
  const char *GetConditionText(size_t *hash = nullptr) const;

  bool ConditionSaysStop(ExecutionContext &exe_ctx, Status &error);

  /// Set the valid thread to be checked when the breakpoint is hit.
  ///
  /// \param[in] thread_id
  ///    If this thread hits the breakpoint, we stop, otherwise not.
  void SetThreadID(lldb::tid_t thread_id);

  lldb::tid_t GetThreadID();

  void SetThreadIndex(uint32_t index);

  uint32_t GetThreadIndex() const;

  void SetThreadName(const char *thread_name);

  const char *GetThreadName() const;

  void SetQueueName(const char *queue_name);

  const char *GetQueueName() const;

  // The next section deals with this location's breakpoint sites.

  /// Try to resolve the breakpoint site for this location.
  ///
  /// \return
  ///     \b true if we were successful at setting a breakpoint site,
  ///     \b false otherwise.
  bool ResolveBreakpointSite();

  /// Clear this breakpoint location's breakpoint site - for instance when
  /// disabling the breakpoint.
  ///
  /// \return
  ///     \b true if there was a breakpoint site to be cleared, \b false
  ///     otherwise.
  bool ClearBreakpointSite();

  /// Return whether this breakpoint location has a breakpoint site. \return
  ///     \b true if there was a breakpoint site for this breakpoint
  ///     location, \b false otherwise.
  bool IsResolved() const;

  lldb::BreakpointSiteSP GetBreakpointSite() const;

  // The next section are generic report functions.

  /// Print a description of this breakpoint location to the stream \a s.
  ///
  /// \param[in] s
  ///     The stream to which to print the description.
  ///
  /// \param[in] level
  ///     The description level that indicates the detail level to
  ///     provide.
  ///
  /// \see lldb::DescriptionLevel
  void GetDescription(Stream *s, lldb::DescriptionLevel level);

  /// Standard "Dump" method.  At present it does nothing.
  void Dump(Stream *s) const override;

  /// Use this to set location specific breakpoint options.
  ///
  /// It will create a copy of the containing breakpoint's options if that
  /// hasn't been done already
  ///
  /// \return
  ///    A pointer to the breakpoint options.
  BreakpointOptions *GetLocationOptions();

  /// Use this to access breakpoint options from this breakpoint location.
  /// This will return the options that have a setting for the specified
  /// BreakpointOptions kind.
  ///
  /// \param[in] kind
  ///     The particular option you are looking up.
  /// \return
  ///     A pointer to the containing breakpoint's options if this
  ///     location doesn't have its own copy.
  const BreakpointOptions *GetOptionsSpecifyingKind(
      BreakpointOptions::OptionKind kind) const;

  bool ValidForThisThread(Thread *thread);

  /// Invoke the callback action when the breakpoint is hit.
  ///
  /// Meant to be used by the BreakpointLocation class.
  ///
  /// \param[in] context
  ///    Described the breakpoint event.
  ///
  /// \param[in] bp_loc_id
  ///    Which breakpoint location hit this breakpoint.
  ///
  /// \return
  ///     \b true if the target should stop at this breakpoint and \b
  ///     false not.
  bool InvokeCallback(StoppointCallbackContext *context);

  /// Returns whether we should resolve Indirect functions in setting the
  /// breakpoint site for this location.
  ///
  /// \return
  ///     \b true if the breakpoint SITE for this location should be set on the
  ///     resolved location for Indirect functions.
  bool ShouldResolveIndirectFunctions() {
    return m_should_resolve_indirect_functions;
  }

  /// Returns whether the address set in the breakpoint site for this location
  /// was found by resolving an indirect symbol.
  ///
  /// \return
  ///     \b true or \b false as given in the description above.
  bool IsIndirect() { return m_is_indirect; }

  void SetIsIndirect(bool is_indirect) { m_is_indirect = is_indirect; }

  /// Returns whether the address set in the breakpoint location was re-routed
  /// to the target of a re-exported symbol.
  ///
  /// \return
  ///     \b true or \b false as given in the description above.
  bool IsReExported() { return m_is_reexported; }

  void SetIsReExported(bool is_reexported) { m_is_reexported = is_reexported; }

  /// Returns whether the two breakpoint locations might represent "equivalent
  /// locations". This is used when modules changed to determine if a Location
  /// in the old module might be the "same as" the input location.
  ///
  /// \param[in] location
  ///    The location to compare against.
  ///
  /// \return
  ///     \b true or \b false as given in the description above.
  bool EquivalentToLocation(BreakpointLocation &location);

protected:
  friend class BreakpointSite;
  friend class BreakpointLocationList;
  friend class Process;
  friend class StopInfoBreakpoint;

  /// Set the breakpoint site for this location to \a bp_site_sp.
  ///
  /// \param[in] bp_site_sp
  ///      The breakpoint site we are setting for this location.
  ///
  /// \return
  ///     \b true if we were successful at setting the breakpoint site,
  ///     \b false otherwise.
  bool SetBreakpointSite(lldb::BreakpointSiteSP &bp_site_sp);

  void DecrementIgnoreCount();

  bool IgnoreCountShouldStop();

private:
  void SwapLocation(lldb::BreakpointLocationSP swap_from);

  void BumpHitCount();

  void UndoBumpHitCount();

  // Constructors and Destructors
  //
  // Only the Breakpoint can make breakpoint locations, and it owns them.

  /// Constructor.
  ///
  /// \param[in] owner
  ///     A back pointer to the breakpoint that owns this location.
  ///
  /// \param[in] addr
  ///     The Address defining this location.
  ///
  /// \param[in] tid
  ///     The thread for which this breakpoint location is valid, or
  ///     LLDB_INVALID_THREAD_ID if it is valid for all threads.
  ///
  /// \param[in] hardware
  ///     \b true if a hardware breakpoint is requested.

  BreakpointLocation(lldb::break_id_t bid, Breakpoint &owner,
                     const Address &addr, lldb::tid_t tid, bool hardware,
                     bool check_for_resolver = true);

  // Data members:
  bool m_being_created;
  bool m_should_resolve_indirect_functions;
  bool m_is_reexported;
  bool m_is_indirect;
  Address m_address;   ///< The address defining this location.
  Breakpoint &m_owner; ///< The breakpoint that produced this object.
  std::unique_ptr<BreakpointOptions> m_options_up; ///< Breakpoint options
                                                   /// pointer, nullptr if we're
                                                   /// using our breakpoint's
                                                   /// options.
  lldb::BreakpointSiteSP m_bp_site_sp; ///< Our breakpoint site (it may be
                                       ///shared by more than one location.)
  lldb::UserExpressionSP m_user_expression_sp; ///< The compiled expression to
                                               ///use in testing our condition.
  std::mutex m_condition_mutex; ///< Guards parsing and evaluation of the
                                ///condition, which could be evaluated by
                                /// multiple processes.
  size_t m_condition_hash; ///< For testing whether the condition source code
                           ///changed.

  void SetShouldResolveIndirectFunctions(bool do_resolve) {
    m_should_resolve_indirect_functions = do_resolve;
  }

  void SendBreakpointLocationChangedEvent(lldb::BreakpointEventType eventKind);

  DISALLOW_COPY_AND_ASSIGN(BreakpointLocation);
};

} // namespace lldb_private

#endif // liblldb_BreakpointLocation_h_