1 //===-- 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"
13 #include "lldb/API/SBEvent.h"
14 #include "lldb/API/SBProcess.h"
15 #include "lldb/API/SBStream.h"
16 #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/Log.h"
23 #include "lldb/Core/Stream.h"
24 #include "lldb/Core/StreamFile.h"
25 #include "lldb/Target/Process.h"
26 #include "lldb/Target/Target.h"
27 #include "lldb/Target/Thread.h"
28 #include "lldb/Target/ThreadSpec.h"
29
30
31 #include "lldb/lldb-enumerations.h"
32
33 using namespace lldb;
34 using namespace lldb_private;
35
36 struct CallbackData
37 {
38 SBBreakpoint::BreakpointHitCallback callback;
39 void *callback_baton;
40 };
41
42 class SBBreakpointCallbackBaton : public Baton
43 {
44 public:
45
SBBreakpointCallbackBaton(SBBreakpoint::BreakpointHitCallback callback,void * baton)46 SBBreakpointCallbackBaton (SBBreakpoint::BreakpointHitCallback callback, void *baton) :
47 Baton (new CallbackData)
48 {
49 CallbackData *data = (CallbackData *)m_data;
50 data->callback = callback;
51 data->callback_baton = baton;
52 }
53
~SBBreakpointCallbackBaton()54 virtual ~SBBreakpointCallbackBaton()
55 {
56 CallbackData *data = (CallbackData *)m_data;
57
58 if (data)
59 {
60 delete data;
61 m_data = NULL;
62 }
63 }
64 };
65
66
SBBreakpoint()67 SBBreakpoint::SBBreakpoint () :
68 m_opaque_sp ()
69 {
70 }
71
SBBreakpoint(const SBBreakpoint & rhs)72 SBBreakpoint::SBBreakpoint (const SBBreakpoint& rhs) :
73 m_opaque_sp (rhs.m_opaque_sp)
74 {
75 }
76
77
SBBreakpoint(const lldb::BreakpointSP & bp_sp)78 SBBreakpoint::SBBreakpoint (const lldb::BreakpointSP &bp_sp) :
79 m_opaque_sp (bp_sp)
80 {
81 }
82
~SBBreakpoint()83 SBBreakpoint::~SBBreakpoint()
84 {
85 }
86
87 const SBBreakpoint &
operator =(const SBBreakpoint & rhs)88 SBBreakpoint::operator = (const SBBreakpoint& rhs)
89 {
90 if (this != &rhs)
91 m_opaque_sp = rhs.m_opaque_sp;
92 return *this;
93 }
94
95 bool
operator ==(const lldb::SBBreakpoint & rhs)96 SBBreakpoint::operator == (const lldb::SBBreakpoint& rhs)
97 {
98 if (m_opaque_sp && rhs.m_opaque_sp)
99 return m_opaque_sp.get() == rhs.m_opaque_sp.get();
100 return false;
101 }
102
103 bool
operator !=(const lldb::SBBreakpoint & rhs)104 SBBreakpoint::operator != (const lldb::SBBreakpoint& rhs)
105 {
106 if (m_opaque_sp && rhs.m_opaque_sp)
107 return m_opaque_sp.get() != rhs.m_opaque_sp.get();
108 return (m_opaque_sp && !rhs.m_opaque_sp) || (rhs.m_opaque_sp && !m_opaque_sp);
109 }
110
111 break_id_t
GetID() const112 SBBreakpoint::GetID () const
113 {
114 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
115
116 break_id_t break_id = LLDB_INVALID_BREAK_ID;
117 if (m_opaque_sp)
118 break_id = m_opaque_sp->GetID();
119
120 if (log)
121 {
122 if (break_id == LLDB_INVALID_BREAK_ID)
123 log->Printf ("SBBreakpoint(%p)::GetID () => LLDB_INVALID_BREAK_ID", m_opaque_sp.get());
124 else
125 log->Printf ("SBBreakpoint(%p)::GetID () => %u", m_opaque_sp.get(), break_id);
126 }
127
128 return break_id;
129 }
130
131
132 bool
IsValid() const133 SBBreakpoint::IsValid() const
134 {
135 return (bool) m_opaque_sp;
136 }
137
138 void
ClearAllBreakpointSites()139 SBBreakpoint::ClearAllBreakpointSites ()
140 {
141 if (m_opaque_sp)
142 {
143 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
144 m_opaque_sp->ClearAllBreakpointSites ();
145 }
146 }
147
148 SBBreakpointLocation
FindLocationByAddress(addr_t vm_addr)149 SBBreakpoint::FindLocationByAddress (addr_t vm_addr)
150 {
151 SBBreakpointLocation sb_bp_location;
152
153 if (m_opaque_sp)
154 {
155 if (vm_addr != LLDB_INVALID_ADDRESS)
156 {
157 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
158 Address address;
159 Target &target = m_opaque_sp->GetTarget();
160 if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false)
161 {
162 address.SetRawAddress (vm_addr);
163 }
164 sb_bp_location.SetLocation (m_opaque_sp->FindLocationByAddress (address));
165 }
166 }
167 return sb_bp_location;
168 }
169
170 break_id_t
FindLocationIDByAddress(addr_t vm_addr)171 SBBreakpoint::FindLocationIDByAddress (addr_t vm_addr)
172 {
173 break_id_t break_id = LLDB_INVALID_BREAK_ID;
174
175 if (m_opaque_sp && vm_addr != LLDB_INVALID_ADDRESS)
176 {
177 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
178 Address address;
179 Target &target = m_opaque_sp->GetTarget();
180 if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false)
181 {
182 address.SetRawAddress (vm_addr);
183 }
184 break_id = m_opaque_sp->FindLocationIDByAddress (address);
185 }
186
187 return break_id;
188 }
189
190 SBBreakpointLocation
FindLocationByID(break_id_t bp_loc_id)191 SBBreakpoint::FindLocationByID (break_id_t bp_loc_id)
192 {
193 SBBreakpointLocation sb_bp_location;
194
195 if (m_opaque_sp)
196 {
197 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
198 sb_bp_location.SetLocation (m_opaque_sp->FindLocationByID (bp_loc_id));
199 }
200
201 return sb_bp_location;
202 }
203
204 SBBreakpointLocation
GetLocationAtIndex(uint32_t index)205 SBBreakpoint::GetLocationAtIndex (uint32_t index)
206 {
207 SBBreakpointLocation sb_bp_location;
208
209 if (m_opaque_sp)
210 {
211 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
212 sb_bp_location.SetLocation (m_opaque_sp->GetLocationAtIndex (index));
213 }
214
215 return sb_bp_location;
216 }
217
218 void
SetEnabled(bool enable)219 SBBreakpoint::SetEnabled (bool enable)
220 {
221 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
222
223 if (log)
224 log->Printf ("SBBreakpoint(%p)::SetEnabled (enabled=%i)", m_opaque_sp.get(), enable);
225
226 if (m_opaque_sp)
227 {
228 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
229 m_opaque_sp->SetEnabled (enable);
230 }
231 }
232
233 bool
IsEnabled()234 SBBreakpoint::IsEnabled ()
235 {
236 if (m_opaque_sp)
237 {
238 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
239 return m_opaque_sp->IsEnabled();
240 }
241 else
242 return false;
243 }
244
245 void
SetOneShot(bool one_shot)246 SBBreakpoint::SetOneShot (bool one_shot)
247 {
248 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
249
250 if (log)
251 log->Printf ("SBBreakpoint(%p)::SetOneShot (one_shot=%i)", m_opaque_sp.get(), one_shot);
252
253 if (m_opaque_sp)
254 {
255 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
256 m_opaque_sp->SetOneShot (one_shot);
257 }
258 }
259
260 bool
IsOneShot() const261 SBBreakpoint::IsOneShot () const
262 {
263 if (m_opaque_sp)
264 {
265 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
266 return m_opaque_sp->IsOneShot();
267 }
268 else
269 return false;
270 }
271
272 bool
IsInternal()273 SBBreakpoint::IsInternal ()
274 {
275 if (m_opaque_sp)
276 {
277 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
278 return m_opaque_sp->IsInternal();
279 }
280 else
281 return false;
282 }
283
284 void
SetIgnoreCount(uint32_t count)285 SBBreakpoint::SetIgnoreCount (uint32_t count)
286 {
287 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
288
289 if (log)
290 log->Printf ("SBBreakpoint(%p)::SetIgnoreCount (count=%u)", m_opaque_sp.get(), count);
291
292 if (m_opaque_sp)
293 {
294 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
295 m_opaque_sp->SetIgnoreCount (count);
296 }
297 }
298
299 void
SetCondition(const char * condition)300 SBBreakpoint::SetCondition (const char *condition)
301 {
302 if (m_opaque_sp)
303 {
304 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
305 m_opaque_sp->SetCondition (condition);
306 }
307 }
308
309 const char *
GetCondition()310 SBBreakpoint::GetCondition ()
311 {
312 if (m_opaque_sp)
313 {
314 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
315 return m_opaque_sp->GetConditionText ();
316 }
317 return NULL;
318 }
319
320 uint32_t
GetHitCount() const321 SBBreakpoint::GetHitCount () const
322 {
323 uint32_t count = 0;
324 if (m_opaque_sp)
325 {
326 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
327 count = m_opaque_sp->GetHitCount();
328 }
329
330 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
331 if (log)
332 log->Printf ("SBBreakpoint(%p)::GetHitCount () => %u", m_opaque_sp.get(), count);
333
334 return count;
335 }
336
337 uint32_t
GetIgnoreCount() const338 SBBreakpoint::GetIgnoreCount () const
339 {
340 uint32_t count = 0;
341 if (m_opaque_sp)
342 {
343 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
344 count = m_opaque_sp->GetIgnoreCount();
345 }
346
347 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
348 if (log)
349 log->Printf ("SBBreakpoint(%p)::GetIgnoreCount () => %u", m_opaque_sp.get(), count);
350
351 return count;
352 }
353
354 void
SetThreadID(tid_t tid)355 SBBreakpoint::SetThreadID (tid_t tid)
356 {
357 if (m_opaque_sp)
358 {
359 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
360 m_opaque_sp->SetThreadID (tid);
361 }
362 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
363 if (log)
364 log->Printf ("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4" PRIx64 ")", m_opaque_sp.get(), tid);
365
366 }
367
368 tid_t
GetThreadID()369 SBBreakpoint::GetThreadID ()
370 {
371 tid_t tid = LLDB_INVALID_THREAD_ID;
372 if (m_opaque_sp)
373 {
374 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
375 tid = m_opaque_sp->GetThreadID();
376 }
377
378 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
379 if (log)
380 log->Printf ("SBBreakpoint(%p)::GetThreadID () => 0x%4.4" PRIx64, m_opaque_sp.get(), tid);
381 return tid;
382 }
383
384 void
SetThreadIndex(uint32_t index)385 SBBreakpoint::SetThreadIndex (uint32_t index)
386 {
387 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
388 if (log)
389 log->Printf ("SBBreakpoint(%p)::SetThreadIndex (%u)", m_opaque_sp.get(), index);
390 if (m_opaque_sp)
391 {
392 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
393 m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex (index);
394 }
395 }
396
397 uint32_t
GetThreadIndex() const398 SBBreakpoint::GetThreadIndex() const
399 {
400 uint32_t thread_idx = UINT32_MAX;
401 if (m_opaque_sp)
402 {
403 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
404 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
405 if (thread_spec != NULL)
406 thread_idx = thread_spec->GetIndex();
407 }
408 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
409 if (log)
410 log->Printf ("SBBreakpoint(%p)::GetThreadIndex () => %u", m_opaque_sp.get(), thread_idx);
411
412 return thread_idx;
413 }
414
415
416 void
SetThreadName(const char * thread_name)417 SBBreakpoint::SetThreadName (const char *thread_name)
418 {
419 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
420 if (log)
421 log->Printf ("SBBreakpoint(%p)::SetThreadName (%s)", m_opaque_sp.get(), thread_name);
422
423 if (m_opaque_sp)
424 {
425 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
426 m_opaque_sp->GetOptions()->GetThreadSpec()->SetName (thread_name);
427 }
428 }
429
430 const char *
GetThreadName() const431 SBBreakpoint::GetThreadName () const
432 {
433 const char *name = NULL;
434 if (m_opaque_sp)
435 {
436 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
437 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
438 if (thread_spec != NULL)
439 name = thread_spec->GetName();
440 }
441 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
442 if (log)
443 log->Printf ("SBBreakpoint(%p)::GetThreadName () => %s", m_opaque_sp.get(), name);
444
445 return name;
446 }
447
448 void
SetQueueName(const char * queue_name)449 SBBreakpoint::SetQueueName (const char *queue_name)
450 {
451 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
452 if (log)
453 log->Printf ("SBBreakpoint(%p)::SetQueueName (%s)", m_opaque_sp.get(), queue_name);
454 if (m_opaque_sp)
455 {
456 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
457 m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName (queue_name);
458 }
459 }
460
461 const char *
GetQueueName() const462 SBBreakpoint::GetQueueName () const
463 {
464 const char *name = NULL;
465 if (m_opaque_sp)
466 {
467 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
468 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
469 if (thread_spec)
470 name = thread_spec->GetQueueName();
471 }
472 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
473 if (log)
474 log->Printf ("SBBreakpoint(%p)::GetQueueName () => %s", m_opaque_sp.get(), name);
475
476 return name;
477 }
478
479 size_t
GetNumResolvedLocations() const480 SBBreakpoint::GetNumResolvedLocations() const
481 {
482 size_t num_resolved = 0;
483 if (m_opaque_sp)
484 {
485 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
486 num_resolved = m_opaque_sp->GetNumResolvedLocations();
487 }
488 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
489 if (log)
490 log->Printf ("SBBreakpoint(%p)::GetNumResolvedLocations () => %" PRIu64, m_opaque_sp.get(), (uint64_t)num_resolved);
491 return num_resolved;
492 }
493
494 size_t
GetNumLocations() const495 SBBreakpoint::GetNumLocations() const
496 {
497 size_t num_locs = 0;
498 if (m_opaque_sp)
499 {
500 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
501 num_locs = m_opaque_sp->GetNumLocations();
502 }
503 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
504 if (log)
505 log->Printf ("SBBreakpoint(%p)::GetNumLocations () => %" PRIu64, m_opaque_sp.get(), (uint64_t)num_locs);
506 return num_locs;
507 }
508
509 bool
GetDescription(SBStream & s)510 SBBreakpoint::GetDescription (SBStream &s)
511 {
512 if (m_opaque_sp)
513 {
514 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
515 s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
516 m_opaque_sp->GetResolverDescription (s.get());
517 m_opaque_sp->GetFilterDescription (s.get());
518 const size_t num_locations = m_opaque_sp->GetNumLocations ();
519 s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
520 return true;
521 }
522 s.Printf ("No value");
523 return false;
524 }
525
526 bool
PrivateBreakpointHitCallback(void * baton,StoppointCallbackContext * ctx,lldb::user_id_t break_id,lldb::user_id_t break_loc_id)527 SBBreakpoint::PrivateBreakpointHitCallback
528 (
529 void *baton,
530 StoppointCallbackContext *ctx,
531 lldb::user_id_t break_id,
532 lldb::user_id_t break_loc_id
533 )
534 {
535 ExecutionContext exe_ctx (ctx->exe_ctx_ref);
536 BreakpointSP bp_sp(exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
537 if (baton && bp_sp)
538 {
539 CallbackData *data = (CallbackData *)baton;
540 lldb_private::Breakpoint *bp = bp_sp.get();
541 if (bp && data->callback)
542 {
543 Process *process = exe_ctx.GetProcessPtr();
544 if (process)
545 {
546 SBProcess sb_process (process->shared_from_this());
547 SBThread sb_thread;
548 SBBreakpointLocation sb_location;
549 assert (bp_sp);
550 sb_location.SetLocation (bp_sp->FindLocationByID (break_loc_id));
551 Thread *thread = exe_ctx.GetThreadPtr();
552 if (thread)
553 sb_thread.SetThread(thread->shared_from_this());
554
555 return data->callback (data->callback_baton,
556 sb_process,
557 sb_thread,
558 sb_location);
559 }
560 }
561 }
562 return true; // Return true if we should stop at this breakpoint
563 }
564
565 void
SetCallback(BreakpointHitCallback callback,void * baton)566 SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton)
567 {
568 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
569
570 if (log)
571 log->Printf ("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)", m_opaque_sp.get(), callback, baton);
572
573 if (m_opaque_sp)
574 {
575 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
576 BatonSP baton_sp(new SBBreakpointCallbackBaton (callback, baton));
577 m_opaque_sp->SetCallback (SBBreakpoint::PrivateBreakpointHitCallback, baton_sp, false);
578 }
579 }
580
581
582 lldb_private::Breakpoint *
operator ->() const583 SBBreakpoint::operator->() const
584 {
585 return m_opaque_sp.get();
586 }
587
588 lldb_private::Breakpoint *
get() const589 SBBreakpoint::get() const
590 {
591 return m_opaque_sp.get();
592 }
593
594 lldb::BreakpointSP &
operator *()595 SBBreakpoint::operator *()
596 {
597 return m_opaque_sp;
598 }
599
600 const lldb::BreakpointSP &
operator *() const601 SBBreakpoint::operator *() const
602 {
603 return m_opaque_sp;
604 }
605
606 bool
EventIsBreakpointEvent(const lldb::SBEvent & event)607 SBBreakpoint::EventIsBreakpointEvent (const lldb::SBEvent &event)
608 {
609 return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) != NULL;
610
611 }
612
613 BreakpointEventType
GetBreakpointEventTypeFromEvent(const SBEvent & event)614 SBBreakpoint::GetBreakpointEventTypeFromEvent (const SBEvent& event)
615 {
616 if (event.IsValid())
617 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event.GetSP());
618 return eBreakpointEventTypeInvalidType;
619 }
620
621 SBBreakpoint
GetBreakpointFromEvent(const lldb::SBEvent & event)622 SBBreakpoint::GetBreakpointFromEvent (const lldb::SBEvent& event)
623 {
624 SBBreakpoint sb_breakpoint;
625 if (event.IsValid())
626 sb_breakpoint.m_opaque_sp = Breakpoint::BreakpointEventData::GetBreakpointFromEvent (event.GetSP());
627 return sb_breakpoint;
628 }
629
630 SBBreakpointLocation
GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent & event,uint32_t loc_idx)631 SBBreakpoint::GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx)
632 {
633 SBBreakpointLocation sb_breakpoint_loc;
634 if (event.IsValid())
635 sb_breakpoint_loc.SetLocation (Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (event.GetSP(), loc_idx));
636 return sb_breakpoint_loc;
637 }
638
639 uint32_t
GetNumBreakpointLocationsFromEvent(const lldb::SBEvent & event)640 SBBreakpoint::GetNumBreakpointLocationsFromEvent (const lldb::SBEvent &event)
641 {
642 uint32_t num_locations = 0;
643 if (event.IsValid())
644 num_locations = (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (event.GetSP()));
645 return num_locations;
646 }
647
648
649