blob: 8f0545310b1d8486fccec3f8bf90db7ce415d33a [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- SBBreakpoint.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/API/SBBreakpoint.h"
11#include "lldb/API/SBBreakpointLocation.h"
12#include "lldb/API/SBDebugger.h"
Greg Claytonc7f5d5c2010-07-23 23:33:17 +000013#include "lldb/API/SBEvent.h"
Chris Lattner24943d22010-06-08 16:52:24 +000014#include "lldb/API/SBProcess.h"
Caroline Tice98f930f2010-09-20 05:20:02 +000015#include "lldb/API/SBStream.h"
Chris Lattner24943d22010-06-08 16:52:24 +000016#include "lldb/API/SBThread.h"
17
18#include "lldb/Breakpoint/Breakpoint.h"
19#include "lldb/Breakpoint/BreakpointLocation.h"
20#include "lldb/Breakpoint/StoppointCallbackContext.h"
21#include "lldb/Core/Address.h"
22#include "lldb/Core/Stream.h"
23#include "lldb/Core/StreamFile.h"
24#include "lldb/Target/Process.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Target/Target.h"
Jim Ingham8e5e38f2010-06-18 01:47:08 +000026#include "lldb/Target/Thread.h"
27#include "lldb/Target/ThreadSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000028
29
30#include "lldb/lldb-enumerations.h"
31
32using namespace lldb;
33using namespace lldb_private;
34
35struct CallbackData
36{
37 SBBreakpoint::BreakpointHitCallback callback;
38 void *callback_baton;
39};
40
41class SBBreakpointCallbackBaton : public Baton
42{
43public:
44
45 SBBreakpointCallbackBaton (SBBreakpoint::BreakpointHitCallback callback, void *baton) :
46 Baton (new CallbackData)
47 {
48 CallbackData *data = (CallbackData *)m_data;
49 data->callback = callback;
50 data->callback_baton = baton;
51 }
52
53 virtual ~SBBreakpointCallbackBaton()
54 {
55 CallbackData *data = (CallbackData *)m_data;
56
57 if (data)
58 {
59 delete data;
60 m_data = NULL;
61 }
62 }
63};
64
65
66SBBreakpoint::SBBreakpoint () :
Greg Clayton63094e02010-06-23 01:19:29 +000067 m_opaque_sp ()
Chris Lattner24943d22010-06-08 16:52:24 +000068{
69}
70
71SBBreakpoint::SBBreakpoint (const SBBreakpoint& rhs) :
Greg Clayton63094e02010-06-23 01:19:29 +000072 m_opaque_sp (rhs.m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000073{
74}
75
76
77SBBreakpoint::SBBreakpoint (const lldb::BreakpointSP &bp_sp) :
Greg Clayton63094e02010-06-23 01:19:29 +000078 m_opaque_sp (bp_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000079{
80}
81
82SBBreakpoint::~SBBreakpoint()
83{
84}
85
86const SBBreakpoint &
87SBBreakpoint::operator = (const SBBreakpoint& rhs)
88{
89 if (this != &rhs)
90 {
Greg Clayton63094e02010-06-23 01:19:29 +000091 m_opaque_sp = rhs.m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +000092 }
93 return *this;
94}
95
96break_id_t
97SBBreakpoint::GetID () const
98{
Greg Clayton63094e02010-06-23 01:19:29 +000099 if (m_opaque_sp)
100 return m_opaque_sp->GetID();
Chris Lattner24943d22010-06-08 16:52:24 +0000101 return LLDB_INVALID_BREAK_ID;
102}
103
104
105bool
106SBBreakpoint::IsValid() const
107{
Greg Clayton63094e02010-06-23 01:19:29 +0000108 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000109}
110
111void
Chris Lattner24943d22010-06-08 16:52:24 +0000112SBBreakpoint::ClearAllBreakpointSites ()
113{
Greg Clayton63094e02010-06-23 01:19:29 +0000114 if (m_opaque_sp)
115 m_opaque_sp->ClearAllBreakpointSites ();
Chris Lattner24943d22010-06-08 16:52:24 +0000116}
117
118SBBreakpointLocation
119SBBreakpoint::FindLocationByAddress (addr_t vm_addr)
120{
121 SBBreakpointLocation sb_bp_location;
122
Greg Clayton63094e02010-06-23 01:19:29 +0000123 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000124 {
125 if (vm_addr != LLDB_INVALID_ADDRESS)
126 {
127 Address address;
Greg Claytoneea26402010-09-14 23:36:40 +0000128 Target &target = m_opaque_sp->GetTarget();
129 if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000130 {
131 address.SetSection (NULL);
132 address.SetOffset (vm_addr);
133 }
Greg Clayton63094e02010-06-23 01:19:29 +0000134 sb_bp_location.SetLocation (m_opaque_sp->FindLocationByAddress (address));
Chris Lattner24943d22010-06-08 16:52:24 +0000135 }
136 }
137 return sb_bp_location;
138}
139
140break_id_t
141SBBreakpoint::FindLocationIDByAddress (addr_t vm_addr)
142{
143 break_id_t lldb_id = (break_id_t) 0;
144
Greg Clayton63094e02010-06-23 01:19:29 +0000145 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000146 {
147 if (vm_addr != LLDB_INVALID_ADDRESS)
148 {
149 Address address;
Greg Claytoneea26402010-09-14 23:36:40 +0000150 Target &target = m_opaque_sp->GetTarget();
151 if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000152 {
153 address.SetSection (NULL);
154 address.SetOffset (vm_addr);
155 }
Greg Clayton63094e02010-06-23 01:19:29 +0000156 lldb_id = m_opaque_sp->FindLocationIDByAddress (address);
Chris Lattner24943d22010-06-08 16:52:24 +0000157 }
158 }
159
160 return lldb_id;
161}
162
163SBBreakpointLocation
164SBBreakpoint::FindLocationByID (break_id_t bp_loc_id)
165{
166 SBBreakpointLocation sb_bp_location;
167
Greg Clayton63094e02010-06-23 01:19:29 +0000168 if (m_opaque_sp)
169 sb_bp_location.SetLocation (m_opaque_sp->FindLocationByID (bp_loc_id));
Chris Lattner24943d22010-06-08 16:52:24 +0000170
171 return sb_bp_location;
172}
173
174SBBreakpointLocation
175SBBreakpoint::GetLocationAtIndex (uint32_t index)
176{
177 SBBreakpointLocation sb_bp_location;
178
Greg Clayton63094e02010-06-23 01:19:29 +0000179 if (m_opaque_sp)
180 sb_bp_location.SetLocation (m_opaque_sp->GetLocationAtIndex (index));
Chris Lattner24943d22010-06-08 16:52:24 +0000181
182 return sb_bp_location;
183}
184
185void
Chris Lattner24943d22010-06-08 16:52:24 +0000186SBBreakpoint::SetEnabled (bool enable)
187{
Greg Clayton63094e02010-06-23 01:19:29 +0000188 if (m_opaque_sp)
189 m_opaque_sp->SetEnabled (enable);
Chris Lattner24943d22010-06-08 16:52:24 +0000190}
191
192bool
193SBBreakpoint::IsEnabled ()
194{
Greg Clayton63094e02010-06-23 01:19:29 +0000195 if (m_opaque_sp)
196 return m_opaque_sp->IsEnabled();
Chris Lattner24943d22010-06-08 16:52:24 +0000197 else
198 return false;
199}
200
201void
Greg Clayton54e7afa2010-07-09 20:39:50 +0000202SBBreakpoint::SetIgnoreCount (uint32_t count)
Chris Lattner24943d22010-06-08 16:52:24 +0000203{
Greg Clayton63094e02010-06-23 01:19:29 +0000204 if (m_opaque_sp)
205 m_opaque_sp->SetIgnoreCount (count);
Chris Lattner24943d22010-06-08 16:52:24 +0000206}
207
Greg Clayton54e7afa2010-07-09 20:39:50 +0000208uint32_t
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000209SBBreakpoint::GetHitCount () const
210{
211 if (m_opaque_sp)
212 return m_opaque_sp->GetHitCount();
213 else
214 return 0;
215}
216
217uint32_t
Chris Lattner24943d22010-06-08 16:52:24 +0000218SBBreakpoint::GetIgnoreCount () const
219{
Greg Clayton63094e02010-06-23 01:19:29 +0000220 if (m_opaque_sp)
221 return m_opaque_sp->GetIgnoreCount();
Chris Lattner24943d22010-06-08 16:52:24 +0000222 else
223 return 0;
224}
225
226void
227SBBreakpoint::SetThreadID (tid_t sb_thread_id)
228{
Greg Clayton63094e02010-06-23 01:19:29 +0000229 if (m_opaque_sp)
230 m_opaque_sp->SetThreadID (sb_thread_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000231}
232
233tid_t
234SBBreakpoint::GetThreadID ()
235{
236 tid_t lldb_thread_id = LLDB_INVALID_THREAD_ID;
Greg Clayton63094e02010-06-23 01:19:29 +0000237 if (m_opaque_sp)
238 lldb_thread_id = m_opaque_sp->GetThreadID();
Chris Lattner24943d22010-06-08 16:52:24 +0000239
240 return lldb_thread_id;
241}
242
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000243void
244SBBreakpoint::SetThreadIndex (uint32_t index)
245{
Greg Clayton63094e02010-06-23 01:19:29 +0000246 if (m_opaque_sp)
247 m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex (index);
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000248}
249
250uint32_t
251SBBreakpoint::GetThreadIndex() const
252{
Greg Clayton63094e02010-06-23 01:19:29 +0000253 if (m_opaque_sp)
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000254 {
Greg Clayton63094e02010-06-23 01:19:29 +0000255 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpec();
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000256 if (thread_spec == NULL)
257 return 0;
258 else
259 return thread_spec->GetIndex();
260 }
261 return 0;
262}
263
264
265void
266SBBreakpoint::SetThreadName (const char *thread_name)
267{
Greg Clayton63094e02010-06-23 01:19:29 +0000268 if (m_opaque_sp)
269 m_opaque_sp->GetOptions()->GetThreadSpec()->SetName (thread_name);
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000270}
271
272const char *
273SBBreakpoint::GetThreadName () const
274{
Greg Clayton63094e02010-06-23 01:19:29 +0000275 if (m_opaque_sp)
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000276 {
Greg Clayton63094e02010-06-23 01:19:29 +0000277 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpec();
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000278 if (thread_spec == NULL)
279 return NULL;
280 else
281 return thread_spec->GetName();
282 }
283 return NULL;
284}
285
286void
287SBBreakpoint::SetQueueName (const char *queue_name)
288{
Greg Clayton63094e02010-06-23 01:19:29 +0000289 if (m_opaque_sp)
290 m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName (queue_name);
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000291}
292
293const char *
294SBBreakpoint::GetQueueName () const
295{
Greg Clayton63094e02010-06-23 01:19:29 +0000296 if (m_opaque_sp)
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000297 {
Greg Clayton63094e02010-06-23 01:19:29 +0000298 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpec();
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000299 if (thread_spec == NULL)
300 return NULL;
301 else
302 return thread_spec->GetQueueName();
303 }
304 return NULL;
305}
306
Chris Lattner24943d22010-06-08 16:52:24 +0000307size_t
308SBBreakpoint::GetNumResolvedLocations() const
309{
Greg Clayton63094e02010-06-23 01:19:29 +0000310 if (m_opaque_sp)
311 return m_opaque_sp->GetNumResolvedLocations();
Chris Lattner24943d22010-06-08 16:52:24 +0000312 else
313 return 0;
314}
315
316size_t
317SBBreakpoint::GetNumLocations() const
318{
Greg Clayton63094e02010-06-23 01:19:29 +0000319 if (m_opaque_sp)
320 return m_opaque_sp->GetNumLocations();
Chris Lattner24943d22010-06-08 16:52:24 +0000321 else
322 return 0;
323}
324
Caroline Tice98f930f2010-09-20 05:20:02 +0000325bool
Greg Claytond8c62532010-10-07 04:19:01 +0000326SBBreakpoint::GetDescription (SBStream &s)
Chris Lattner24943d22010-06-08 16:52:24 +0000327{
Greg Clayton63094e02010-06-23 01:19:29 +0000328 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000329 {
Greg Claytond8c62532010-10-07 04:19:01 +0000330 s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
331 m_opaque_sp->GetResolverDescription (s.get());
332 m_opaque_sp->GetFilterDescription (s.get());
333 const size_t num_locations = m_opaque_sp->GetNumLocations ();
334 s.Printf(", locations = %zu", num_locations);
335 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000336 }
Greg Claytond8c62532010-10-07 04:19:01 +0000337 s.Printf ("No value");
338 return false;
Caroline Tice98f930f2010-09-20 05:20:02 +0000339}
340
Chris Lattner24943d22010-06-08 16:52:24 +0000341bool
342SBBreakpoint::PrivateBreakpointHitCallback
343(
344 void *baton,
345 StoppointCallbackContext *ctx,
346 lldb::user_id_t break_id,
347 lldb::user_id_t break_loc_id
348)
349{
Greg Clayton63094e02010-06-23 01:19:29 +0000350 BreakpointSP bp_sp(ctx->exe_ctx.target->GetBreakpointList().FindBreakpointByID(break_id));
Chris Lattner24943d22010-06-08 16:52:24 +0000351 if (baton && bp_sp)
352 {
353 CallbackData *data = (CallbackData *)baton;
354 lldb_private::Breakpoint *bp = bp_sp.get();
355 if (bp && data->callback)
356 {
Greg Clayton63094e02010-06-23 01:19:29 +0000357 if (ctx->exe_ctx.process)
Chris Lattner24943d22010-06-08 16:52:24 +0000358 {
Greg Clayton63094e02010-06-23 01:19:29 +0000359 SBProcess sb_process (ctx->exe_ctx.process->GetSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000360 SBThread sb_thread;
361 SBBreakpointLocation sb_location;
362 assert (bp_sp);
363 sb_location.SetLocation (bp_sp->FindLocationByID (break_loc_id));
Greg Clayton63094e02010-06-23 01:19:29 +0000364 if (ctx->exe_ctx.thread)
365 sb_thread.SetThread(ctx->exe_ctx.thread->GetSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000366
367 return data->callback (data->callback_baton,
368 sb_process,
369 sb_thread,
370 sb_location);
371 }
372 }
373 }
374 return true; // Return true if we should stop at this breakpoint
375}
376
377void
378SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton)
379{
Greg Clayton63094e02010-06-23 01:19:29 +0000380 if (m_opaque_sp.get())
Chris Lattner24943d22010-06-08 16:52:24 +0000381 {
382 BatonSP baton_sp(new SBBreakpointCallbackBaton (callback, baton));
Greg Clayton63094e02010-06-23 01:19:29 +0000383 m_opaque_sp->SetCallback (SBBreakpoint::PrivateBreakpointHitCallback, baton_sp, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000384 }
385}
386
387
388lldb_private::Breakpoint *
389SBBreakpoint::operator->() const
390{
Greg Clayton63094e02010-06-23 01:19:29 +0000391 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000392}
393
394lldb_private::Breakpoint *
395SBBreakpoint::get() const
396{
Greg Clayton63094e02010-06-23 01:19:29 +0000397 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000398}
399
400lldb::BreakpointSP &
401SBBreakpoint::operator *()
402{
Greg Clayton63094e02010-06-23 01:19:29 +0000403 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000404}
405
406const lldb::BreakpointSP &
407SBBreakpoint::operator *() const
408{
Greg Clayton63094e02010-06-23 01:19:29 +0000409 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000410}
411
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000412BreakpointEventType
413SBBreakpoint::GetBreakpointEventTypeFromEvent (const SBEvent& event)
414{
415 if (event.IsValid())
416 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event.GetSP());
417 return eBreakpointEventTypeInvalidType;
418}
419
420SBBreakpoint
421SBBreakpoint::GetBreakpointFromEvent (const lldb::SBEvent& event)
422{
423 SBBreakpoint sb_breakpoint;
424 if (event.IsValid())
425 sb_breakpoint.m_opaque_sp = Breakpoint::BreakpointEventData::GetBreakpointFromEvent (event.GetSP());
426 return sb_breakpoint;
427}
428
429SBBreakpointLocation
430SBBreakpoint::GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx)
431{
432 SBBreakpointLocation sb_breakpoint_loc;
433 if (event.IsValid())
434 sb_breakpoint_loc.SetLocation (Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (event.GetSP(), loc_idx));
435 return sb_breakpoint_loc;
436}
437
438