blob: 7fc4d81e28343961533eee4725add751651cf92e [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- BreakpointLocationList.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
11// C Includes
12// C++ Includes
13// Other libraries and framework includes
14// Project includes
15#include "lldb/Breakpoint/BreakpointLocationList.h"
16#include "lldb/Breakpoint/BreakpointLocation.h"
17#include "lldb/Core/ModuleList.h"
18#include "lldb/Target/Target.h"
19
20using namespace lldb;
21using namespace lldb_private;
22
Jim Inghame6bc6cb2012-02-08 05:23:15 +000023BreakpointLocationList::BreakpointLocationList(Breakpoint &owner) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024 m_locations(),
25 m_address_to_location (),
Jim Inghame6bc6cb2012-02-08 05:23:15 +000026 m_mutex (Mutex::eMutexTypeRecursive),
27 m_new_location_recorder (NULL),
Greg Claytone72dfb32012-02-24 01:59:29 +000028 m_owner (owner),
29 m_next_id (0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030{
31}
32
33BreakpointLocationList::~BreakpointLocationList()
34{
35}
36
Greg Claytonc0d34462011-02-05 00:38:04 +000037BreakpointLocationSP
Jim Inghame6bc6cb2012-02-08 05:23:15 +000038BreakpointLocationList::Create (const Address &addr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039{
Greg Claytonc0d34462011-02-05 00:38:04 +000040 Mutex::Locker locker (m_mutex);
41 // The location ID is just the size of the location list + 1
Greg Claytone72dfb32012-02-24 01:59:29 +000042 lldb::break_id_t bp_loc_id = ++m_next_id;
Jim Inghame6bc6cb2012-02-08 05:23:15 +000043 BreakpointLocationSP bp_loc_sp (new BreakpointLocation (bp_loc_id, m_owner, addr));
Greg Claytonc0d34462011-02-05 00:38:04 +000044 m_locations.push_back (bp_loc_sp);
45 m_address_to_location[addr] = bp_loc_sp;
46 return bp_loc_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047}
48
49bool
Greg Claytonc982c762010-07-09 20:39:50 +000050BreakpointLocationList::ShouldStop (StoppointCallbackContext *context, lldb::break_id_t break_id)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051{
52 BreakpointLocationSP bp = FindByID (break_id);
53 if (bp)
54 {
55 // Let the BreakpointLocation decide if it should stop here (could not have
56 // reached it's target hit count yet, or it could have a callback
57 // that decided it shouldn't stop (shared library loads/unloads).
58 return bp->ShouldStop (context);
59 }
60 // We should stop here since this BreakpointLocation isn't valid anymore or it
61 // doesn't exist.
62 return true;
63}
64
Greg Claytonc982c762010-07-09 20:39:50 +000065lldb::break_id_t
Greg Claytonc0d34462011-02-05 00:38:04 +000066BreakpointLocationList::FindIDByAddress (const Address &addr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000067{
68 BreakpointLocationSP bp_loc_sp = FindByAddress (addr);
69 if (bp_loc_sp)
70 {
71 return bp_loc_sp->GetID();
72 }
73 return LLDB_INVALID_BREAK_ID;
74}
75
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076BreakpointLocationSP
Greg Claytonc982c762010-07-09 20:39:50 +000077BreakpointLocationList::FindByID (lldb::break_id_t break_id) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +000078{
Greg Claytonc0d34462011-02-05 00:38:04 +000079 BreakpointLocationSP bp_loc_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080 Mutex::Locker locker (m_mutex);
Greg Claytonc0d34462011-02-05 00:38:04 +000081 // We never remove a breakpoint locations, so the ID can be translated into
82 // the location index by subtracting 1
83 uint32_t idx = break_id - 1;
84 if (idx <= m_locations.size())
85 {
86 bp_loc_sp = m_locations[idx];
87 }
88 return bp_loc_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000089}
90
91size_t
92BreakpointLocationList::FindInModule (Module *module,
93 BreakpointLocationCollection& bp_loc_list)
94{
95 Mutex::Locker locker (m_mutex);
96 const size_t orig_size = bp_loc_list.GetSize();
97 collection::iterator pos, end = m_locations.end();
98
99 for (pos = m_locations.begin(); pos != end; ++pos)
100 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000101 BreakpointLocationSP break_loc = (*pos);
Greg Claytone72dfb32012-02-24 01:59:29 +0000102 SectionSP section_sp (break_loc->GetAddress().GetSection());
103 if (section_sp && section_sp->GetModule().get() == module)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000104 {
Johnny Chen0861be02011-08-11 21:43:13 +0000105 bp_loc_list.Add (break_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106 }
107 }
108 return bp_loc_list.GetSize() - orig_size;
109}
110
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000111const BreakpointLocationSP
Greg Claytonc0d34462011-02-05 00:38:04 +0000112BreakpointLocationList::FindByAddress (const Address &addr) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000113{
114 Mutex::Locker locker (m_mutex);
Greg Claytonc0d34462011-02-05 00:38:04 +0000115 BreakpointLocationSP bp_loc_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000116 if (!m_locations.empty())
117 {
118 addr_map::const_iterator pos = m_address_to_location.find (addr);
119 if (pos != m_address_to_location.end())
Greg Claytonc0d34462011-02-05 00:38:04 +0000120 bp_loc_sp = pos->second;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000121 }
122
Greg Claytonc0d34462011-02-05 00:38:04 +0000123 return bp_loc_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000124}
125
126void
127BreakpointLocationList::Dump (Stream *s) const
128{
Jason Molendafd54b362011-09-20 21:44:10 +0000129 s->Printf("%p: ", this);
Greg Claytonded470d2011-03-19 01:12:21 +0000130 //s->Indent();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000131 Mutex::Locker locker (m_mutex);
132 s->Printf("BreakpointLocationList with %zu BreakpointLocations:\n", m_locations.size());
133 s->IndentMore();
134 collection::const_iterator pos, end = m_locations.end();
135 for (pos = m_locations.begin(); pos != end; ++pos)
136 (*pos).get()->Dump(s);
137 s->IndentLess();
138}
139
140
141BreakpointLocationSP
142BreakpointLocationList::GetByIndex (uint32_t i)
143{
144 Mutex::Locker locker (m_mutex);
Greg Claytonc0d34462011-02-05 00:38:04 +0000145 BreakpointLocationSP bp_loc_sp;
Greg Claytonc982c762010-07-09 20:39:50 +0000146 if (i < m_locations.size())
Greg Claytonc0d34462011-02-05 00:38:04 +0000147 bp_loc_sp = m_locations[i];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000148
Greg Claytonc0d34462011-02-05 00:38:04 +0000149 return bp_loc_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000150}
151
152const BreakpointLocationSP
153BreakpointLocationList::GetByIndex (uint32_t i) const
154{
155 Mutex::Locker locker (m_mutex);
Greg Claytonc0d34462011-02-05 00:38:04 +0000156 BreakpointLocationSP bp_loc_sp;
Greg Claytonc982c762010-07-09 20:39:50 +0000157 if (i < m_locations.size())
Greg Claytonc0d34462011-02-05 00:38:04 +0000158 bp_loc_sp = m_locations[i];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159
Greg Claytonc0d34462011-02-05 00:38:04 +0000160 return bp_loc_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161}
162
163void
164BreakpointLocationList::ClearAllBreakpointSites ()
165{
166 Mutex::Locker locker (m_mutex);
167 collection::iterator pos, end = m_locations.end();
168 for (pos = m_locations.begin(); pos != end; ++pos)
169 (*pos)->ClearBreakpointSite();
170}
171
172void
173BreakpointLocationList::ResolveAllBreakpointSites ()
174{
175 Mutex::Locker locker (m_mutex);
176 collection::iterator pos, end = m_locations.end();
177
178 for (pos = m_locations.begin(); pos != end; ++pos)
Jim Inghamd4ce0a12010-10-20 03:36:33 +0000179 {
180 if ((*pos)->IsEnabled())
181 (*pos)->ResolveBreakpointSite();
182 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183}
184
Greg Clayton9fed0d82010-07-23 23:33:17 +0000185uint32_t
186BreakpointLocationList::GetHitCount () const
187{
188 uint32_t hit_count = 0;
189 Mutex::Locker locker (m_mutex);
190 collection::const_iterator pos, end = m_locations.end();
191 for (pos = m_locations.begin(); pos != end; ++pos)
192 hit_count += (*pos)->GetHitCount();
193 return hit_count;
194}
195
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000196size_t
197BreakpointLocationList::GetNumResolvedLocations() const
198{
199 Mutex::Locker locker (m_mutex);
200 size_t resolve_count = 0;
201 collection::const_iterator pos, end = m_locations.end();
202 for (pos = m_locations.begin(); pos != end; ++pos)
203 {
204 if ((*pos)->IsResolved())
205 ++resolve_count;
206 }
207 return resolve_count;
208}
209
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000210void
211BreakpointLocationList::GetDescription (Stream *s, lldb::DescriptionLevel level)
212{
213 Mutex::Locker locker (m_mutex);
214 collection::iterator pos, end = m_locations.end();
215
216 for (pos = m_locations.begin(); pos != end; ++pos)
217 {
218 s->Printf(" ");
219 (*pos)->GetDescription(s, level);
220 }
221}
222
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000223BreakpointLocationSP
224BreakpointLocationList::AddLocation (const Address &addr, bool *new_location)
225{
226 Mutex::Locker locker (m_mutex);
227
228 if (new_location)
229 *new_location = false;
230 BreakpointLocationSP bp_loc_sp (FindByAddress(addr));
231 if (!bp_loc_sp)
232 {
233 bp_loc_sp = Create (addr);
234 if (bp_loc_sp)
235 {
236 bp_loc_sp->ResolveBreakpointSite();
237
238 if (new_location)
239 *new_location = true;
240 if(m_new_location_recorder)
241 {
242 m_new_location_recorder->Add(bp_loc_sp);
243 }
244 }
245 }
246 return bp_loc_sp;
247}
248
Greg Claytone72dfb32012-02-24 01:59:29 +0000249bool
250BreakpointLocationList::RemoveLocation (const lldb::BreakpointLocationSP &bp_loc_sp)
251{
252 if (bp_loc_sp)
253 {
254 Mutex::Locker locker (m_mutex);
255
256 m_address_to_location.erase (bp_loc_sp->GetAddress());
257
258 collection::iterator pos, end = m_locations.end();
259 for (pos = m_locations.begin(); pos != end; ++pos)
260 {
261 if ((*pos).get() == bp_loc_sp.get())
262 {
263 m_locations.erase (pos);
264 return true;
265 }
266 }
267 }
268 return false;
269}
270
271
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000272
273void
274BreakpointLocationList::StartRecordingNewLocations (BreakpointLocationCollection &new_locations)
275{
276 Mutex::Locker locker (m_mutex);
277 assert (m_new_location_recorder == NULL);
278 m_new_location_recorder = &new_locations;
279}
280
281void
282BreakpointLocationList::StopRecordingNewLocations ()
283{
284 Mutex::Locker locker (m_mutex);
285 m_new_location_recorder = NULL;
286}
287