blob: f8c52ef08938da18aa700a989edfdcc4579c6a2f [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
111SBBreakpoint::Dump (FILE *f)
112{
Greg Clayton63094e02010-06-23 01:19:29 +0000113 if (m_opaque_sp && f)
Chris Lattner24943d22010-06-08 16:52:24 +0000114 {
Chris Lattner24943d22010-06-08 16:52:24 +0000115 lldb_private::StreamFile str (f);
Greg Clayton63094e02010-06-23 01:19:29 +0000116 m_opaque_sp->Dump (&str);
Chris Lattner24943d22010-06-08 16:52:24 +0000117 }
118}
119
120void
121SBBreakpoint::ClearAllBreakpointSites ()
122{
Greg Clayton63094e02010-06-23 01:19:29 +0000123 if (m_opaque_sp)
124 m_opaque_sp->ClearAllBreakpointSites ();
Chris Lattner24943d22010-06-08 16:52:24 +0000125}
126
127SBBreakpointLocation
128SBBreakpoint::FindLocationByAddress (addr_t vm_addr)
129{
130 SBBreakpointLocation sb_bp_location;
131
Greg Clayton63094e02010-06-23 01:19:29 +0000132 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000133 {
134 if (vm_addr != LLDB_INVALID_ADDRESS)
135 {
136 Address address;
Greg Clayton63094e02010-06-23 01:19:29 +0000137 Process *sb_process = m_opaque_sp->GetTarget().GetProcessSP().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000138 if (sb_process == NULL || sb_process->ResolveLoadAddress (vm_addr, address) == false)
139 {
140 address.SetSection (NULL);
141 address.SetOffset (vm_addr);
142 }
Greg Clayton63094e02010-06-23 01:19:29 +0000143 sb_bp_location.SetLocation (m_opaque_sp->FindLocationByAddress (address));
Chris Lattner24943d22010-06-08 16:52:24 +0000144 }
145 }
146 return sb_bp_location;
147}
148
149break_id_t
150SBBreakpoint::FindLocationIDByAddress (addr_t vm_addr)
151{
152 break_id_t lldb_id = (break_id_t) 0;
153
Greg Clayton63094e02010-06-23 01:19:29 +0000154 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000155 {
156 if (vm_addr != LLDB_INVALID_ADDRESS)
157 {
158 Address address;
Greg Clayton63094e02010-06-23 01:19:29 +0000159 Process *sb_process = m_opaque_sp->GetTarget().GetProcessSP().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000160 if (sb_process == NULL || sb_process->ResolveLoadAddress (vm_addr, address) == false)
161 {
162 address.SetSection (NULL);
163 address.SetOffset (vm_addr);
164 }
Greg Clayton63094e02010-06-23 01:19:29 +0000165 lldb_id = m_opaque_sp->FindLocationIDByAddress (address);
Chris Lattner24943d22010-06-08 16:52:24 +0000166 }
167 }
168
169 return lldb_id;
170}
171
172SBBreakpointLocation
173SBBreakpoint::FindLocationByID (break_id_t bp_loc_id)
174{
175 SBBreakpointLocation sb_bp_location;
176
Greg Clayton63094e02010-06-23 01:19:29 +0000177 if (m_opaque_sp)
178 sb_bp_location.SetLocation (m_opaque_sp->FindLocationByID (bp_loc_id));
Chris Lattner24943d22010-06-08 16:52:24 +0000179
180 return sb_bp_location;
181}
182
183SBBreakpointLocation
184SBBreakpoint::GetLocationAtIndex (uint32_t index)
185{
186 SBBreakpointLocation sb_bp_location;
187
Greg Clayton63094e02010-06-23 01:19:29 +0000188 if (m_opaque_sp)
189 sb_bp_location.SetLocation (m_opaque_sp->GetLocationAtIndex (index));
Chris Lattner24943d22010-06-08 16:52:24 +0000190
191 return sb_bp_location;
192}
193
194void
195SBBreakpoint::ListLocations (FILE* f, const char *description_level)
196{
Greg Clayton63094e02010-06-23 01:19:29 +0000197 if (m_opaque_sp && f)
Chris Lattner24943d22010-06-08 16:52:24 +0000198 {
199 DescriptionLevel level;
200 if (strcmp (description_level, "brief") == 0)
201 level = eDescriptionLevelBrief;
202 else if (strcmp (description_level, "full") == 0)
203 level = eDescriptionLevelFull;
204 else if (strcmp (description_level, "verbose") == 0)
205 level = eDescriptionLevelVerbose;
206 else
207 level = eDescriptionLevelBrief;
208
209 StreamFile str (f);
210
211 str.IndentMore();
Greg Clayton63094e02010-06-23 01:19:29 +0000212 int num_locs = m_opaque_sp->GetNumLocations();
Chris Lattner24943d22010-06-08 16:52:24 +0000213 for (int i = 0; i < num_locs; ++i)
214 {
Greg Clayton63094e02010-06-23 01:19:29 +0000215 BreakpointLocation *loc = m_opaque_sp->GetLocationAtIndex (i).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000216 loc->GetDescription (&str, level);
217 str.EOL();
218 }
219 }
220}
221
222void
223SBBreakpoint::SetEnabled (bool enable)
224{
Greg Clayton63094e02010-06-23 01:19:29 +0000225 if (m_opaque_sp)
226 m_opaque_sp->SetEnabled (enable);
Chris Lattner24943d22010-06-08 16:52:24 +0000227}
228
229bool
230SBBreakpoint::IsEnabled ()
231{
Greg Clayton63094e02010-06-23 01:19:29 +0000232 if (m_opaque_sp)
233 return m_opaque_sp->IsEnabled();
Chris Lattner24943d22010-06-08 16:52:24 +0000234 else
235 return false;
236}
237
238void
Greg Clayton54e7afa2010-07-09 20:39:50 +0000239SBBreakpoint::SetIgnoreCount (uint32_t count)
Chris Lattner24943d22010-06-08 16:52:24 +0000240{
Greg Clayton63094e02010-06-23 01:19:29 +0000241 if (m_opaque_sp)
242 m_opaque_sp->SetIgnoreCount (count);
Chris Lattner24943d22010-06-08 16:52:24 +0000243}
244
Greg Clayton54e7afa2010-07-09 20:39:50 +0000245uint32_t
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000246SBBreakpoint::GetHitCount () const
247{
248 if (m_opaque_sp)
249 return m_opaque_sp->GetHitCount();
250 else
251 return 0;
252}
253
254uint32_t
Chris Lattner24943d22010-06-08 16:52:24 +0000255SBBreakpoint::GetIgnoreCount () const
256{
Greg Clayton63094e02010-06-23 01:19:29 +0000257 if (m_opaque_sp)
258 return m_opaque_sp->GetIgnoreCount();
Chris Lattner24943d22010-06-08 16:52:24 +0000259 else
260 return 0;
261}
262
263void
264SBBreakpoint::SetThreadID (tid_t sb_thread_id)
265{
Greg Clayton63094e02010-06-23 01:19:29 +0000266 if (m_opaque_sp)
267 m_opaque_sp->SetThreadID (sb_thread_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000268}
269
270tid_t
271SBBreakpoint::GetThreadID ()
272{
273 tid_t lldb_thread_id = LLDB_INVALID_THREAD_ID;
Greg Clayton63094e02010-06-23 01:19:29 +0000274 if (m_opaque_sp)
275 lldb_thread_id = m_opaque_sp->GetThreadID();
Chris Lattner24943d22010-06-08 16:52:24 +0000276
277 return lldb_thread_id;
278}
279
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000280void
281SBBreakpoint::SetThreadIndex (uint32_t index)
282{
Greg Clayton63094e02010-06-23 01:19:29 +0000283 if (m_opaque_sp)
284 m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex (index);
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000285}
286
287uint32_t
288SBBreakpoint::GetThreadIndex() const
289{
Greg Clayton63094e02010-06-23 01:19:29 +0000290 if (m_opaque_sp)
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000291 {
Greg Clayton63094e02010-06-23 01:19:29 +0000292 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpec();
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000293 if (thread_spec == NULL)
294 return 0;
295 else
296 return thread_spec->GetIndex();
297 }
298 return 0;
299}
300
301
302void
303SBBreakpoint::SetThreadName (const char *thread_name)
304{
Greg Clayton63094e02010-06-23 01:19:29 +0000305 if (m_opaque_sp)
306 m_opaque_sp->GetOptions()->GetThreadSpec()->SetName (thread_name);
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000307}
308
309const char *
310SBBreakpoint::GetThreadName () const
311{
Greg Clayton63094e02010-06-23 01:19:29 +0000312 if (m_opaque_sp)
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000313 {
Greg Clayton63094e02010-06-23 01:19:29 +0000314 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpec();
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000315 if (thread_spec == NULL)
316 return NULL;
317 else
318 return thread_spec->GetName();
319 }
320 return NULL;
321}
322
323void
324SBBreakpoint::SetQueueName (const char *queue_name)
325{
Greg Clayton63094e02010-06-23 01:19:29 +0000326 if (m_opaque_sp)
327 m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName (queue_name);
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000328}
329
330const char *
331SBBreakpoint::GetQueueName () const
332{
Greg Clayton63094e02010-06-23 01:19:29 +0000333 if (m_opaque_sp)
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000334 {
Greg Clayton63094e02010-06-23 01:19:29 +0000335 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpec();
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000336 if (thread_spec == NULL)
337 return NULL;
338 else
339 return thread_spec->GetQueueName();
340 }
341 return NULL;
342}
343
Chris Lattner24943d22010-06-08 16:52:24 +0000344size_t
345SBBreakpoint::GetNumResolvedLocations() const
346{
Greg Clayton63094e02010-06-23 01:19:29 +0000347 if (m_opaque_sp)
348 return m_opaque_sp->GetNumResolvedLocations();
Chris Lattner24943d22010-06-08 16:52:24 +0000349 else
350 return 0;
351}
352
353size_t
354SBBreakpoint::GetNumLocations() const
355{
Greg Clayton63094e02010-06-23 01:19:29 +0000356 if (m_opaque_sp)
357 return m_opaque_sp->GetNumLocations();
Chris Lattner24943d22010-06-08 16:52:24 +0000358 else
359 return 0;
360}
361
362void
363SBBreakpoint::GetDescription (FILE *f, const char *description_level, bool describe_locations)
364{
365 if (f == NULL)
366 return;
367
Greg Clayton63094e02010-06-23 01:19:29 +0000368 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000369 {
370 DescriptionLevel level;
371 if (strcmp (description_level, "brief") == 0)
372 level = eDescriptionLevelBrief;
373 else if (strcmp (description_level, "full") == 0)
374 level = eDescriptionLevelFull;
375 else if (strcmp (description_level, "verbose") == 0)
376 level = eDescriptionLevelVerbose;
377 else
378 level = eDescriptionLevelBrief;
379
380 StreamFile str (f);
381
Greg Clayton63094e02010-06-23 01:19:29 +0000382 m_opaque_sp->GetDescription (&str, level);
Chris Lattner24943d22010-06-08 16:52:24 +0000383 str.EOL();
384 if (describe_locations)
385 {
386 //str.IndentMore();
Greg Clayton63094e02010-06-23 01:19:29 +0000387 // int num_locs = m_opaque_sp->GetNumLocations();
Chris Lattner24943d22010-06-08 16:52:24 +0000388 // for (int i = 0; i < num_locs; ++i)
389 // {
Greg Clayton63094e02010-06-23 01:19:29 +0000390 // BreakpointLocation *loc = m_opaque_sp->FindLocationByIndex (i);
Chris Lattner24943d22010-06-08 16:52:24 +0000391 // loc->GetDescription (&str, level);
392 // str.EOL();
393 // }
394 ListLocations (f, description_level);
395 }
396 }
397}
398
399bool
400SBBreakpoint::PrivateBreakpointHitCallback
401(
402 void *baton,
403 StoppointCallbackContext *ctx,
404 lldb::user_id_t break_id,
405 lldb::user_id_t break_loc_id
406)
407{
Greg Clayton63094e02010-06-23 01:19:29 +0000408 BreakpointSP bp_sp(ctx->exe_ctx.target->GetBreakpointList().FindBreakpointByID(break_id));
Chris Lattner24943d22010-06-08 16:52:24 +0000409 if (baton && bp_sp)
410 {
411 CallbackData *data = (CallbackData *)baton;
412 lldb_private::Breakpoint *bp = bp_sp.get();
413 if (bp && data->callback)
414 {
Greg Clayton63094e02010-06-23 01:19:29 +0000415 if (ctx->exe_ctx.process)
Chris Lattner24943d22010-06-08 16:52:24 +0000416 {
Greg Clayton63094e02010-06-23 01:19:29 +0000417 SBProcess sb_process (ctx->exe_ctx.process->GetSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000418 SBThread sb_thread;
419 SBBreakpointLocation sb_location;
420 assert (bp_sp);
421 sb_location.SetLocation (bp_sp->FindLocationByID (break_loc_id));
Greg Clayton63094e02010-06-23 01:19:29 +0000422 if (ctx->exe_ctx.thread)
423 sb_thread.SetThread(ctx->exe_ctx.thread->GetSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000424
425 return data->callback (data->callback_baton,
426 sb_process,
427 sb_thread,
428 sb_location);
429 }
430 }
431 }
432 return true; // Return true if we should stop at this breakpoint
433}
434
435void
436SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton)
437{
Greg Clayton63094e02010-06-23 01:19:29 +0000438 if (m_opaque_sp.get())
Chris Lattner24943d22010-06-08 16:52:24 +0000439 {
440 BatonSP baton_sp(new SBBreakpointCallbackBaton (callback, baton));
Greg Clayton63094e02010-06-23 01:19:29 +0000441 m_opaque_sp->SetCallback (SBBreakpoint::PrivateBreakpointHitCallback, baton_sp, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000442 }
443}
444
445
446lldb_private::Breakpoint *
447SBBreakpoint::operator->() const
448{
Greg Clayton63094e02010-06-23 01:19:29 +0000449 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000450}
451
452lldb_private::Breakpoint *
453SBBreakpoint::get() const
454{
Greg Clayton63094e02010-06-23 01:19:29 +0000455 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000456}
457
458lldb::BreakpointSP &
459SBBreakpoint::operator *()
460{
Greg Clayton63094e02010-06-23 01:19:29 +0000461 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000462}
463
464const lldb::BreakpointSP &
465SBBreakpoint::operator *() const
466{
Greg Clayton63094e02010-06-23 01:19:29 +0000467 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000468}
469
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000470BreakpointEventType
471SBBreakpoint::GetBreakpointEventTypeFromEvent (const SBEvent& event)
472{
473 if (event.IsValid())
474 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event.GetSP());
475 return eBreakpointEventTypeInvalidType;
476}
477
478SBBreakpoint
479SBBreakpoint::GetBreakpointFromEvent (const lldb::SBEvent& event)
480{
481 SBBreakpoint sb_breakpoint;
482 if (event.IsValid())
483 sb_breakpoint.m_opaque_sp = Breakpoint::BreakpointEventData::GetBreakpointFromEvent (event.GetSP());
484 return sb_breakpoint;
485}
486
487SBBreakpointLocation
488SBBreakpoint::GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx)
489{
490 SBBreakpointLocation sb_breakpoint_loc;
491 if (event.IsValid())
492 sb_breakpoint_loc.SetLocation (Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (event.GetSP(), loc_idx));
493 return sb_breakpoint_loc;
494}
495
496