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 LLDB_BREAKPOINT_BREAKPOINTLIST_H
10 #define LLDB_BREAKPOINT_BREAKPOINTLIST_H
11 
12 #include <list>
13 #include <mutex>
14 
15 #include "lldb/Breakpoint/Breakpoint.h"
16 
17 namespace 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 
25 class BreakpointList {
26 public:
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.
GetSize()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   /// Resets the hit count of all breakpoints.
142   void ResetHitCounts();
143 
144   /// Sets the passed in Locker to hold the Breakpoint List mutex.
145   ///
146   /// \param[in] lock
147   ///   The locker object that is set.
148   void GetListMutex(std::unique_lock<std::recursive_mutex> &lock);
149 
150 protected:
151   typedef std::vector<lldb::BreakpointSP> bp_collection;
152 
153   bp_collection::iterator GetBreakpointIDIterator(lldb::break_id_t breakID);
154 
155   bp_collection::const_iterator
156   GetBreakpointIDConstIterator(lldb::break_id_t breakID) const;
157 
GetMutex()158   std::recursive_mutex &GetMutex() const { return m_mutex; }
159 
160   mutable std::recursive_mutex m_mutex;
161   bp_collection m_breakpoints;
162   lldb::break_id_t m_next_break_id;
163   bool m_is_internal;
164 
165 public:
166   typedef LockingAdaptedIterable<bp_collection, lldb::BreakpointSP,
167                                  list_adapter, std::recursive_mutex>
168       BreakpointIterable;
Breakpoints()169   BreakpointIterable Breakpoints() {
170     return BreakpointIterable(m_breakpoints, GetMutex());
171   }
172 
173 private:
174   BreakpointList(const BreakpointList &) = delete;
175   const BreakpointList &operator=(const BreakpointList &) = delete;
176 };
177 
178 } // namespace lldb_private
179 
180 #endif // LLDB_BREAKPOINT_BREAKPOINTLIST_H
181