1//===-- BreakpointList.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 liblldb_BreakpointList_h_
10#define liblldb_BreakpointList_h_
11
12#include <list>
13#include <mutex>
14
15#include "lldb/Breakpoint/Breakpoint.h"
16
17namespace lldb_private {
18
19/// \class BreakpointList BreakpointList.h "lldb/Breakpoint/BreakpointList.h"
20/// This class manages a list of breakpoints.
21
22/// General Outline:
23/// Allows adding and removing breakpoints and find by ID and index.
24
25class BreakpointList {
26public:
27  BreakpointList(bool is_internal);
28
29  ~BreakpointList();
30
31  /// Add the breakpoint \a bp_sp to the list.
32  ///
33  /// \param[in] bp_sp
34  ///   Shared pointer to the breakpoint that will get added to the list.
35  ///
36  /// \result
37  ///   Returns breakpoint id.
38  lldb::break_id_t Add(lldb::BreakpointSP &bp_sp, bool notify);
39
40  /// Standard "Dump" method.  At present it does nothing.
41  void Dump(Stream *s) const;
42
43  /// Returns a shared pointer to the breakpoint with id \a breakID.  Const
44  /// version.
45  ///
46  /// \param[in] breakID
47  ///   The breakpoint ID to seek for.
48  ///
49  /// \result
50  ///   A shared pointer to the breakpoint.  May contain a NULL pointer if the
51  ///   breakpoint doesn't exist.
52  lldb::BreakpointSP FindBreakpointByID(lldb::break_id_t breakID) const;
53
54  /// Returns a shared pointer to the breakpoint with index \a i.
55  ///
56  /// \param[in] i
57  ///   The breakpoint index to seek for.
58  ///
59  /// \result
60  ///   A shared pointer to the breakpoint.  May contain a NULL pointer if the
61  ///   breakpoint doesn't exist.
62  lldb::BreakpointSP GetBreakpointAtIndex(size_t i) const;
63
64  /// Find all the breakpoints with a given name
65  ///
66  /// \param[in] name
67  ///   The breakpoint name for which to search.
68  ///
69  /// \result
70  ///   error if the input name was not a legal breakpoint name, vector
71  ///   of breakpoints otherwise.
72  llvm::Expected<std::vector<lldb::BreakpointSP>>
73  FindBreakpointsByName(const char *name);
74
75  /// Returns the number of elements in this breakpoint list.
76  ///
77  /// \result
78  ///   The number of elements.
79  size_t GetSize() const {
80    std::lock_guard<std::recursive_mutex> guard(m_mutex);
81    return m_breakpoints.size();
82  }
83
84  /// Removes the breakpoint given by \b breakID from this list.
85  ///
86  /// \param[in] breakID
87  ///   The breakpoint index to remove.
88  ///
89  /// \result
90  ///   \b true if the breakpoint \a breakID was in the list.
91  bool Remove(lldb::break_id_t breakID, bool notify);
92
93  /// Removes all invalid breakpoint locations.
94  ///
95  /// Removes all breakpoint locations in the list with architectures that
96  /// aren't compatible with \a arch. Also remove any breakpoint locations
97  /// with whose locations have address where the section has been deleted
98  /// (module and object files no longer exist).
99  ///
100  /// This is typically used after the process calls exec, or anytime the
101  /// architecture of the target changes.
102  ///
103  /// \param[in] arch
104  ///     If valid, check the module in each breakpoint to make sure
105  ///     they are compatible, otherwise, ignore architecture.
106  void RemoveInvalidLocations(const ArchSpec &arch);
107
108  void SetEnabledAll(bool enabled);
109
110  void SetEnabledAllowed(bool enabled);
111
112  /// Removes all the breakpoints from this list.
113  void RemoveAll(bool notify);
114
115  /// Removes all the breakpoints from this list - first checking the
116  /// ePermDelete on the breakpoints.  This call should be used unless you are
117  /// shutting down and need to actually clear them all.
118  void RemoveAllowed(bool notify);
119
120  /// Tell all the breakpoints to update themselves due to a change in the
121  /// modules in \a module_list.  \a added says whether the module was loaded
122  /// or unloaded.
123  ///
124  /// \param[in] module_list
125  ///   The module list that has changed.
126  ///
127  /// \param[in] load
128  ///   \b true if the modules are loaded, \b false if unloaded.
129  ///
130  /// \param[in] delete_locations
131  ///   If \a load is \b false, then delete breakpoint locations when
132  ///   when updating breakpoints.
133  void UpdateBreakpoints(ModuleList &module_list, bool load,
134                         bool delete_locations);
135
136  void UpdateBreakpointsWhenModuleIsReplaced(lldb::ModuleSP old_module_sp,
137                                             lldb::ModuleSP new_module_sp);
138
139  void ClearAllBreakpointSites();
140
141  /// Sets the passed in Locker to hold the Breakpoint List mutex.
142  ///
143  /// \param[in] lock
144  ///   The locker object that is set.
145  void GetListMutex(std::unique_lock<std::recursive_mutex> &lock);
146
147protected:
148  typedef std::vector<lldb::BreakpointSP> bp_collection;
149
150  bp_collection::iterator GetBreakpointIDIterator(lldb::break_id_t breakID);
151
152  bp_collection::const_iterator
153  GetBreakpointIDConstIterator(lldb::break_id_t breakID) const;
154
155  std::recursive_mutex &GetMutex() const { return m_mutex; }
156
157  mutable std::recursive_mutex m_mutex;
158  bp_collection m_breakpoints;
159  lldb::break_id_t m_next_break_id;
160  bool m_is_internal;
161
162public:
163  typedef LockingAdaptedIterable<bp_collection, lldb::BreakpointSP,
164                                 list_adapter, std::recursive_mutex>
165      BreakpointIterable;
166  BreakpointIterable Breakpoints() {
167    return BreakpointIterable(m_breakpoints, GetMutex());
168  }
169
170private:
171  DISALLOW_COPY_AND_ASSIGN(BreakpointList);
172};
173
174} // namespace lldb_private
175
176#endif // liblldb_BreakpointList_h_
177