blob: 70a70458b3643e0720bd2990366005c49864f3f1 [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
Caroline Ticee49ec182010-09-22 23:01:29 +0000340 description.ref();
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
Chris Lattner24943d22010-06-08 16:52:24 +0000350bool
351SBBreakpoint::PrivateBreakpointHitCallback
352(
353 void *baton,
354 StoppointCallbackContext *ctx,
355 lldb::user_id_t break_id,
356 lldb::user_id_t break_loc_id
357)
358{
Greg Clayton63094e02010-06-23 01:19:29 +0000359 BreakpointSP bp_sp(ctx->exe_ctx.target->GetBreakpointList().FindBreakpointByID(break_id));
Chris Lattner24943d22010-06-08 16:52:24 +0000360 if (baton && bp_sp)
361 {
362 CallbackData *data = (CallbackData *)baton;
363 lldb_private::Breakpoint *bp = bp_sp.get();
364 if (bp && data->callback)
365 {
Greg Clayton63094e02010-06-23 01:19:29 +0000366 if (ctx->exe_ctx.process)
Chris Lattner24943d22010-06-08 16:52:24 +0000367 {
Greg Clayton63094e02010-06-23 01:19:29 +0000368 SBProcess sb_process (ctx->exe_ctx.process->GetSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000369 SBThread sb_thread;
370 SBBreakpointLocation sb_location;
371 assert (bp_sp);
372 sb_location.SetLocation (bp_sp->FindLocationByID (break_loc_id));
Greg Clayton63094e02010-06-23 01:19:29 +0000373 if (ctx->exe_ctx.thread)
374 sb_thread.SetThread(ctx->exe_ctx.thread->GetSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000375
376 return data->callback (data->callback_baton,
377 sb_process,
378 sb_thread,
379 sb_location);
380 }
381 }
382 }
383 return true; // Return true if we should stop at this breakpoint
384}
385
386void
387SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton)
388{
Greg Clayton63094e02010-06-23 01:19:29 +0000389 if (m_opaque_sp.get())
Chris Lattner24943d22010-06-08 16:52:24 +0000390 {
391 BatonSP baton_sp(new SBBreakpointCallbackBaton (callback, baton));
Greg Clayton63094e02010-06-23 01:19:29 +0000392 m_opaque_sp->SetCallback (SBBreakpoint::PrivateBreakpointHitCallback, baton_sp, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000393 }
394}
395
396
397lldb_private::Breakpoint *
398SBBreakpoint::operator->() const
399{
Greg Clayton63094e02010-06-23 01:19:29 +0000400 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000401}
402
403lldb_private::Breakpoint *
404SBBreakpoint::get() const
405{
Greg Clayton63094e02010-06-23 01:19:29 +0000406 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000407}
408
409lldb::BreakpointSP &
410SBBreakpoint::operator *()
411{
Greg Clayton63094e02010-06-23 01:19:29 +0000412 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000413}
414
415const lldb::BreakpointSP &
416SBBreakpoint::operator *() const
417{
Greg Clayton63094e02010-06-23 01:19:29 +0000418 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000419}
420
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000421BreakpointEventType
422SBBreakpoint::GetBreakpointEventTypeFromEvent (const SBEvent& event)
423{
424 if (event.IsValid())
425 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event.GetSP());
426 return eBreakpointEventTypeInvalidType;
427}
428
429SBBreakpoint
430SBBreakpoint::GetBreakpointFromEvent (const lldb::SBEvent& event)
431{
432 SBBreakpoint sb_breakpoint;
433 if (event.IsValid())
434 sb_breakpoint.m_opaque_sp = Breakpoint::BreakpointEventData::GetBreakpointFromEvent (event.GetSP());
435 return sb_breakpoint;
436}
437
438SBBreakpointLocation
439SBBreakpoint::GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx)
440{
441 SBBreakpointLocation sb_breakpoint_loc;
442 if (event.IsValid())
443 sb_breakpoint_loc.SetLocation (Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (event.GetSP(), loc_idx));
444 return sb_breakpoint_loc;
445}
446
447