BreakpointList.cpp revision 263367
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
18using namespace lldb;
19using namespace lldb_private;
20
21BreakpointList::BreakpointList (bool is_internal) :
22    m_mutex (Mutex::eMutexTypeRecursive),
23    m_breakpoints(),
24    m_next_break_id (0),
25    m_is_internal (is_internal)
26{
27}
28
29BreakpointList::~BreakpointList()
30{
31}
32
33
34break_id_t
35BreakpointList::Add (BreakpointSP &bp_sp, bool notify)
36{
37    Mutex::Locker locker(m_mutex);
38    // Internal breakpoint IDs are negative, normal ones are positive
39    bp_sp->SetID (m_is_internal ? --m_next_break_id : ++m_next_break_id);
40
41    m_breakpoints.push_back(bp_sp);
42    if (notify)
43    {
44        if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
45            bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
46                                               new Breakpoint::BreakpointEventData (eBreakpointEventTypeAdded, bp_sp));
47    }
48    return bp_sp->GetID();
49}
50
51bool
52BreakpointList::Remove (break_id_t break_id, bool notify)
53{
54    Mutex::Locker locker(m_mutex);
55    bp_collection::iterator pos = GetBreakpointIDIterator(break_id);    // Predicate
56    if (pos != m_breakpoints.end())
57    {
58        BreakpointSP bp_sp (*pos);
59        m_breakpoints.erase(pos);
60        if (notify)
61        {
62            if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
63                bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
64                                                   new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved, bp_sp));
65        }
66        return true;
67    }
68    return false;
69}
70
71void
72BreakpointList::RemoveInvalidLocations (const ArchSpec &arch)
73{
74    Mutex::Locker locker(m_mutex);
75    for (const auto &bp_sp : m_breakpoints)
76        bp_sp->RemoveInvalidLocations(arch);
77}
78
79
80void
81BreakpointList::SetEnabledAll (bool enabled)
82{
83    Mutex::Locker locker(m_mutex);
84    for (const auto &bp_sp : m_breakpoints)
85        bp_sp->SetEnabled (enabled);
86}
87
88
89void
90BreakpointList::RemoveAll (bool notify)
91{
92    Mutex::Locker locker(m_mutex);
93    ClearAllBreakpointSites ();
94
95    if (notify)
96    {
97        bp_collection::iterator pos, end = m_breakpoints.end();
98        for (pos = m_breakpoints.begin(); pos != end; ++pos)
99        {
100            if ((*pos)->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
101            {
102                (*pos)->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
103                                                    new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved,
104                                                                                         *pos));
105            }
106        }
107    }
108    m_breakpoints.erase (m_breakpoints.begin(), m_breakpoints.end());
109}
110
111class BreakpointIDMatches
112{
113public:
114    BreakpointIDMatches (break_id_t break_id) :
115        m_break_id(break_id)
116    {
117    }
118
119    bool operator() (const BreakpointSP &bp) const
120    {
121        return m_break_id == bp->GetID();
122    }
123
124private:
125   const break_id_t m_break_id;
126};
127
128BreakpointList::bp_collection::iterator
129BreakpointList::GetBreakpointIDIterator (break_id_t break_id)
130{
131    return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
132                        BreakpointIDMatches(break_id));             // Predicate
133}
134
135BreakpointList::bp_collection::const_iterator
136BreakpointList::GetBreakpointIDConstIterator (break_id_t break_id) const
137{
138    return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
139                        BreakpointIDMatches(break_id));             // Predicate
140}
141
142BreakpointSP
143BreakpointList::FindBreakpointByID (break_id_t break_id)
144{
145    Mutex::Locker locker(m_mutex);
146    BreakpointSP stop_sp;
147    bp_collection::iterator pos = GetBreakpointIDIterator(break_id);
148    if (pos != m_breakpoints.end())
149        stop_sp = *pos;
150
151    return stop_sp;
152}
153
154const BreakpointSP
155BreakpointList::FindBreakpointByID (break_id_t break_id) const
156{
157    Mutex::Locker locker(m_mutex);
158    BreakpointSP stop_sp;
159    bp_collection::const_iterator pos = GetBreakpointIDConstIterator(break_id);
160    if (pos != m_breakpoints.end())
161        stop_sp = *pos;
162
163    return stop_sp;
164}
165
166void
167BreakpointList::Dump (Stream *s) const
168{
169    Mutex::Locker locker(m_mutex);
170    s->Printf("%p: ", this);
171    s->Indent();
172    s->Printf("BreakpointList with %u Breakpoints:\n", (uint32_t)m_breakpoints.size());
173    s->IndentMore();
174    for (const auto &bp_sp : m_breakpoints)
175        bp_sp->Dump(s);
176    s->IndentLess();
177}
178
179
180BreakpointSP
181BreakpointList::GetBreakpointAtIndex (size_t i)
182{
183    Mutex::Locker locker(m_mutex);
184    BreakpointSP stop_sp;
185    bp_collection::iterator end = m_breakpoints.end();
186    bp_collection::iterator pos;
187    size_t curr_i = 0;
188    for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
189    {
190        if (curr_i == i)
191            stop_sp = *pos;
192    }
193    return stop_sp;
194}
195
196const BreakpointSP
197BreakpointList::GetBreakpointAtIndex (size_t i) const
198{
199    Mutex::Locker locker(m_mutex);
200    BreakpointSP stop_sp;
201    bp_collection::const_iterator end = m_breakpoints.end();
202    bp_collection::const_iterator pos;
203    size_t curr_i = 0;
204    for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
205    {
206        if (curr_i == i)
207            stop_sp = *pos;
208    }
209    return stop_sp;
210}
211
212void
213BreakpointList::UpdateBreakpoints (ModuleList& module_list, bool added, bool delete_locations)
214{
215    Mutex::Locker locker(m_mutex);
216    for (const auto &bp_sp : m_breakpoints)
217        bp_sp->ModulesChanged (module_list, added, delete_locations);
218
219}
220
221void
222BreakpointList::UpdateBreakpointsWhenModuleIsReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
223{
224    Mutex::Locker locker(m_mutex);
225    for (const auto &bp_sp : m_breakpoints)
226        bp_sp->ModuleReplaced (old_module_sp, new_module_sp);
227
228}
229
230void
231BreakpointList::ClearAllBreakpointSites ()
232{
233    Mutex::Locker locker(m_mutex);
234    for (const auto &bp_sp : m_breakpoints)
235        bp_sp->ClearAllBreakpointSites ();
236
237}
238
239void
240BreakpointList::GetListMutex (Mutex::Locker &locker)
241{
242    return locker.Lock (m_mutex);
243}
244