BreakpointList.cpp revision 263363
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::SetEnabledAll (bool enabled)
73{
74    Mutex::Locker locker(m_mutex);
75    bp_collection::iterator pos, end = m_breakpoints.end();
76    for (pos = m_breakpoints.begin(); pos != end; ++pos)
77        (*pos)->SetEnabled (enabled);
78}
79
80
81void
82BreakpointList::RemoveAll (bool notify)
83{
84    Mutex::Locker locker(m_mutex);
85    ClearAllBreakpointSites ();
86
87    if (notify)
88    {
89        bp_collection::iterator pos, end = m_breakpoints.end();
90        for (pos = m_breakpoints.begin(); pos != end; ++pos)
91        {
92            if ((*pos)->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
93            {
94                (*pos)->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
95                                                    new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved,
96                                                                                         *pos));
97            }
98        }
99    }
100    m_breakpoints.erase (m_breakpoints.begin(), m_breakpoints.end());
101}
102
103class BreakpointIDMatches
104{
105public:
106    BreakpointIDMatches (break_id_t break_id) :
107        m_break_id(break_id)
108    {
109    }
110
111    bool operator() (const BreakpointSP &bp) const
112    {
113        return m_break_id == bp->GetID();
114    }
115
116private:
117   const break_id_t m_break_id;
118};
119
120BreakpointList::bp_collection::iterator
121BreakpointList::GetBreakpointIDIterator (break_id_t break_id)
122{
123    return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
124                        BreakpointIDMatches(break_id));             // Predicate
125}
126
127BreakpointList::bp_collection::const_iterator
128BreakpointList::GetBreakpointIDConstIterator (break_id_t break_id) const
129{
130    return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
131                        BreakpointIDMatches(break_id));             // Predicate
132}
133
134BreakpointSP
135BreakpointList::FindBreakpointByID (break_id_t break_id)
136{
137    Mutex::Locker locker(m_mutex);
138    BreakpointSP stop_sp;
139    bp_collection::iterator pos = GetBreakpointIDIterator(break_id);
140    if (pos != m_breakpoints.end())
141        stop_sp = *pos;
142
143    return stop_sp;
144}
145
146const BreakpointSP
147BreakpointList::FindBreakpointByID (break_id_t break_id) const
148{
149    Mutex::Locker locker(m_mutex);
150    BreakpointSP stop_sp;
151    bp_collection::const_iterator pos = GetBreakpointIDConstIterator(break_id);
152    if (pos != m_breakpoints.end())
153        stop_sp = *pos;
154
155    return stop_sp;
156}
157
158void
159BreakpointList::Dump (Stream *s) const
160{
161    Mutex::Locker locker(m_mutex);
162    s->Printf("%p: ", this);
163    s->Indent();
164    s->Printf("BreakpointList with %u Breakpoints:\n", (uint32_t)m_breakpoints.size());
165    s->IndentMore();
166    bp_collection::const_iterator pos;
167    bp_collection::const_iterator end = m_breakpoints.end();
168    for (pos = m_breakpoints.begin(); pos != end; ++pos)
169        (*pos)->Dump(s);
170    s->IndentLess();
171}
172
173
174BreakpointSP
175BreakpointList::GetBreakpointAtIndex (size_t i)
176{
177    Mutex::Locker locker(m_mutex);
178    BreakpointSP stop_sp;
179    bp_collection::iterator end = m_breakpoints.end();
180    bp_collection::iterator pos;
181    size_t curr_i = 0;
182    for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
183    {
184        if (curr_i == i)
185            stop_sp = *pos;
186    }
187    return stop_sp;
188}
189
190const BreakpointSP
191BreakpointList::GetBreakpointAtIndex (size_t i) const
192{
193    Mutex::Locker locker(m_mutex);
194    BreakpointSP stop_sp;
195    bp_collection::const_iterator end = m_breakpoints.end();
196    bp_collection::const_iterator pos;
197    size_t curr_i = 0;
198    for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
199    {
200        if (curr_i == i)
201            stop_sp = *pos;
202    }
203    return stop_sp;
204}
205
206void
207BreakpointList::UpdateBreakpoints (ModuleList& module_list, bool added, bool delete_locations)
208{
209    Mutex::Locker locker(m_mutex);
210    bp_collection::iterator end = m_breakpoints.end();
211    bp_collection::iterator pos;
212    for (pos = m_breakpoints.begin(); pos != end; ++pos)
213        (*pos)->ModulesChanged (module_list, added, delete_locations);
214
215}
216
217void
218BreakpointList::UpdateBreakpointsWhenModuleIsReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
219{
220    Mutex::Locker locker(m_mutex);
221    bp_collection::iterator end = m_breakpoints.end();
222    bp_collection::iterator pos;
223    for (pos = m_breakpoints.begin(); pos != end; ++pos)
224        (*pos)->ModuleReplaced (old_module_sp, new_module_sp);
225
226}
227
228void
229BreakpointList::ClearAllBreakpointSites ()
230{
231    Mutex::Locker locker(m_mutex);
232    bp_collection::iterator end = m_breakpoints.end();
233    bp_collection::iterator pos;
234    for (pos = m_breakpoints.begin(); pos != end; ++pos)
235        (*pos)->ClearAllBreakpointSites ();
236
237}
238
239void
240BreakpointList::GetListMutex (Mutex::Locker &locker)
241{
242    return locker.Lock (m_mutex);
243}
244