blob: 2ba7b9e96b9280aaec8e9a28d606d1a7722aa19b [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
Jim Inghame3740832010-10-22 01:15:49 +0000208void
209SBBreakpoint::SetCondition (const char *condition)
210{
211 m_opaque_sp->SetCondition (condition);
212}
213
214const char *
215SBBreakpoint::GetCondition ()
216{
217 return m_opaque_sp->GetConditionText ();
218}
219
Greg Clayton54e7afa2010-07-09 20:39:50 +0000220uint32_t
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000221SBBreakpoint::GetHitCount () const
222{
223 if (m_opaque_sp)
224 return m_opaque_sp->GetHitCount();
225 else
226 return 0;
227}
228
229uint32_t
Chris Lattner24943d22010-06-08 16:52:24 +0000230SBBreakpoint::GetIgnoreCount () const
231{
Greg Clayton63094e02010-06-23 01:19:29 +0000232 if (m_opaque_sp)
233 return m_opaque_sp->GetIgnoreCount();
Chris Lattner24943d22010-06-08 16:52:24 +0000234 else
235 return 0;
236}
237
238void
239SBBreakpoint::SetThreadID (tid_t sb_thread_id)
240{
Greg Clayton63094e02010-06-23 01:19:29 +0000241 if (m_opaque_sp)
242 m_opaque_sp->SetThreadID (sb_thread_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000243}
244
245tid_t
246SBBreakpoint::GetThreadID ()
247{
248 tid_t lldb_thread_id = LLDB_INVALID_THREAD_ID;
Greg Clayton63094e02010-06-23 01:19:29 +0000249 if (m_opaque_sp)
250 lldb_thread_id = m_opaque_sp->GetThreadID();
Chris Lattner24943d22010-06-08 16:52:24 +0000251
252 return lldb_thread_id;
253}
254
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000255void
256SBBreakpoint::SetThreadIndex (uint32_t index)
257{
Greg Clayton63094e02010-06-23 01:19:29 +0000258 if (m_opaque_sp)
259 m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex (index);
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000260}
261
262uint32_t
263SBBreakpoint::GetThreadIndex() const
264{
Greg Clayton63094e02010-06-23 01:19:29 +0000265 if (m_opaque_sp)
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000266 {
Greg Clayton63094e02010-06-23 01:19:29 +0000267 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpec();
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000268 if (thread_spec == NULL)
269 return 0;
270 else
271 return thread_spec->GetIndex();
272 }
273 return 0;
274}
275
276
277void
278SBBreakpoint::SetThreadName (const char *thread_name)
279{
Greg Clayton63094e02010-06-23 01:19:29 +0000280 if (m_opaque_sp)
281 m_opaque_sp->GetOptions()->GetThreadSpec()->SetName (thread_name);
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000282}
283
284const char *
285SBBreakpoint::GetThreadName () const
286{
Greg Clayton63094e02010-06-23 01:19:29 +0000287 if (m_opaque_sp)
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000288 {
Greg Clayton63094e02010-06-23 01:19:29 +0000289 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpec();
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000290 if (thread_spec == NULL)
291 return NULL;
292 else
293 return thread_spec->GetName();
294 }
295 return NULL;
296}
297
298void
299SBBreakpoint::SetQueueName (const char *queue_name)
300{
Greg Clayton63094e02010-06-23 01:19:29 +0000301 if (m_opaque_sp)
302 m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName (queue_name);
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000303}
304
305const char *
306SBBreakpoint::GetQueueName () const
307{
Greg Clayton63094e02010-06-23 01:19:29 +0000308 if (m_opaque_sp)
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000309 {
Greg Clayton63094e02010-06-23 01:19:29 +0000310 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpec();
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000311 if (thread_spec == NULL)
312 return NULL;
313 else
314 return thread_spec->GetQueueName();
315 }
316 return NULL;
317}
318
Chris Lattner24943d22010-06-08 16:52:24 +0000319size_t
320SBBreakpoint::GetNumResolvedLocations() const
321{
Greg Clayton63094e02010-06-23 01:19:29 +0000322 if (m_opaque_sp)
323 return m_opaque_sp->GetNumResolvedLocations();
Chris Lattner24943d22010-06-08 16:52:24 +0000324 else
325 return 0;
326}
327
328size_t
329SBBreakpoint::GetNumLocations() const
330{
Greg Clayton63094e02010-06-23 01:19:29 +0000331 if (m_opaque_sp)
332 return m_opaque_sp->GetNumLocations();
Chris Lattner24943d22010-06-08 16:52:24 +0000333 else
334 return 0;
335}
336
Caroline Tice98f930f2010-09-20 05:20:02 +0000337bool
Greg Claytond8c62532010-10-07 04:19:01 +0000338SBBreakpoint::GetDescription (SBStream &s)
Chris Lattner24943d22010-06-08 16:52:24 +0000339{
Greg Clayton63094e02010-06-23 01:19:29 +0000340 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000341 {
Greg Claytond8c62532010-10-07 04:19:01 +0000342 s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
343 m_opaque_sp->GetResolverDescription (s.get());
344 m_opaque_sp->GetFilterDescription (s.get());
345 const size_t num_locations = m_opaque_sp->GetNumLocations ();
346 s.Printf(", locations = %zu", num_locations);
347 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000348 }
Greg Claytond8c62532010-10-07 04:19:01 +0000349 s.Printf ("No value");
350 return false;
Caroline Tice98f930f2010-09-20 05:20:02 +0000351}
352
Chris Lattner24943d22010-06-08 16:52:24 +0000353bool
354SBBreakpoint::PrivateBreakpointHitCallback
355(
356 void *baton,
357 StoppointCallbackContext *ctx,
358 lldb::user_id_t break_id,
359 lldb::user_id_t break_loc_id
360)
361{
Greg Clayton63094e02010-06-23 01:19:29 +0000362 BreakpointSP bp_sp(ctx->exe_ctx.target->GetBreakpointList().FindBreakpointByID(break_id));
Chris Lattner24943d22010-06-08 16:52:24 +0000363 if (baton && bp_sp)
364 {
365 CallbackData *data = (CallbackData *)baton;
366 lldb_private::Breakpoint *bp = bp_sp.get();
367 if (bp && data->callback)
368 {
Greg Clayton63094e02010-06-23 01:19:29 +0000369 if (ctx->exe_ctx.process)
Chris Lattner24943d22010-06-08 16:52:24 +0000370 {
Greg Clayton63094e02010-06-23 01:19:29 +0000371 SBProcess sb_process (ctx->exe_ctx.process->GetSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000372 SBThread sb_thread;
373 SBBreakpointLocation sb_location;
374 assert (bp_sp);
375 sb_location.SetLocation (bp_sp->FindLocationByID (break_loc_id));
Greg Clayton63094e02010-06-23 01:19:29 +0000376 if (ctx->exe_ctx.thread)
377 sb_thread.SetThread(ctx->exe_ctx.thread->GetSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000378
379 return data->callback (data->callback_baton,
380 sb_process,
381 sb_thread,
382 sb_location);
383 }
384 }
385 }
386 return true; // Return true if we should stop at this breakpoint
387}
388
389void
390SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton)
391{
Greg Clayton63094e02010-06-23 01:19:29 +0000392 if (m_opaque_sp.get())
Chris Lattner24943d22010-06-08 16:52:24 +0000393 {
394 BatonSP baton_sp(new SBBreakpointCallbackBaton (callback, baton));
Greg Clayton63094e02010-06-23 01:19:29 +0000395 m_opaque_sp->SetCallback (SBBreakpoint::PrivateBreakpointHitCallback, baton_sp, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000396 }
397}
398
399
400lldb_private::Breakpoint *
401SBBreakpoint::operator->() const
402{
Greg Clayton63094e02010-06-23 01:19:29 +0000403 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000404}
405
406lldb_private::Breakpoint *
407SBBreakpoint::get() const
408{
Greg Clayton63094e02010-06-23 01:19:29 +0000409 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000410}
411
412lldb::BreakpointSP &
413SBBreakpoint::operator *()
414{
Greg Clayton63094e02010-06-23 01:19:29 +0000415 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000416}
417
418const lldb::BreakpointSP &
419SBBreakpoint::operator *() const
420{
Greg Clayton63094e02010-06-23 01:19:29 +0000421 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000422}
423
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000424BreakpointEventType
425SBBreakpoint::GetBreakpointEventTypeFromEvent (const SBEvent& event)
426{
427 if (event.IsValid())
428 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event.GetSP());
429 return eBreakpointEventTypeInvalidType;
430}
431
432SBBreakpoint
433SBBreakpoint::GetBreakpointFromEvent (const lldb::SBEvent& event)
434{
435 SBBreakpoint sb_breakpoint;
436 if (event.IsValid())
437 sb_breakpoint.m_opaque_sp = Breakpoint::BreakpointEventData::GetBreakpointFromEvent (event.GetSP());
438 return sb_breakpoint;
439}
440
441SBBreakpointLocation
442SBBreakpoint::GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx)
443{
444 SBBreakpointLocation sb_breakpoint_loc;
445 if (event.IsValid())
446 sb_breakpoint_loc.SetLocation (Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (event.GetSP(), loc_idx));
447 return sb_breakpoint_loc;
448}
449
450