blob: 0034a9241b810fe2c99b1ffdebe5ad390625fbe0 [file] [log] [blame]
Chris Lattner24943d22010-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"
Greg Clayton49ce8962012-08-29 21:13:06 +000017#include "lldb/Core/Section.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018
19using namespace lldb;
20using namespace lldb_private;
21
Jim Ingham28e23862012-02-08 05:23:15 +000022BreakpointLocationList::BreakpointLocationList(Breakpoint &owner) :
Bill Wendlingc9fda2d2012-04-03 04:14:58 +000023 m_owner (owner),
Chris Lattner24943d22010-06-08 16:52:24 +000024 m_locations(),
25 m_address_to_location (),
Jim Ingham28e23862012-02-08 05:23:15 +000026 m_mutex (Mutex::eMutexTypeRecursive),
Bill Wendlingc9fda2d2012-04-03 04:14:58 +000027 m_next_id (0),
28 m_new_location_recorder (NULL)
Chris Lattner24943d22010-06-08 16:52:24 +000029{
30}
31
32BreakpointLocationList::~BreakpointLocationList()
33{
34}
35
Greg Clayton19a1ab82011-02-05 00:38:04 +000036BreakpointLocationSP
Jim Ingham28e23862012-02-08 05:23:15 +000037BreakpointLocationList::Create (const Address &addr)
Chris Lattner24943d22010-06-08 16:52:24 +000038{
Greg Clayton19a1ab82011-02-05 00:38:04 +000039 Mutex::Locker locker (m_mutex);
40 // The location ID is just the size of the location list + 1
Greg Clayton3508c382012-02-24 01:59:29 +000041 lldb::break_id_t bp_loc_id = ++m_next_id;
Jim Ingham28e23862012-02-08 05:23:15 +000042 BreakpointLocationSP bp_loc_sp (new BreakpointLocation (bp_loc_id, m_owner, addr));
Greg Clayton19a1ab82011-02-05 00:38:04 +000043 m_locations.push_back (bp_loc_sp);
44 m_address_to_location[addr] = bp_loc_sp;
45 return bp_loc_sp;
Chris Lattner24943d22010-06-08 16:52:24 +000046}
47
48bool
Greg Clayton54e7afa2010-07-09 20:39:50 +000049BreakpointLocationList::ShouldStop (StoppointCallbackContext *context, lldb::break_id_t break_id)
Chris Lattner24943d22010-06-08 16:52:24 +000050{
51 BreakpointLocationSP bp = FindByID (break_id);
52 if (bp)
53 {
54 // Let the BreakpointLocation decide if it should stop here (could not have
55 // reached it's target hit count yet, or it could have a callback
56 // that decided it shouldn't stop (shared library loads/unloads).
57 return bp->ShouldStop (context);
58 }
59 // We should stop here since this BreakpointLocation isn't valid anymore or it
60 // doesn't exist.
61 return true;
62}
63
Greg Clayton54e7afa2010-07-09 20:39:50 +000064lldb::break_id_t
Greg Clayton19a1ab82011-02-05 00:38:04 +000065BreakpointLocationList::FindIDByAddress (const Address &addr)
Chris Lattner24943d22010-06-08 16:52:24 +000066{
67 BreakpointLocationSP bp_loc_sp = FindByAddress (addr);
68 if (bp_loc_sp)
69 {
70 return bp_loc_sp->GetID();
71 }
72 return LLDB_INVALID_BREAK_ID;
73}
74
Chris Lattner24943d22010-06-08 16:52:24 +000075BreakpointLocationSP
Greg Clayton54e7afa2010-07-09 20:39:50 +000076BreakpointLocationList::FindByID (lldb::break_id_t break_id) const
Chris Lattner24943d22010-06-08 16:52:24 +000077{
Greg Clayton19a1ab82011-02-05 00:38:04 +000078 BreakpointLocationSP bp_loc_sp;
Chris Lattner24943d22010-06-08 16:52:24 +000079 Mutex::Locker locker (m_mutex);
Greg Clayton19a1ab82011-02-05 00:38:04 +000080 // We never remove a breakpoint locations, so the ID can be translated into
81 // the location index by subtracting 1
82 uint32_t idx = break_id - 1;
83 if (idx <= m_locations.size())
84 {
85 bp_loc_sp = m_locations[idx];
86 }
87 return bp_loc_sp;
Chris Lattner24943d22010-06-08 16:52:24 +000088}
89
90size_t
91BreakpointLocationList::FindInModule (Module *module,
92 BreakpointLocationCollection& bp_loc_list)
93{
94 Mutex::Locker locker (m_mutex);
95 const size_t orig_size = bp_loc_list.GetSize();
96 collection::iterator pos, end = m_locations.end();
97
98 for (pos = m_locations.begin(); pos != end; ++pos)
99 {
Chris Lattner24943d22010-06-08 16:52:24 +0000100 BreakpointLocationSP break_loc = (*pos);
Greg Clayton3508c382012-02-24 01:59:29 +0000101 SectionSP section_sp (break_loc->GetAddress().GetSection());
102 if (section_sp && section_sp->GetModule().get() == module)
Chris Lattner24943d22010-06-08 16:52:24 +0000103 {
Johnny Chen87ff1502011-08-11 21:43:13 +0000104 bp_loc_list.Add (break_loc);
Chris Lattner24943d22010-06-08 16:52:24 +0000105 }
106 }
107 return bp_loc_list.GetSize() - orig_size;
108}
109
Chris Lattner24943d22010-06-08 16:52:24 +0000110const BreakpointLocationSP
Greg Clayton19a1ab82011-02-05 00:38:04 +0000111BreakpointLocationList::FindByAddress (const Address &addr) const
Chris Lattner24943d22010-06-08 16:52:24 +0000112{
113 Mutex::Locker locker (m_mutex);
Greg Clayton19a1ab82011-02-05 00:38:04 +0000114 BreakpointLocationSP bp_loc_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000115 if (!m_locations.empty())
116 {
117 addr_map::const_iterator pos = m_address_to_location.find (addr);
118 if (pos != m_address_to_location.end())
Greg Clayton19a1ab82011-02-05 00:38:04 +0000119 bp_loc_sp = pos->second;
Chris Lattner24943d22010-06-08 16:52:24 +0000120 }
121
Greg Clayton19a1ab82011-02-05 00:38:04 +0000122 return bp_loc_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000123}
124
125void
126BreakpointLocationList::Dump (Stream *s) const
127{
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000128 s->Printf("%p: ", this);
Greg Claytonb1888f22011-03-19 01:12:21 +0000129 //s->Indent();
Chris Lattner24943d22010-06-08 16:52:24 +0000130 Mutex::Locker locker (m_mutex);
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000131 s->Printf("BreakpointLocationList with %" PRIu64 " BreakpointLocations:\n", (uint64_t)m_locations.size());
Chris Lattner24943d22010-06-08 16:52:24 +0000132 s->IndentMore();
133 collection::const_iterator pos, end = m_locations.end();
134 for (pos = m_locations.begin(); pos != end; ++pos)
135 (*pos).get()->Dump(s);
136 s->IndentLess();
137}
138
139
140BreakpointLocationSP
141BreakpointLocationList::GetByIndex (uint32_t i)
142{
143 Mutex::Locker locker (m_mutex);
Greg Clayton19a1ab82011-02-05 00:38:04 +0000144 BreakpointLocationSP bp_loc_sp;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000145 if (i < m_locations.size())
Greg Clayton19a1ab82011-02-05 00:38:04 +0000146 bp_loc_sp = m_locations[i];
Chris Lattner24943d22010-06-08 16:52:24 +0000147
Greg Clayton19a1ab82011-02-05 00:38:04 +0000148 return bp_loc_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000149}
150
151const BreakpointLocationSP
152BreakpointLocationList::GetByIndex (uint32_t i) const
153{
154 Mutex::Locker locker (m_mutex);
Greg Clayton19a1ab82011-02-05 00:38:04 +0000155 BreakpointLocationSP bp_loc_sp;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000156 if (i < m_locations.size())
Greg Clayton19a1ab82011-02-05 00:38:04 +0000157 bp_loc_sp = m_locations[i];
Chris Lattner24943d22010-06-08 16:52:24 +0000158
Greg Clayton19a1ab82011-02-05 00:38:04 +0000159 return bp_loc_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000160}
161
162void
163BreakpointLocationList::ClearAllBreakpointSites ()
164{
165 Mutex::Locker locker (m_mutex);
166 collection::iterator pos, end = m_locations.end();
167 for (pos = m_locations.begin(); pos != end; ++pos)
168 (*pos)->ClearBreakpointSite();
169}
170
171void
172BreakpointLocationList::ResolveAllBreakpointSites ()
173{
174 Mutex::Locker locker (m_mutex);
175 collection::iterator pos, end = m_locations.end();
176
177 for (pos = m_locations.begin(); pos != end; ++pos)
Jim Ingham1de036b2010-10-20 03:36:33 +0000178 {
179 if ((*pos)->IsEnabled())
180 (*pos)->ResolveBreakpointSite();
181 }
Chris Lattner24943d22010-06-08 16:52:24 +0000182}
183
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000184uint32_t
185BreakpointLocationList::GetHitCount () const
186{
187 uint32_t hit_count = 0;
188 Mutex::Locker locker (m_mutex);
189 collection::const_iterator pos, end = m_locations.end();
190 for (pos = m_locations.begin(); pos != end; ++pos)
191 hit_count += (*pos)->GetHitCount();
192 return hit_count;
193}
194
Chris Lattner24943d22010-06-08 16:52:24 +0000195size_t
196BreakpointLocationList::GetNumResolvedLocations() const
197{
198 Mutex::Locker locker (m_mutex);
199 size_t resolve_count = 0;
200 collection::const_iterator pos, end = m_locations.end();
201 for (pos = m_locations.begin(); pos != end; ++pos)
202 {
203 if ((*pos)->IsResolved())
204 ++resolve_count;
205 }
206 return resolve_count;
207}
208
Chris Lattner24943d22010-06-08 16:52:24 +0000209void
210BreakpointLocationList::GetDescription (Stream *s, lldb::DescriptionLevel level)
211{
212 Mutex::Locker locker (m_mutex);
213 collection::iterator pos, end = m_locations.end();
214
215 for (pos = m_locations.begin(); pos != end; ++pos)
216 {
217 s->Printf(" ");
218 (*pos)->GetDescription(s, level);
219 }
220}
221
Jim Ingham28e23862012-02-08 05:23:15 +0000222BreakpointLocationSP
223BreakpointLocationList::AddLocation (const Address &addr, bool *new_location)
224{
225 Mutex::Locker locker (m_mutex);
226
227 if (new_location)
228 *new_location = false;
229 BreakpointLocationSP bp_loc_sp (FindByAddress(addr));
230 if (!bp_loc_sp)
231 {
232 bp_loc_sp = Create (addr);
233 if (bp_loc_sp)
234 {
235 bp_loc_sp->ResolveBreakpointSite();
236
237 if (new_location)
238 *new_location = true;
239 if(m_new_location_recorder)
240 {
241 m_new_location_recorder->Add(bp_loc_sp);
242 }
243 }
244 }
245 return bp_loc_sp;
246}
247
Greg Clayton3508c382012-02-24 01:59:29 +0000248bool
249BreakpointLocationList::RemoveLocation (const lldb::BreakpointLocationSP &bp_loc_sp)
250{
251 if (bp_loc_sp)
252 {
253 Mutex::Locker locker (m_mutex);
254
255 m_address_to_location.erase (bp_loc_sp->GetAddress());
256
257 collection::iterator pos, end = m_locations.end();
258 for (pos = m_locations.begin(); pos != end; ++pos)
259 {
260 if ((*pos).get() == bp_loc_sp.get())
261 {
262 m_locations.erase (pos);
263 return true;
264 }
265 }
266 }
267 return false;
268}
269
270
Jim Ingham28e23862012-02-08 05:23:15 +0000271
272void
273BreakpointLocationList::StartRecordingNewLocations (BreakpointLocationCollection &new_locations)
274{
275 Mutex::Locker locker (m_mutex);
276 assert (m_new_location_recorder == NULL);
277 m_new_location_recorder = &new_locations;
278}
279
280void
281BreakpointLocationList::StopRecordingNewLocations ()
282{
283 Mutex::Locker locker (m_mutex);
284 m_new_location_recorder = NULL;
285}
286