BreakpointList.cpp revision 309124
1254721Semaste//===-- BreakpointList.cpp --------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/Breakpoint/BreakpointList.h"
11254721Semaste
12254721Semaste// C Includes
13254721Semaste// C++ Includes
14254721Semaste// Other libraries and framework includes
15254721Semaste// Project includes
16254721Semaste#include "lldb/Target/Target.h"
17254721Semaste
18254721Semasteusing namespace lldb;
19254721Semasteusing namespace lldb_private;
20254721Semaste
21309124SdimBreakpointList::BreakpointList(bool is_internal)
22309124Sdim    : m_mutex(), m_breakpoints(), m_next_break_id(0), m_is_internal(is_internal)
23254721Semaste{
24254721Semaste}
25254721Semaste
26254721SemasteBreakpointList::~BreakpointList()
27254721Semaste{
28254721Semaste}
29254721Semaste
30254721Semaste
31254721Semastebreak_id_t
32254721SemasteBreakpointList::Add (BreakpointSP &bp_sp, bool notify)
33254721Semaste{
34309124Sdim    std::lock_guard<std::recursive_mutex> guard(m_mutex);
35254721Semaste    // Internal breakpoint IDs are negative, normal ones are positive
36254721Semaste    bp_sp->SetID (m_is_internal ? --m_next_break_id : ++m_next_break_id);
37254721Semaste
38254721Semaste    m_breakpoints.push_back(bp_sp);
39254721Semaste    if (notify)
40254721Semaste    {
41254721Semaste        if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
42254721Semaste            bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
43254721Semaste                                               new Breakpoint::BreakpointEventData (eBreakpointEventTypeAdded, bp_sp));
44254721Semaste    }
45254721Semaste    return bp_sp->GetID();
46254721Semaste}
47254721Semaste
48254721Semastebool
49254721SemasteBreakpointList::Remove (break_id_t break_id, bool notify)
50254721Semaste{
51309124Sdim    std::lock_guard<std::recursive_mutex> guard(m_mutex);
52254721Semaste    bp_collection::iterator pos = GetBreakpointIDIterator(break_id);    // Predicate
53254721Semaste    if (pos != m_breakpoints.end())
54254721Semaste    {
55254721Semaste        BreakpointSP bp_sp (*pos);
56254721Semaste        m_breakpoints.erase(pos);
57254721Semaste        if (notify)
58254721Semaste        {
59254721Semaste            if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
60254721Semaste                bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
61254721Semaste                                                   new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved, bp_sp));
62254721Semaste        }
63254721Semaste        return true;
64254721Semaste    }
65254721Semaste    return false;
66254721Semaste}
67254721Semaste
68254721Semastevoid
69258884SemasteBreakpointList::RemoveInvalidLocations (const ArchSpec &arch)
70258884Semaste{
71309124Sdim    std::lock_guard<std::recursive_mutex> guard(m_mutex);
72258884Semaste    for (const auto &bp_sp : m_breakpoints)
73258884Semaste        bp_sp->RemoveInvalidLocations(arch);
74258884Semaste}
75258884Semaste
76258884Semaste
77258884Semastevoid
78254721SemasteBreakpointList::SetEnabledAll (bool enabled)
79254721Semaste{
80309124Sdim    std::lock_guard<std::recursive_mutex> guard(m_mutex);
81258884Semaste    for (const auto &bp_sp : m_breakpoints)
82258884Semaste        bp_sp->SetEnabled (enabled);
83254721Semaste}
84254721Semaste
85254721Semaste
86254721Semastevoid
87254721SemasteBreakpointList::RemoveAll (bool notify)
88254721Semaste{
89309124Sdim    std::lock_guard<std::recursive_mutex> guard(m_mutex);
90254721Semaste    ClearAllBreakpointSites ();
91254721Semaste
92254721Semaste    if (notify)
93254721Semaste    {
94254721Semaste        bp_collection::iterator pos, end = m_breakpoints.end();
95254721Semaste        for (pos = m_breakpoints.begin(); pos != end; ++pos)
96254721Semaste        {
97254721Semaste            if ((*pos)->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
98254721Semaste            {
99254721Semaste                (*pos)->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
100254721Semaste                                                    new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved,
101254721Semaste                                                                                         *pos));
102254721Semaste            }
103254721Semaste        }
104254721Semaste    }
105254721Semaste    m_breakpoints.erase (m_breakpoints.begin(), m_breakpoints.end());
106254721Semaste}
107254721Semaste
108254721Semasteclass BreakpointIDMatches
109254721Semaste{
110254721Semastepublic:
111254721Semaste    BreakpointIDMatches (break_id_t break_id) :
112254721Semaste        m_break_id(break_id)
113254721Semaste    {
114254721Semaste    }
115254721Semaste
116254721Semaste    bool operator() (const BreakpointSP &bp) const
117254721Semaste    {
118254721Semaste        return m_break_id == bp->GetID();
119254721Semaste    }
120254721Semaste
121254721Semasteprivate:
122254721Semaste   const break_id_t m_break_id;
123254721Semaste};
124254721Semaste
125254721SemasteBreakpointList::bp_collection::iterator
126254721SemasteBreakpointList::GetBreakpointIDIterator (break_id_t break_id)
127254721Semaste{
128254721Semaste    return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
129254721Semaste                        BreakpointIDMatches(break_id));             // Predicate
130254721Semaste}
131254721Semaste
132254721SemasteBreakpointList::bp_collection::const_iterator
133254721SemasteBreakpointList::GetBreakpointIDConstIterator (break_id_t break_id) const
134254721Semaste{
135254721Semaste    return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
136254721Semaste                        BreakpointIDMatches(break_id));             // Predicate
137254721Semaste}
138254721Semaste
139254721SemasteBreakpointSP
140254721SemasteBreakpointList::FindBreakpointByID (break_id_t break_id)
141254721Semaste{
142309124Sdim    std::lock_guard<std::recursive_mutex> guard(m_mutex);
143254721Semaste    BreakpointSP stop_sp;
144254721Semaste    bp_collection::iterator pos = GetBreakpointIDIterator(break_id);
145254721Semaste    if (pos != m_breakpoints.end())
146254721Semaste        stop_sp = *pos;
147254721Semaste
148254721Semaste    return stop_sp;
149254721Semaste}
150254721Semaste
151254721Semasteconst BreakpointSP
152254721SemasteBreakpointList::FindBreakpointByID (break_id_t break_id) const
153254721Semaste{
154309124Sdim    std::lock_guard<std::recursive_mutex> guard(m_mutex);
155254721Semaste    BreakpointSP stop_sp;
156254721Semaste    bp_collection::const_iterator pos = GetBreakpointIDConstIterator(break_id);
157254721Semaste    if (pos != m_breakpoints.end())
158254721Semaste        stop_sp = *pos;
159254721Semaste
160254721Semaste    return stop_sp;
161254721Semaste}
162254721Semaste
163254721Semastevoid
164254721SemasteBreakpointList::Dump (Stream *s) const
165254721Semaste{
166309124Sdim    std::lock_guard<std::recursive_mutex> guard(m_mutex);
167276479Sdim    s->Printf("%p: ", static_cast<const void*>(this));
168254721Semaste    s->Indent();
169254721Semaste    s->Printf("BreakpointList with %u Breakpoints:\n", (uint32_t)m_breakpoints.size());
170254721Semaste    s->IndentMore();
171258884Semaste    for (const auto &bp_sp : m_breakpoints)
172258884Semaste        bp_sp->Dump(s);
173254721Semaste    s->IndentLess();
174254721Semaste}
175254721Semaste
176254721Semaste
177254721SemasteBreakpointSP
178254721SemasteBreakpointList::GetBreakpointAtIndex (size_t i)
179254721Semaste{
180309124Sdim    std::lock_guard<std::recursive_mutex> guard(m_mutex);
181254721Semaste    BreakpointSP stop_sp;
182254721Semaste    bp_collection::iterator end = m_breakpoints.end();
183254721Semaste    bp_collection::iterator pos;
184254721Semaste    size_t curr_i = 0;
185254721Semaste    for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
186254721Semaste    {
187254721Semaste        if (curr_i == i)
188254721Semaste            stop_sp = *pos;
189254721Semaste    }
190254721Semaste    return stop_sp;
191254721Semaste}
192254721Semaste
193254721Semasteconst BreakpointSP
194254721SemasteBreakpointList::GetBreakpointAtIndex (size_t i) const
195254721Semaste{
196309124Sdim    std::lock_guard<std::recursive_mutex> guard(m_mutex);
197254721Semaste    BreakpointSP stop_sp;
198254721Semaste    bp_collection::const_iterator end = m_breakpoints.end();
199254721Semaste    bp_collection::const_iterator pos;
200254721Semaste    size_t curr_i = 0;
201254721Semaste    for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
202254721Semaste    {
203254721Semaste        if (curr_i == i)
204254721Semaste            stop_sp = *pos;
205254721Semaste    }
206254721Semaste    return stop_sp;
207254721Semaste}
208254721Semaste
209254721Semastevoid
210258054SemasteBreakpointList::UpdateBreakpoints (ModuleList& module_list, bool added, bool delete_locations)
211254721Semaste{
212309124Sdim    std::lock_guard<std::recursive_mutex> guard(m_mutex);
213258884Semaste    for (const auto &bp_sp : m_breakpoints)
214258884Semaste        bp_sp->ModulesChanged (module_list, added, delete_locations);
215254721Semaste
216254721Semaste}
217254721Semaste
218254721Semastevoid
219254721SemasteBreakpointList::UpdateBreakpointsWhenModuleIsReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
220254721Semaste{
221309124Sdim    std::lock_guard<std::recursive_mutex> guard(m_mutex);
222258884Semaste    for (const auto &bp_sp : m_breakpoints)
223258884Semaste        bp_sp->ModuleReplaced (old_module_sp, new_module_sp);
224254721Semaste
225254721Semaste}
226254721Semaste
227254721Semastevoid
228254721SemasteBreakpointList::ClearAllBreakpointSites ()
229254721Semaste{
230309124Sdim    std::lock_guard<std::recursive_mutex> guard(m_mutex);
231258884Semaste    for (const auto &bp_sp : m_breakpoints)
232258884Semaste        bp_sp->ClearAllBreakpointSites ();
233254721Semaste
234254721Semaste}
235254721Semaste
236254721Semastevoid
237309124SdimBreakpointList::GetListMutex(std::unique_lock<std::recursive_mutex> &lock)
238254721Semaste{
239309124Sdim    lock = std::unique_lock<std::recursive_mutex>(m_mutex);
240254721Semaste}
241