blob: aa84575be2e986f3705c4d36688ae433461513b3 [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
326SBBreakpoint::GetDescription (const char *description_level, SBStream &description)
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 {
330 DescriptionLevel level;
331 if (strcmp (description_level, "brief") == 0)
332 level = eDescriptionLevelBrief;
333 else if (strcmp (description_level, "full") == 0)
334 level = eDescriptionLevelFull;
335 else if (strcmp (description_level, "verbose") == 0)
336 level = eDescriptionLevelVerbose;
337 else
338 level = eDescriptionLevelBrief;
339
Chris Lattner24943d22010-06-08 16:52:24 +0000340
Caroline Tice98f930f2010-09-20 05:20:02 +0000341 m_opaque_sp->GetDescription (description.get(), level);
342 description.get()->EOL();
Chris Lattner24943d22010-06-08 16:52:24 +0000343 }
Caroline Tice98f930f2010-09-20 05:20:02 +0000344 else
345 description.Printf ("No value");
346
347 return true;
348}
349
350PyObject *
351SBBreakpoint::__repr__ ()
352{
353 SBStream description;
354 description.ref();
355 GetDescription ("full", description);
356 return PyString_FromString (description.GetData());
Chris Lattner24943d22010-06-08 16:52:24 +0000357}
358
359bool
360SBBreakpoint::PrivateBreakpointHitCallback
361(
362 void *baton,
363 StoppointCallbackContext *ctx,
364 lldb::user_id_t break_id,
365 lldb::user_id_t break_loc_id
366)
367{
Greg Clayton63094e02010-06-23 01:19:29 +0000368 BreakpointSP bp_sp(ctx->exe_ctx.target->GetBreakpointList().FindBreakpointByID(break_id));
Chris Lattner24943d22010-06-08 16:52:24 +0000369 if (baton && bp_sp)
370 {
371 CallbackData *data = (CallbackData *)baton;
372 lldb_private::Breakpoint *bp = bp_sp.get();
373 if (bp && data->callback)
374 {
Greg Clayton63094e02010-06-23 01:19:29 +0000375 if (ctx->exe_ctx.process)
Chris Lattner24943d22010-06-08 16:52:24 +0000376 {
Greg Clayton63094e02010-06-23 01:19:29 +0000377 SBProcess sb_process (ctx->exe_ctx.process->GetSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000378 SBThread sb_thread;
379 SBBreakpointLocation sb_location;
380 assert (bp_sp);
381 sb_location.SetLocation (bp_sp->FindLocationByID (break_loc_id));
Greg Clayton63094e02010-06-23 01:19:29 +0000382 if (ctx->exe_ctx.thread)
383 sb_thread.SetThread(ctx->exe_ctx.thread->GetSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000384
385 return data->callback (data->callback_baton,
386 sb_process,
387 sb_thread,
388 sb_location);
389 }
390 }
391 }
392 return true; // Return true if we should stop at this breakpoint
393}
394
395void
396SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton)
397{
Greg Clayton63094e02010-06-23 01:19:29 +0000398 if (m_opaque_sp.get())
Chris Lattner24943d22010-06-08 16:52:24 +0000399 {
400 BatonSP baton_sp(new SBBreakpointCallbackBaton (callback, baton));
Greg Clayton63094e02010-06-23 01:19:29 +0000401 m_opaque_sp->SetCallback (SBBreakpoint::PrivateBreakpointHitCallback, baton_sp, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000402 }
403}
404
405
406lldb_private::Breakpoint *
407SBBreakpoint::operator->() 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_private::Breakpoint *
413SBBreakpoint::get() const
414{
Greg Clayton63094e02010-06-23 01:19:29 +0000415 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000416}
417
418lldb::BreakpointSP &
419SBBreakpoint::operator *()
420{
Greg Clayton63094e02010-06-23 01:19:29 +0000421 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000422}
423
424const lldb::BreakpointSP &
425SBBreakpoint::operator *() const
426{
Greg Clayton63094e02010-06-23 01:19:29 +0000427 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000428}
429
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000430BreakpointEventType
431SBBreakpoint::GetBreakpointEventTypeFromEvent (const SBEvent& event)
432{
433 if (event.IsValid())
434 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event.GetSP());
435 return eBreakpointEventTypeInvalidType;
436}
437
438SBBreakpoint
439SBBreakpoint::GetBreakpointFromEvent (const lldb::SBEvent& event)
440{
441 SBBreakpoint sb_breakpoint;
442 if (event.IsValid())
443 sb_breakpoint.m_opaque_sp = Breakpoint::BreakpointEventData::GetBreakpointFromEvent (event.GetSP());
444 return sb_breakpoint;
445}
446
447SBBreakpointLocation
448SBBreakpoint::GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx)
449{
450 SBBreakpointLocation sb_breakpoint_loc;
451 if (event.IsValid())
452 sb_breakpoint_loc.SetLocation (Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (event.GetSP(), loc_idx));
453 return sb_breakpoint_loc;
454}
455
456