]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Breakpoint/BreakpointList.cpp
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / source / Breakpoint / BreakpointList.cpp
1 //===-- BreakpointList.cpp --------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Breakpoint/BreakpointList.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Target/Target.h"
17
18 using namespace lldb;
19 using namespace lldb_private;
20
21 BreakpointList::BreakpointList(bool is_internal)
22     : m_mutex(), m_breakpoints(), m_next_break_id(0),
23       m_is_internal(is_internal) {}
24
25 BreakpointList::~BreakpointList() {}
26
27 break_id_t BreakpointList::Add(BreakpointSP &bp_sp, bool notify) {
28   std::lock_guard<std::recursive_mutex> guard(m_mutex);
29   // Internal breakpoint IDs are negative, normal ones are positive
30   bp_sp->SetID(m_is_internal ? --m_next_break_id : ++m_next_break_id);
31
32   m_breakpoints.push_back(bp_sp);
33   if (notify) {
34     if (bp_sp->GetTarget().EventTypeHasListeners(
35             Target::eBroadcastBitBreakpointChanged))
36       bp_sp->GetTarget().BroadcastEvent(Target::eBroadcastBitBreakpointChanged,
37                                         new Breakpoint::BreakpointEventData(
38                                             eBreakpointEventTypeAdded, bp_sp));
39   }
40   return bp_sp->GetID();
41 }
42
43 bool BreakpointList::Remove(break_id_t break_id, bool notify) {
44   std::lock_guard<std::recursive_mutex> guard(m_mutex);
45   bp_collection::iterator pos = GetBreakpointIDIterator(break_id); // Predicate
46   if (pos != m_breakpoints.end()) {
47     BreakpointSP bp_sp(*pos);
48     m_breakpoints.erase(pos);
49     if (notify) {
50       if (bp_sp->GetTarget().EventTypeHasListeners(
51               Target::eBroadcastBitBreakpointChanged))
52         bp_sp->GetTarget().BroadcastEvent(
53             Target::eBroadcastBitBreakpointChanged,
54             new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved,
55                                                 bp_sp));
56     }
57     return true;
58   }
59   return false;
60 }
61
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);
66 }
67
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);
72 }
73
74 void BreakpointList::RemoveAll(bool notify) {
75   std::lock_guard<std::recursive_mutex> guard(m_mutex);
76   ClearAllBreakpointSites();
77
78   if (notify) {
79     bp_collection::iterator pos, end = m_breakpoints.end();
80     for (pos = m_breakpoints.begin(); pos != end; ++pos) {
81       if ((*pos)->GetTarget().EventTypeHasListeners(
82               Target::eBroadcastBitBreakpointChanged)) {
83         (*pos)->GetTarget().BroadcastEvent(
84             Target::eBroadcastBitBreakpointChanged,
85             new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved,
86                                                 *pos));
87       }
88     }
89   }
90   m_breakpoints.erase(m_breakpoints.begin(), m_breakpoints.end());
91 }
92
93 class BreakpointIDMatches {
94 public:
95   BreakpointIDMatches(break_id_t break_id) : m_break_id(break_id) {}
96
97   bool operator()(const BreakpointSP &bp) const {
98     return m_break_id == bp->GetID();
99   }
100
101 private:
102   const break_id_t m_break_id;
103 };
104
105 BreakpointList::bp_collection::iterator
106 BreakpointList::GetBreakpointIDIterator(break_id_t break_id) {
107   return std::find_if(m_breakpoints.begin(),
108                       m_breakpoints.end(),            // Search full range
109                       BreakpointIDMatches(break_id)); // Predicate
110 }
111
112 BreakpointList::bp_collection::const_iterator
113 BreakpointList::GetBreakpointIDConstIterator(break_id_t break_id) const {
114   return std::find_if(m_breakpoints.begin(),
115                       m_breakpoints.end(),            // Search full range
116                       BreakpointIDMatches(break_id)); // Predicate
117 }
118
119 BreakpointSP BreakpointList::FindBreakpointByID(break_id_t break_id) {
120   std::lock_guard<std::recursive_mutex> guard(m_mutex);
121   BreakpointSP stop_sp;
122   bp_collection::iterator pos = GetBreakpointIDIterator(break_id);
123   if (pos != m_breakpoints.end())
124     stop_sp = *pos;
125
126   return stop_sp;
127 }
128
129 const BreakpointSP
130 BreakpointList::FindBreakpointByID(break_id_t break_id) const {
131   std::lock_guard<std::recursive_mutex> guard(m_mutex);
132   BreakpointSP stop_sp;
133   bp_collection::const_iterator pos = GetBreakpointIDConstIterator(break_id);
134   if (pos != m_breakpoints.end())
135     stop_sp = *pos;
136
137   return stop_sp;
138 }
139
140 bool BreakpointList::FindBreakpointsByName(const char *name,
141                                            BreakpointList &matching_bps) {
142   Error error;
143   if (!name)
144     return false;
145
146   if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(name), error))
147     return false;
148
149   for (BreakpointSP bkpt_sp : Breakpoints()) {
150     if (bkpt_sp->MatchesName(name)) {
151       matching_bps.Add(bkpt_sp, false);
152     }
153   }
154   return true;
155 }
156
157 void BreakpointList::Dump(Stream *s) const {
158   std::lock_guard<std::recursive_mutex> guard(m_mutex);
159   s->Printf("%p: ", static_cast<const void *>(this));
160   s->Indent();
161   s->Printf("BreakpointList with %u Breakpoints:\n",
162             (uint32_t)m_breakpoints.size());
163   s->IndentMore();
164   for (const auto &bp_sp : m_breakpoints)
165     bp_sp->Dump(s);
166   s->IndentLess();
167 }
168
169 BreakpointSP BreakpointList::GetBreakpointAtIndex(size_t i) {
170   std::lock_guard<std::recursive_mutex> guard(m_mutex);
171   BreakpointSP stop_sp;
172   bp_collection::iterator end = m_breakpoints.end();
173   bp_collection::iterator pos;
174   size_t curr_i = 0;
175   for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) {
176     if (curr_i == i)
177       stop_sp = *pos;
178   }
179   return stop_sp;
180 }
181
182 const BreakpointSP BreakpointList::GetBreakpointAtIndex(size_t i) const {
183   std::lock_guard<std::recursive_mutex> guard(m_mutex);
184   BreakpointSP stop_sp;
185   bp_collection::const_iterator end = m_breakpoints.end();
186   bp_collection::const_iterator pos;
187   size_t curr_i = 0;
188   for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) {
189     if (curr_i == i)
190       stop_sp = *pos;
191   }
192   return stop_sp;
193 }
194
195 void BreakpointList::UpdateBreakpoints(ModuleList &module_list, bool added,
196                                        bool delete_locations) {
197   std::lock_guard<std::recursive_mutex> guard(m_mutex);
198   for (const auto &bp_sp : m_breakpoints)
199     bp_sp->ModulesChanged(module_list, added, delete_locations);
200 }
201
202 void BreakpointList::UpdateBreakpointsWhenModuleIsReplaced(
203     ModuleSP old_module_sp, ModuleSP new_module_sp) {
204   std::lock_guard<std::recursive_mutex> guard(m_mutex);
205   for (const auto &bp_sp : m_breakpoints)
206     bp_sp->ModuleReplaced(old_module_sp, new_module_sp);
207 }
208
209 void BreakpointList::ClearAllBreakpointSites() {
210   std::lock_guard<std::recursive_mutex> guard(m_mutex);
211   for (const auto &bp_sp : m_breakpoints)
212     bp_sp->ClearAllBreakpointSites();
213 }
214
215 void BreakpointList::GetListMutex(
216     std::unique_lock<std::recursive_mutex> &lock) {
217   lock = std::unique_lock<std::recursive_mutex>(m_mutex);
218 }