1 //===-- BreakpointList.cpp --------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Breakpoint/BreakpointList.h"
12 #include "lldb/Target/Target.h"
15 using namespace lldb_private;
17 static void NotifyChange(const BreakpointSP &bp, BreakpointEventType event) {
18 Target &target = bp->GetTarget();
19 if (target.EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
20 target.BroadcastEvent(Target::eBroadcastBitBreakpointChanged,
21 new Breakpoint::BreakpointEventData(event, bp));
24 BreakpointList::BreakpointList(bool is_internal)
25 : m_mutex(), m_breakpoints(), m_next_break_id(0),
26 m_is_internal(is_internal) {}
28 BreakpointList::~BreakpointList() {}
30 break_id_t BreakpointList::Add(BreakpointSP &bp_sp, bool notify) {
31 std::lock_guard<std::recursive_mutex> guard(m_mutex);
33 // Internal breakpoint IDs are negative, normal ones are positive
34 bp_sp->SetID(m_is_internal ? --m_next_break_id : ++m_next_break_id);
36 m_breakpoints.push_back(bp_sp);
39 NotifyChange(bp_sp, eBreakpointEventTypeAdded);
41 return bp_sp->GetID();
44 bool BreakpointList::Remove(break_id_t break_id, bool notify) {
45 std::lock_guard<std::recursive_mutex> guard(m_mutex);
47 auto it = std::find_if(
48 m_breakpoints.begin(), m_breakpoints.end(),
49 [&](const BreakpointSP &bp) { return bp->GetID() == break_id; });
51 if (it == m_breakpoints.end())
55 NotifyChange(*it, eBreakpointEventTypeRemoved);
57 m_breakpoints.erase(it);
62 void BreakpointList::RemoveInvalidLocations(const ArchSpec &arch) {
63 std::lock_guard<std::recursive_mutex> guard(m_mutex);
64 for (const auto &bp_sp : m_breakpoints)
65 bp_sp->RemoveInvalidLocations(arch);
68 void BreakpointList::SetEnabledAll(bool enabled) {
69 std::lock_guard<std::recursive_mutex> guard(m_mutex);
70 for (const auto &bp_sp : m_breakpoints)
71 bp_sp->SetEnabled(enabled);
74 void BreakpointList::SetEnabledAllowed(bool enabled) {
75 std::lock_guard<std::recursive_mutex> guard(m_mutex);
76 for (const auto &bp_sp : m_breakpoints)
77 if (bp_sp->AllowDisable())
78 bp_sp->SetEnabled(enabled);
81 void BreakpointList::RemoveAll(bool notify) {
82 std::lock_guard<std::recursive_mutex> guard(m_mutex);
83 ClearAllBreakpointSites();
86 for (const auto &bp_sp : m_breakpoints)
87 NotifyChange(bp_sp, eBreakpointEventTypeRemoved);
90 m_breakpoints.clear();
93 void BreakpointList::RemoveAllowed(bool notify) {
94 std::lock_guard<std::recursive_mutex> guard(m_mutex);
96 for (const auto &bp_sp : m_breakpoints) {
97 if (bp_sp->AllowDelete())
98 bp_sp->ClearAllBreakpointSites();
100 NotifyChange(bp_sp, eBreakpointEventTypeRemoved);
104 std::remove_if(m_breakpoints.begin(), m_breakpoints.end(),
105 [&](const BreakpointSP &bp) { return bp->AllowDelete(); }),
106 m_breakpoints.end());
109 BreakpointList::bp_collection::iterator
110 BreakpointList::GetBreakpointIDIterator(break_id_t break_id) {
112 m_breakpoints.begin(), m_breakpoints.end(),
113 [&](const BreakpointSP &bp) { return bp->GetID() == break_id; });
116 BreakpointList::bp_collection::const_iterator
117 BreakpointList::GetBreakpointIDConstIterator(break_id_t break_id) const {
119 m_breakpoints.begin(), m_breakpoints.end(),
120 [&](const BreakpointSP &bp) { return bp->GetID() == break_id; });
123 BreakpointSP BreakpointList::FindBreakpointByID(break_id_t break_id) const {
124 std::lock_guard<std::recursive_mutex> guard(m_mutex);
126 auto it = GetBreakpointIDConstIterator(break_id);
127 if (it != m_breakpoints.end())
132 bool BreakpointList::FindBreakpointsByName(const char *name,
133 BreakpointList &matching_bps) {
138 if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(name), error))
141 for (BreakpointSP bkpt_sp : Breakpoints()) {
142 if (bkpt_sp->MatchesName(name)) {
143 matching_bps.Add(bkpt_sp, false);
150 void BreakpointList::Dump(Stream *s) const {
151 std::lock_guard<std::recursive_mutex> guard(m_mutex);
152 s->Printf("%p: ", static_cast<const void *>(this));
154 s->Printf("BreakpointList with %u Breakpoints:\n",
155 (uint32_t)m_breakpoints.size());
157 for (const auto &bp_sp : m_breakpoints)
162 BreakpointSP BreakpointList::GetBreakpointAtIndex(size_t i) const {
163 std::lock_guard<std::recursive_mutex> guard(m_mutex);
164 if (i < m_breakpoints.size())
165 return m_breakpoints[i];
169 void BreakpointList::UpdateBreakpoints(ModuleList &module_list, bool added,
170 bool delete_locations) {
171 std::lock_guard<std::recursive_mutex> guard(m_mutex);
172 for (const auto &bp_sp : m_breakpoints)
173 bp_sp->ModulesChanged(module_list, added, delete_locations);
176 void BreakpointList::UpdateBreakpointsWhenModuleIsReplaced(
177 ModuleSP old_module_sp, ModuleSP new_module_sp) {
178 std::lock_guard<std::recursive_mutex> guard(m_mutex);
179 for (const auto &bp_sp : m_breakpoints)
180 bp_sp->ModuleReplaced(old_module_sp, new_module_sp);
183 void BreakpointList::ClearAllBreakpointSites() {
184 std::lock_guard<std::recursive_mutex> guard(m_mutex);
185 for (const auto &bp_sp : m_breakpoints)
186 bp_sp->ClearAllBreakpointSites();
189 void BreakpointList::GetListMutex(
190 std::unique_lock<std::recursive_mutex> &lock) {
191 lock = std::unique_lock<std::recursive_mutex>(m_mutex);