Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Breakpoint/BreakpointList.cpp
39587 views
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
9
#include "lldb/Breakpoint/BreakpointList.h"
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
auto event_data_sp =
22
std::make_shared<Breakpoint::BreakpointEventData>(event, bp);
23
target.BroadcastEvent(Target::eBroadcastBitBreakpointChanged,
24
event_data_sp);
25
}
26
}
27
28
BreakpointList::BreakpointList(bool is_internal)
29
: m_next_break_id(0), m_is_internal(is_internal) {}
30
31
BreakpointList::~BreakpointList() = default;
32
33
break_id_t BreakpointList::Add(BreakpointSP &bp_sp, bool notify) {
34
std::lock_guard<std::recursive_mutex> guard(m_mutex);
35
36
// Internal breakpoint IDs are negative, normal ones are positive
37
bp_sp->SetID(m_is_internal ? --m_next_break_id : ++m_next_break_id);
38
39
m_breakpoints.push_back(bp_sp);
40
41
if (notify)
42
NotifyChange(bp_sp, eBreakpointEventTypeAdded);
43
44
return bp_sp->GetID();
45
}
46
47
bool BreakpointList::Remove(break_id_t break_id, bool notify) {
48
std::lock_guard<std::recursive_mutex> guard(m_mutex);
49
50
auto it = std::find_if(
51
m_breakpoints.begin(), m_breakpoints.end(),
52
[&](const BreakpointSP &bp) { return bp->GetID() == break_id; });
53
54
if (it == m_breakpoints.end())
55
return false;
56
57
if (notify)
58
NotifyChange(*it, eBreakpointEventTypeRemoved);
59
60
m_breakpoints.erase(it);
61
62
return true;
63
}
64
65
void BreakpointList::RemoveInvalidLocations(const ArchSpec &arch) {
66
std::lock_guard<std::recursive_mutex> guard(m_mutex);
67
for (const auto &bp_sp : m_breakpoints)
68
bp_sp->RemoveInvalidLocations(arch);
69
}
70
71
void BreakpointList::SetEnabledAll(bool enabled) {
72
std::lock_guard<std::recursive_mutex> guard(m_mutex);
73
for (const auto &bp_sp : m_breakpoints)
74
bp_sp->SetEnabled(enabled);
75
}
76
77
void BreakpointList::SetEnabledAllowed(bool enabled) {
78
std::lock_guard<std::recursive_mutex> guard(m_mutex);
79
for (const auto &bp_sp : m_breakpoints)
80
if (bp_sp->AllowDisable())
81
bp_sp->SetEnabled(enabled);
82
}
83
84
void BreakpointList::RemoveAll(bool notify) {
85
std::lock_guard<std::recursive_mutex> guard(m_mutex);
86
ClearAllBreakpointSites();
87
88
if (notify) {
89
for (const auto &bp_sp : m_breakpoints)
90
NotifyChange(bp_sp, eBreakpointEventTypeRemoved);
91
}
92
93
m_breakpoints.clear();
94
}
95
96
void BreakpointList::RemoveAllowed(bool notify) {
97
std::lock_guard<std::recursive_mutex> guard(m_mutex);
98
99
for (const auto &bp_sp : m_breakpoints) {
100
if (bp_sp->AllowDelete())
101
bp_sp->ClearAllBreakpointSites();
102
if (notify)
103
NotifyChange(bp_sp, eBreakpointEventTypeRemoved);
104
}
105
106
llvm::erase_if(m_breakpoints,
107
[&](const BreakpointSP &bp) { return bp->AllowDelete(); });
108
}
109
110
BreakpointList::bp_collection::iterator
111
BreakpointList::GetBreakpointIDIterator(break_id_t break_id) {
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
118
BreakpointList::GetBreakpointIDConstIterator(break_id_t break_id) const {
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>>
134
BreakpointList::FindBreakpointsByName(const char *name) {
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
179
void BreakpointList::UpdateBreakpointsWhenModuleIsReplaced(
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
186
void BreakpointList::ClearAllBreakpointSites() {
187
std::lock_guard<std::recursive_mutex> guard(m_mutex);
188
for (const auto &bp_sp : m_breakpoints)
189
bp_sp->ClearAllBreakpointSites();
190
}
191
192
void BreakpointList::ResetHitCounts() {
193
std::lock_guard<std::recursive_mutex> guard(m_mutex);
194
for (const auto &bp_sp : m_breakpoints)
195
bp_sp->ResetHitCount();
196
}
197
198
void BreakpointList::GetListMutex(
199
std::unique_lock<std::recursive_mutex> &lock) {
200
lock = std::unique_lock<std::recursive_mutex>(m_mutex);
201
}
202
203