blob: 1e3c712382677908ad68575576cd93208b979918 [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"
15#include "lldb/API/SBThread.h"
16
17#include "lldb/Breakpoint/Breakpoint.h"
18#include "lldb/Breakpoint/BreakpointLocation.h"
19#include "lldb/Breakpoint/StoppointCallbackContext.h"
20#include "lldb/Core/Address.h"
21#include "lldb/Core/Stream.h"
22#include "lldb/Core/StreamFile.h"
23#include "lldb/Target/Process.h"
Chris Lattner24943d22010-06-08 16:52:24 +000024#include "lldb/Target/Target.h"
Jim Ingham8e5e38f2010-06-18 01:47:08 +000025#include "lldb/Target/Thread.h"
26#include "lldb/Target/ThreadSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027
28
29#include "lldb/lldb-enumerations.h"
30
31using namespace lldb;
32using namespace lldb_private;
33
34struct CallbackData
35{
36 SBBreakpoint::BreakpointHitCallback callback;
37 void *callback_baton;
38};
39
40class SBBreakpointCallbackBaton : public Baton
41{
42public:
43
44 SBBreakpointCallbackBaton (SBBreakpoint::BreakpointHitCallback callback, void *baton) :
45 Baton (new CallbackData)
46 {
47 CallbackData *data = (CallbackData *)m_data;
48 data->callback = callback;
49 data->callback_baton = baton;
50 }
51
52 virtual ~SBBreakpointCallbackBaton()
53 {
54 CallbackData *data = (CallbackData *)m_data;
55
56 if (data)
57 {
58 delete data;
59 m_data = NULL;
60 }
61 }
62};
63
64
65SBBreakpoint::SBBreakpoint () :
Greg Clayton63094e02010-06-23 01:19:29 +000066 m_opaque_sp ()
Chris Lattner24943d22010-06-08 16:52:24 +000067{
68}
69
70SBBreakpoint::SBBreakpoint (const SBBreakpoint& rhs) :
Greg Clayton63094e02010-06-23 01:19:29 +000071 m_opaque_sp (rhs.m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000072{
73}
74
75
76SBBreakpoint::SBBreakpoint (const lldb::BreakpointSP &bp_sp) :
Greg Clayton63094e02010-06-23 01:19:29 +000077 m_opaque_sp (bp_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000078{
79}
80
81SBBreakpoint::~SBBreakpoint()
82{
83}
84
85const SBBreakpoint &
86SBBreakpoint::operator = (const SBBreakpoint& rhs)
87{
88 if (this != &rhs)
89 {
Greg Clayton63094e02010-06-23 01:19:29 +000090 m_opaque_sp = rhs.m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +000091 }
92 return *this;
93}
94
95break_id_t
96SBBreakpoint::GetID () const
97{
Greg Clayton63094e02010-06-23 01:19:29 +000098 if (m_opaque_sp)
99 return m_opaque_sp->GetID();
Chris Lattner24943d22010-06-08 16:52:24 +0000100 return LLDB_INVALID_BREAK_ID;
101}
102
103
104bool
105SBBreakpoint::IsValid() const
106{
Greg Clayton63094e02010-06-23 01:19:29 +0000107 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000108}
109
110void
Chris Lattner24943d22010-06-08 16:52:24 +0000111SBBreakpoint::ClearAllBreakpointSites ()
112{
Greg Clayton63094e02010-06-23 01:19:29 +0000113 if (m_opaque_sp)
114 m_opaque_sp->ClearAllBreakpointSites ();
Chris Lattner24943d22010-06-08 16:52:24 +0000115}
116
117SBBreakpointLocation
118SBBreakpoint::FindLocationByAddress (addr_t vm_addr)
119{
120 SBBreakpointLocation sb_bp_location;
121
Greg Clayton63094e02010-06-23 01:19:29 +0000122 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000123 {
124 if (vm_addr != LLDB_INVALID_ADDRESS)
125 {
126 Address address;
Greg Claytoneea26402010-09-14 23:36:40 +0000127 Target &target = m_opaque_sp->GetTarget();
128 if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000129 {
130 address.SetSection (NULL);
131 address.SetOffset (vm_addr);
132 }
Greg Clayton63094e02010-06-23 01:19:29 +0000133 sb_bp_location.SetLocation (m_opaque_sp->FindLocationByAddress (address));
Chris Lattner24943d22010-06-08 16:52:24 +0000134 }
135 }
136 return sb_bp_location;
137}
138
139break_id_t
140SBBreakpoint::FindLocationIDByAddress (addr_t vm_addr)
141{
142 break_id_t lldb_id = (break_id_t) 0;
143
Greg Clayton63094e02010-06-23 01:19:29 +0000144 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000145 {
146 if (vm_addr != LLDB_INVALID_ADDRESS)
147 {
148 Address address;
Greg Claytoneea26402010-09-14 23:36:40 +0000149 Target &target = m_opaque_sp->GetTarget();
150 if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000151 {
152 address.SetSection (NULL);
153 address.SetOffset (vm_addr);
154 }
Greg Clayton63094e02010-06-23 01:19:29 +0000155 lldb_id = m_opaque_sp->FindLocationIDByAddress (address);
Chris Lattner24943d22010-06-08 16:52:24 +0000156 }
157 }
158
159 return lldb_id;
160}
161
162SBBreakpointLocation
163SBBreakpoint::FindLocationByID (break_id_t bp_loc_id)
164{
165 SBBreakpointLocation sb_bp_location;
166
Greg Clayton63094e02010-06-23 01:19:29 +0000167 if (m_opaque_sp)
168 sb_bp_location.SetLocation (m_opaque_sp->FindLocationByID (bp_loc_id));
Chris Lattner24943d22010-06-08 16:52:24 +0000169
170 return sb_bp_location;
171}
172
173SBBreakpointLocation
174SBBreakpoint::GetLocationAtIndex (uint32_t index)
175{
176 SBBreakpointLocation sb_bp_location;
177
Greg Clayton63094e02010-06-23 01:19:29 +0000178 if (m_opaque_sp)
179 sb_bp_location.SetLocation (m_opaque_sp->GetLocationAtIndex (index));
Chris Lattner24943d22010-06-08 16:52:24 +0000180
181 return sb_bp_location;
182}
183
184void
Chris Lattner24943d22010-06-08 16:52:24 +0000185SBBreakpoint::SetEnabled (bool enable)
186{
Greg Clayton63094e02010-06-23 01:19:29 +0000187 if (m_opaque_sp)
188 m_opaque_sp->SetEnabled (enable);
Chris Lattner24943d22010-06-08 16:52:24 +0000189}
190
191bool
192SBBreakpoint::IsEnabled ()
193{
Greg Clayton63094e02010-06-23 01:19:29 +0000194 if (m_opaque_sp)
195 return m_opaque_sp->IsEnabled();
Chris Lattner24943d22010-06-08 16:52:24 +0000196 else
197 return false;
198}
199
200void
Greg Clayton54e7afa2010-07-09 20:39:50 +0000201SBBreakpoint::SetIgnoreCount (uint32_t count)
Chris Lattner24943d22010-06-08 16:52:24 +0000202{
Greg Clayton63094e02010-06-23 01:19:29 +0000203 if (m_opaque_sp)
204 m_opaque_sp->SetIgnoreCount (count);
Chris Lattner24943d22010-06-08 16:52:24 +0000205}
206
Greg Clayton54e7afa2010-07-09 20:39:50 +0000207uint32_t
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000208SBBreakpoint::GetHitCount () const
209{
210 if (m_opaque_sp)
211 return m_opaque_sp->GetHitCount();
212 else
213 return 0;
214}
215
216uint32_t
Chris Lattner24943d22010-06-08 16:52:24 +0000217SBBreakpoint::GetIgnoreCount () const
218{
Greg Clayton63094e02010-06-23 01:19:29 +0000219 if (m_opaque_sp)
220 return m_opaque_sp->GetIgnoreCount();
Chris Lattner24943d22010-06-08 16:52:24 +0000221 else
222 return 0;
223}
224
225void
226SBBreakpoint::SetThreadID (tid_t sb_thread_id)
227{
Greg Clayton63094e02010-06-23 01:19:29 +0000228 if (m_opaque_sp)
229 m_opaque_sp->SetThreadID (sb_thread_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000230}
231
232tid_t
233SBBreakpoint::GetThreadID ()
234{
235 tid_t lldb_thread_id = LLDB_INVALID_THREAD_ID;
Greg Clayton63094e02010-06-23 01:19:29 +0000236 if (m_opaque_sp)
237 lldb_thread_id = m_opaque_sp->GetThreadID();
Chris Lattner24943d22010-06-08 16:52:24 +0000238
239 return lldb_thread_id;
240}
241
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000242void
243SBBreakpoint::SetThreadIndex (uint32_t index)
244{
Greg Clayton63094e02010-06-23 01:19:29 +0000245 if (m_opaque_sp)
246 m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex (index);
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000247}
248
249uint32_t
250SBBreakpoint::GetThreadIndex() const
251{
Greg Clayton63094e02010-06-23 01:19:29 +0000252 if (m_opaque_sp)
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000253 {
Greg Clayton63094e02010-06-23 01:19:29 +0000254 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpec();
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000255 if (thread_spec == NULL)
256 return 0;
257 else
258 return thread_spec->GetIndex();
259 }
260 return 0;
261}
262
263
264void
265SBBreakpoint::SetThreadName (const char *thread_name)
266{
Greg Clayton63094e02010-06-23 01:19:29 +0000267 if (m_opaque_sp)
268 m_opaque_sp->GetOptions()->GetThreadSpec()->SetName (thread_name);
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000269}
270
271const char *
272SBBreakpoint::GetThreadName () const
273{
Greg Clayton63094e02010-06-23 01:19:29 +0000274 if (m_opaque_sp)
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000275 {
Greg Clayton63094e02010-06-23 01:19:29 +0000276 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpec();
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000277 if (thread_spec == NULL)
278 return NULL;
279 else
280 return thread_spec->GetName();
281 }
282 return NULL;
283}
284
285void
286SBBreakpoint::SetQueueName (const char *queue_name)
287{
Greg Clayton63094e02010-06-23 01:19:29 +0000288 if (m_opaque_sp)
289 m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName (queue_name);
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000290}
291
292const char *
293SBBreakpoint::GetQueueName () const
294{
Greg Clayton63094e02010-06-23 01:19:29 +0000295 if (m_opaque_sp)
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000296 {
Greg Clayton63094e02010-06-23 01:19:29 +0000297 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpec();
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000298 if (thread_spec == NULL)
299 return NULL;
300 else
301 return thread_spec->GetQueueName();
302 }
303 return NULL;
304}
305
Chris Lattner24943d22010-06-08 16:52:24 +0000306size_t
307SBBreakpoint::GetNumResolvedLocations() const
308{
Greg Clayton63094e02010-06-23 01:19:29 +0000309 if (m_opaque_sp)
310 return m_opaque_sp->GetNumResolvedLocations();
Chris Lattner24943d22010-06-08 16:52:24 +0000311 else
312 return 0;
313}
314
315size_t
316SBBreakpoint::GetNumLocations() const
317{
Greg Clayton63094e02010-06-23 01:19:29 +0000318 if (m_opaque_sp)
319 return m_opaque_sp->GetNumLocations();
Chris Lattner24943d22010-06-08 16:52:24 +0000320 else
321 return 0;
322}
323
324void
Caroline Ticedfc91c32010-09-15 18:29:06 +0000325SBBreakpoint::GetDescription (FILE *f, const char *description_level)
Chris Lattner24943d22010-06-08 16:52:24 +0000326{
327 if (f == NULL)
328 return;
329
Greg Clayton63094e02010-06-23 01:19:29 +0000330 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000331 {
332 DescriptionLevel level;
333 if (strcmp (description_level, "brief") == 0)
334 level = eDescriptionLevelBrief;
335 else if (strcmp (description_level, "full") == 0)
336 level = eDescriptionLevelFull;
337 else if (strcmp (description_level, "verbose") == 0)
338 level = eDescriptionLevelVerbose;
339 else
340 level = eDescriptionLevelBrief;
341
342 StreamFile str (f);
343
Greg Clayton63094e02010-06-23 01:19:29 +0000344 m_opaque_sp->GetDescription (&str, level);
Chris Lattner24943d22010-06-08 16:52:24 +0000345 str.EOL();
Chris Lattner24943d22010-06-08 16:52:24 +0000346 }
347}
348
349bool
350SBBreakpoint::PrivateBreakpointHitCallback
351(
352 void *baton,
353 StoppointCallbackContext *ctx,
354 lldb::user_id_t break_id,
355 lldb::user_id_t break_loc_id
356)
357{
Greg Clayton63094e02010-06-23 01:19:29 +0000358 BreakpointSP bp_sp(ctx->exe_ctx.target->GetBreakpointList().FindBreakpointByID(break_id));
Chris Lattner24943d22010-06-08 16:52:24 +0000359 if (baton && bp_sp)
360 {
361 CallbackData *data = (CallbackData *)baton;
362 lldb_private::Breakpoint *bp = bp_sp.get();
363 if (bp && data->callback)
364 {
Greg Clayton63094e02010-06-23 01:19:29 +0000365 if (ctx->exe_ctx.process)
Chris Lattner24943d22010-06-08 16:52:24 +0000366 {
Greg Clayton63094e02010-06-23 01:19:29 +0000367 SBProcess sb_process (ctx->exe_ctx.process->GetSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000368 SBThread sb_thread;
369 SBBreakpointLocation sb_location;
370 assert (bp_sp);
371 sb_location.SetLocation (bp_sp->FindLocationByID (break_loc_id));
Greg Clayton63094e02010-06-23 01:19:29 +0000372 if (ctx->exe_ctx.thread)
373 sb_thread.SetThread(ctx->exe_ctx.thread->GetSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000374
375 return data->callback (data->callback_baton,
376 sb_process,
377 sb_thread,
378 sb_location);
379 }
380 }
381 }
382 return true; // Return true if we should stop at this breakpoint
383}
384
385void
386SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton)
387{
Greg Clayton63094e02010-06-23 01:19:29 +0000388 if (m_opaque_sp.get())
Chris Lattner24943d22010-06-08 16:52:24 +0000389 {
390 BatonSP baton_sp(new SBBreakpointCallbackBaton (callback, baton));
Greg Clayton63094e02010-06-23 01:19:29 +0000391 m_opaque_sp->SetCallback (SBBreakpoint::PrivateBreakpointHitCallback, baton_sp, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000392 }
393}
394
395
396lldb_private::Breakpoint *
397SBBreakpoint::operator->() const
398{
Greg Clayton63094e02010-06-23 01:19:29 +0000399 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000400}
401
402lldb_private::Breakpoint *
403SBBreakpoint::get() const
404{
Greg Clayton63094e02010-06-23 01:19:29 +0000405 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000406}
407
408lldb::BreakpointSP &
409SBBreakpoint::operator *()
410{
Greg Clayton63094e02010-06-23 01:19:29 +0000411 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000412}
413
414const lldb::BreakpointSP &
415SBBreakpoint::operator *() const
416{
Greg Clayton63094e02010-06-23 01:19:29 +0000417 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000418}
419
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000420BreakpointEventType
421SBBreakpoint::GetBreakpointEventTypeFromEvent (const SBEvent& event)
422{
423 if (event.IsValid())
424 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event.GetSP());
425 return eBreakpointEventTypeInvalidType;
426}
427
428SBBreakpoint
429SBBreakpoint::GetBreakpointFromEvent (const lldb::SBEvent& event)
430{
431 SBBreakpoint sb_breakpoint;
432 if (event.IsValid())
433 sb_breakpoint.m_opaque_sp = Breakpoint::BreakpointEventData::GetBreakpointFromEvent (event.GetSP());
434 return sb_breakpoint;
435}
436
437SBBreakpointLocation
438SBBreakpoint::GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx)
439{
440 SBBreakpointLocation sb_breakpoint_loc;
441 if (event.IsValid())
442 sb_breakpoint_loc.SetLocation (Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (event.GetSP(), loc_idx));
443 return sb_breakpoint_loc;
444}
445
446