LLDB  mainline
BreakpointList.cpp
Go to the documentation of this file.
1 //===-- BreakpointList.cpp ------------------------------------------------===//
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 
10 
11 #include "lldb/Target/Target.h"
12 
13 #include "llvm/Support/Errc.h"
14 
15 using namespace lldb;
16 using namespace lldb_private;
17 
18 static void NotifyChange(const BreakpointSP &bp, BreakpointEventType event) {
19  Target &target = bp->GetTarget();
20  if (target.EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
21  target.BroadcastEvent(Target::eBroadcastBitBreakpointChanged,
22  new Breakpoint::BreakpointEventData(event, bp));
23 }
24 
25 BreakpointList::BreakpointList(bool is_internal)
26  : m_mutex(), m_breakpoints(), m_next_break_id(0),
27  m_is_internal(is_internal) {}
28 
30 
31 break_id_t BreakpointList::Add(BreakpointSP &bp_sp, bool notify) {
32  std::lock_guard<std::recursive_mutex> guard(m_mutex);
33 
34  // Internal breakpoint IDs are negative, normal ones are positive
35  bp_sp->SetID(m_is_internal ? --m_next_break_id : ++m_next_break_id);
36 
37  m_breakpoints.push_back(bp_sp);
38 
39  if (notify)
40  NotifyChange(bp_sp, eBreakpointEventTypeAdded);
41 
42  return bp_sp->GetID();
43 }
44 
45 bool BreakpointList::Remove(break_id_t break_id, bool notify) {
46  std::lock_guard<std::recursive_mutex> guard(m_mutex);
47 
48  auto it = std::find_if(
49  m_breakpoints.begin(), m_breakpoints.end(),
50  [&](const BreakpointSP &bp) { return bp->GetID() == break_id; });
51 
52  if (it == m_breakpoints.end())
53  return false;
54 
55  if (notify)
56  NotifyChange(*it, eBreakpointEventTypeRemoved);
57 
58  m_breakpoints.erase(it);
59 
60  return true;
61 }
62 
64  std::lock_guard<std::recursive_mutex> guard(m_mutex);
65  for (const auto &bp_sp : m_breakpoints)
66  bp_sp->RemoveInvalidLocations(arch);
67 }
68 
69 void BreakpointList::SetEnabledAll(bool enabled) {
70  std::lock_guard<std::recursive_mutex> guard(m_mutex);
71  for (const auto &bp_sp : m_breakpoints)
72  bp_sp->SetEnabled(enabled);
73 }
74 
76  std::lock_guard<std::recursive_mutex> guard(m_mutex);
77  for (const auto &bp_sp : m_breakpoints)
78  if (bp_sp->AllowDisable())
79  bp_sp->SetEnabled(enabled);
80 }
81 
82 void BreakpointList::RemoveAll(bool notify) {
83  std::lock_guard<std::recursive_mutex> guard(m_mutex);
85 
86  if (notify) {
87  for (const auto &bp_sp : m_breakpoints)
88  NotifyChange(bp_sp, eBreakpointEventTypeRemoved);
89  }
90 
91  m_breakpoints.clear();
92 }
93 
94 void BreakpointList::RemoveAllowed(bool notify) {
95  std::lock_guard<std::recursive_mutex> guard(m_mutex);
96 
97  for (const auto &bp_sp : m_breakpoints) {
98  if (bp_sp->AllowDelete())
99  bp_sp->ClearAllBreakpointSites();
100  if (notify)
101  NotifyChange(bp_sp, eBreakpointEventTypeRemoved);
102  }
103 
104  m_breakpoints.erase(
105  std::remove_if(m_breakpoints.begin(), m_breakpoints.end(),
106  [&](const BreakpointSP &bp) { return bp->AllowDelete(); }),
107  m_breakpoints.end());
108 }
109 
110 BreakpointList::bp_collection::iterator
112  return std::find_if(
113  m_breakpoints.begin(), m_breakpoints.end(),
114  [&](const BreakpointSP &bp) { return bp->GetID() == break_id; });
115 }
116 
117 BreakpointList::bp_collection::const_iterator
119  return std::find_if(
120  m_breakpoints.begin(), m_breakpoints.end(),
121  [&](const BreakpointSP &bp) { return bp->GetID() == break_id; });
122 }
123 
124 BreakpointSP BreakpointList::FindBreakpointByID(break_id_t break_id) const {
125  std::lock_guard<std::recursive_mutex> guard(m_mutex);
126 
127  auto it = GetBreakpointIDConstIterator(break_id);
128  if (it != m_breakpoints.end())
129  return *it;
130  return {};
131 }
132 
133 llvm::Expected<std::vector<lldb::BreakpointSP>>
135  if (!name)
136  return llvm::createStringError(llvm::errc::invalid_argument,
137  "FindBreakpointsByName requires a name");
138 
139  Status error;
140  if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(name), error))
141  return error.ToError();
142 
143  std::vector<lldb::BreakpointSP> matching_bps;
144  for (BreakpointSP bkpt_sp : Breakpoints()) {
145  if (bkpt_sp->MatchesName(name)) {
146  matching_bps.push_back(bkpt_sp);
147  }
148  }
149 
150  return matching_bps;
151 }
152 
153 void BreakpointList::Dump(Stream *s) const {
154  std::lock_guard<std::recursive_mutex> guard(m_mutex);
155  s->Printf("%p: ", static_cast<const void *>(this));
156  s->Indent();
157  s->Printf("BreakpointList with %u Breakpoints:\n",
158  (uint32_t)m_breakpoints.size());
159  s->IndentMore();
160  for (const auto &bp_sp : m_breakpoints)
161  bp_sp->Dump(s);
162  s->IndentLess();
163 }
164 
165 BreakpointSP BreakpointList::GetBreakpointAtIndex(size_t i) const {
166  std::lock_guard<std::recursive_mutex> guard(m_mutex);
167  if (i < m_breakpoints.size())
168  return m_breakpoints[i];
169  return {};
170 }
171 
172 void BreakpointList::UpdateBreakpoints(ModuleList &module_list, bool added,
173  bool delete_locations) {
174  std::lock_guard<std::recursive_mutex> guard(m_mutex);
175  for (const auto &bp_sp : m_breakpoints)
176  bp_sp->ModulesChanged(module_list, added, delete_locations);
177 }
178 
180  ModuleSP old_module_sp, ModuleSP new_module_sp) {
181  std::lock_guard<std::recursive_mutex> guard(m_mutex);
182  for (const auto &bp_sp : m_breakpoints)
183  bp_sp->ModuleReplaced(old_module_sp, new_module_sp);
184 }
185 
187  std::lock_guard<std::recursive_mutex> guard(m_mutex);
188  for (const auto &bp_sp : m_breakpoints)
189  bp_sp->ClearAllBreakpointSites();
190 }
191 
193  std::unique_lock<std::recursive_mutex> &lock) {
194  lock = std::unique_lock<std::recursive_mutex>(m_mutex);
195 }
void IndentMore(unsigned amount=2)
Increment the current indentation level.
Definition: Stream.cpp:168
llvm::Error ToError() const
Definition: Status.cpp:90
lldb::break_id_t m_next_break_id
A class that represents a running process on the host machine.
int32_t break_id_t
Definition: lldb-types.h:88
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
void IndentLess(unsigned amount=2)
Decrement the current indentation level.
Definition: Stream.cpp:171
An architecture specification class.
Definition: ArchSpec.h:33
void SetEnabledAllowed(bool enabled)
llvm::Expected< std::vector< lldb::BreakpointSP > > FindBreakpointsByName(const char *name)
Find all the breakpoints with a given name.
void RemoveInvalidLocations(const ArchSpec &arch)
Removes all invalid breakpoint locations.
lldb::BreakpointSP FindBreakpointByID(lldb::break_id_t breakID) const
Returns a shared pointer to the breakpoint with id breakID.
void UpdateBreakpoints(ModuleList &module_list, bool load, bool delete_locations)
Tell all the breakpoints to update themselves due to a change in the modules in module_list.
void RemoveAll(bool notify)
Removes all the breakpoints from this list.
void BroadcastEvent(lldb::EventSP &event_sp)
Broadcast an event which has no associated data.
Definition: Broadcaster.h:262
lldb::break_id_t Add(lldb::BreakpointSP &bp_sp, bool notify)
Add the breakpoint bp_sp to the list.
bool Remove(lldb::break_id_t breakID, bool notify)
Removes the breakpoint given by breakID from this list.
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
Definition: Stream.cpp:130
void SetEnabledAll(bool enabled)
static llvm::raw_ostream & error(Stream &strm)
A collection class for Module objects.
Definition: ModuleList.h:71
void Dump(Stream *s) const
Standard "Dump" method. At present it does nothing.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
std::recursive_mutex m_mutex
void UpdateBreakpointsWhenModuleIsReplaced(lldb::ModuleSP old_module_sp, lldb::ModuleSP new_module_sp)
lldb::BreakpointSP GetBreakpointAtIndex(size_t i) const
Returns a shared pointer to the breakpoint with index i.
bool EventTypeHasListeners(uint32_t event_type)
Definition: Broadcaster.h:345
void RemoveAllowed(bool notify)
Removes all the breakpoints from this list - first checking the ePermDelete on the breakpoints...
static void NotifyChange(const BreakpointSP &bp, BreakpointEventType event)
Definition: SBAddress.h:15
void GetListMutex(std::unique_lock< std::recursive_mutex > &lock)
Sets the passed in Locker to hold the Breakpoint List mutex.
BreakpointIterable Breakpoints()
static bool StringIsBreakpointName(llvm::StringRef str, Status &error)
Takes an input string and checks to see whether it is a breakpoint name.
bp_collection::iterator GetBreakpointIDIterator(lldb::break_id_t breakID)
bp_collection::const_iterator GetBreakpointIDConstIterator(lldb::break_id_t breakID) const
An error handling class.
Definition: Status.h:44