1 //===-- Breakpoint.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
11 // C Includes
12 // C++ Includes
13 // Other libraries and framework includes
14 // Project includes
15
16 #include "lldb/Core/Address.h"
17 #include "lldb/Breakpoint/Breakpoint.h"
18 #include "lldb/Breakpoint/BreakpointLocation.h"
19 #include "lldb/Breakpoint/BreakpointLocationCollection.h"
20 #include "lldb/Breakpoint/BreakpointResolver.h"
21 #include "lldb/Breakpoint/BreakpointResolverFileLine.h"
22 #include "lldb/Core/Log.h"
23 #include "lldb/Core/ModuleList.h"
24 #include "lldb/Core/SearchFilter.h"
25 #include "lldb/Core/Section.h"
26 #include "lldb/Core/Stream.h"
27 #include "lldb/Core/StreamString.h"
28 #include "lldb/Symbol/SymbolContext.h"
29 #include "lldb/Target/Target.h"
30 #include "lldb/Target/ThreadSpec.h"
31 #include "lldb/lldb-private-log.h"
32 #include "llvm/Support/Casting.h"
33
34 using namespace lldb;
35 using namespace lldb_private;
36 using namespace llvm;
37
38 const ConstString &
GetEventIdentifier()39 Breakpoint::GetEventIdentifier ()
40 {
41 static ConstString g_identifier("event-identifier.breakpoint.changed");
42 return g_identifier;
43 }
44
45 //----------------------------------------------------------------------
46 // Breakpoint constructor
47 //----------------------------------------------------------------------
Breakpoint(Target & target,SearchFilterSP & filter_sp,BreakpointResolverSP & resolver_sp)48 Breakpoint::Breakpoint(Target &target, SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp) :
49 m_being_created(true),
50 m_target (target),
51 m_filter_sp (filter_sp),
52 m_resolver_sp (resolver_sp),
53 m_options (),
54 m_locations (*this)
55 {
56 m_being_created = false;
57 }
58
59 //----------------------------------------------------------------------
60 // Destructor
61 //----------------------------------------------------------------------
~Breakpoint()62 Breakpoint::~Breakpoint()
63 {
64 }
65
66 bool
IsInternal() const67 Breakpoint::IsInternal () const
68 {
69 return LLDB_BREAK_ID_IS_INTERNAL(m_bid);
70 }
71
72
73
74 Target&
GetTarget()75 Breakpoint::GetTarget ()
76 {
77 return m_target;
78 }
79
80 const Target&
GetTarget() const81 Breakpoint::GetTarget () const
82 {
83 return m_target;
84 }
85
86 BreakpointLocationSP
AddLocation(const Address & addr,bool * new_location)87 Breakpoint::AddLocation (const Address &addr, bool *new_location)
88 {
89 return m_locations.AddLocation (addr, new_location);
90 }
91
92 BreakpointLocationSP
FindLocationByAddress(const Address & addr)93 Breakpoint::FindLocationByAddress (const Address &addr)
94 {
95 return m_locations.FindByAddress(addr);
96 }
97
98 break_id_t
FindLocationIDByAddress(const Address & addr)99 Breakpoint::FindLocationIDByAddress (const Address &addr)
100 {
101 return m_locations.FindIDByAddress(addr);
102 }
103
104 BreakpointLocationSP
FindLocationByID(break_id_t bp_loc_id)105 Breakpoint::FindLocationByID (break_id_t bp_loc_id)
106 {
107 return m_locations.FindByID(bp_loc_id);
108 }
109
110 BreakpointLocationSP
GetLocationAtIndex(size_t index)111 Breakpoint::GetLocationAtIndex (size_t index)
112 {
113 return m_locations.GetByIndex(index);
114 }
115
116 // For each of the overall options we need to decide how they propagate to
117 // the location options. This will determine the precedence of options on
118 // the breakpoint vs. its locations.
119
120 // Disable at the breakpoint level should override the location settings.
121 // That way you can conveniently turn off a whole breakpoint without messing
122 // up the individual settings.
123
124 void
SetEnabled(bool enable)125 Breakpoint::SetEnabled (bool enable)
126 {
127 if (enable == m_options.IsEnabled())
128 return;
129
130 m_options.SetEnabled(enable);
131 if (enable)
132 m_locations.ResolveAllBreakpointSites();
133 else
134 m_locations.ClearAllBreakpointSites();
135
136 SendBreakpointChangedEvent (enable ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
137
138 }
139
140 bool
IsEnabled()141 Breakpoint::IsEnabled ()
142 {
143 return m_options.IsEnabled();
144 }
145
146 void
SetIgnoreCount(uint32_t n)147 Breakpoint::SetIgnoreCount (uint32_t n)
148 {
149 if (m_options.GetIgnoreCount() == n)
150 return;
151
152 m_options.SetIgnoreCount(n);
153 SendBreakpointChangedEvent (eBreakpointEventTypeIgnoreChanged);
154 }
155
156 void
DecrementIgnoreCount()157 Breakpoint::DecrementIgnoreCount ()
158 {
159 uint32_t ignore = m_options.GetIgnoreCount();
160 if (ignore != 0)
161 m_options.SetIgnoreCount(ignore - 1);
162 }
163
164 uint32_t
GetIgnoreCount() const165 Breakpoint::GetIgnoreCount () const
166 {
167 return m_options.GetIgnoreCount();
168 }
169
170 bool
IgnoreCountShouldStop()171 Breakpoint::IgnoreCountShouldStop ()
172 {
173 uint32_t ignore = GetIgnoreCount();
174 if (ignore != 0)
175 {
176 // When we get here we know the location that caused the stop doesn't have an ignore count,
177 // since by contract we call it first... So we don't have to find & decrement it, we only have
178 // to decrement our own ignore count.
179 DecrementIgnoreCount();
180 return false;
181 }
182 else
183 return true;
184 }
185
186 uint32_t
GetHitCount() const187 Breakpoint::GetHitCount () const
188 {
189 return m_locations.GetHitCount();
190 }
191
192 bool
IsOneShot() const193 Breakpoint::IsOneShot () const
194 {
195 return m_options.IsOneShot();
196 }
197
198 void
SetOneShot(bool one_shot)199 Breakpoint::SetOneShot (bool one_shot)
200 {
201 m_options.SetOneShot (one_shot);
202 }
203
204 void
SetThreadID(lldb::tid_t thread_id)205 Breakpoint::SetThreadID (lldb::tid_t thread_id)
206 {
207 if (m_options.GetThreadSpec()->GetTID() == thread_id)
208 return;
209
210 m_options.GetThreadSpec()->SetTID(thread_id);
211 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
212 }
213
214 lldb::tid_t
GetThreadID() const215 Breakpoint::GetThreadID () const
216 {
217 if (m_options.GetThreadSpecNoCreate() == NULL)
218 return LLDB_INVALID_THREAD_ID;
219 else
220 return m_options.GetThreadSpecNoCreate()->GetTID();
221 }
222
223 void
SetThreadIndex(uint32_t index)224 Breakpoint::SetThreadIndex (uint32_t index)
225 {
226 if (m_options.GetThreadSpec()->GetIndex() == index)
227 return;
228
229 m_options.GetThreadSpec()->SetIndex(index);
230 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
231 }
232
233 uint32_t
GetThreadIndex() const234 Breakpoint::GetThreadIndex() const
235 {
236 if (m_options.GetThreadSpecNoCreate() == NULL)
237 return 0;
238 else
239 return m_options.GetThreadSpecNoCreate()->GetIndex();
240 }
241
242 void
SetThreadName(const char * thread_name)243 Breakpoint::SetThreadName (const char *thread_name)
244 {
245 if (m_options.GetThreadSpec()->GetName() != NULL
246 && ::strcmp (m_options.GetThreadSpec()->GetName(), thread_name) == 0)
247 return;
248
249 m_options.GetThreadSpec()->SetName (thread_name);
250 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
251 }
252
253 const char *
GetThreadName() const254 Breakpoint::GetThreadName () const
255 {
256 if (m_options.GetThreadSpecNoCreate() == NULL)
257 return NULL;
258 else
259 return m_options.GetThreadSpecNoCreate()->GetName();
260 }
261
262 void
SetQueueName(const char * queue_name)263 Breakpoint::SetQueueName (const char *queue_name)
264 {
265 if (m_options.GetThreadSpec()->GetQueueName() != NULL
266 && ::strcmp (m_options.GetThreadSpec()->GetQueueName(), queue_name) == 0)
267 return;
268
269 m_options.GetThreadSpec()->SetQueueName (queue_name);
270 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
271 }
272
273 const char *
GetQueueName() const274 Breakpoint::GetQueueName () const
275 {
276 if (m_options.GetThreadSpecNoCreate() == NULL)
277 return NULL;
278 else
279 return m_options.GetThreadSpecNoCreate()->GetQueueName();
280 }
281
282 void
SetCondition(const char * condition)283 Breakpoint::SetCondition (const char *condition)
284 {
285 m_options.SetCondition (condition);
286 SendBreakpointChangedEvent (eBreakpointEventTypeConditionChanged);
287 }
288
289 const char *
GetConditionText() const290 Breakpoint::GetConditionText () const
291 {
292 return m_options.GetConditionText();
293 }
294
295 // This function is used when "baton" doesn't need to be freed
296 void
SetCallback(BreakpointHitCallback callback,void * baton,bool is_synchronous)297 Breakpoint::SetCallback (BreakpointHitCallback callback, void *baton, bool is_synchronous)
298 {
299 // The default "Baton" class will keep a copy of "baton" and won't free
300 // or delete it when it goes goes out of scope.
301 m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
302
303 SendBreakpointChangedEvent (eBreakpointEventTypeCommandChanged);
304 }
305
306 // This function is used when a baton needs to be freed and therefore is
307 // contained in a "Baton" subclass.
308 void
SetCallback(BreakpointHitCallback callback,const BatonSP & callback_baton_sp,bool is_synchronous)309 Breakpoint::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous)
310 {
311 m_options.SetCallback(callback, callback_baton_sp, is_synchronous);
312 }
313
314 void
ClearCallback()315 Breakpoint::ClearCallback ()
316 {
317 m_options.ClearCallback ();
318 }
319
320 bool
InvokeCallback(StoppointCallbackContext * context,break_id_t bp_loc_id)321 Breakpoint::InvokeCallback (StoppointCallbackContext *context, break_id_t bp_loc_id)
322 {
323 return m_options.InvokeCallback (context, GetID(), bp_loc_id);
324 }
325
326 BreakpointOptions *
GetOptions()327 Breakpoint::GetOptions ()
328 {
329 return &m_options;
330 }
331
332 void
ResolveBreakpoint()333 Breakpoint::ResolveBreakpoint ()
334 {
335 if (m_resolver_sp)
336 m_resolver_sp->ResolveBreakpoint(*m_filter_sp);
337 }
338
339 void
ResolveBreakpointInModules(ModuleList & module_list)340 Breakpoint::ResolveBreakpointInModules (ModuleList &module_list)
341 {
342 if (m_resolver_sp)
343 m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list);
344 }
345
346 void
ClearAllBreakpointSites()347 Breakpoint::ClearAllBreakpointSites ()
348 {
349 m_locations.ClearAllBreakpointSites();
350 }
351
352 //----------------------------------------------------------------------
353 // ModulesChanged: Pass in a list of new modules, and
354 //----------------------------------------------------------------------
355
356 void
ModulesChanged(ModuleList & module_list,bool load,bool delete_locations)357 Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_locations)
358 {
359 Mutex::Locker modules_mutex(module_list.GetMutex());
360 if (load)
361 {
362 // The logic for handling new modules is:
363 // 1) If the filter rejects this module, then skip it.
364 // 2) Run through the current location list and if there are any locations
365 // for that module, we mark the module as "seen" and we don't try to re-resolve
366 // breakpoint locations for that module.
367 // However, we do add breakpoint sites to these locations if needed.
368 // 3) If we don't see this module in our breakpoint location list, call ResolveInModules.
369
370 ModuleList new_modules; // We'll stuff the "unseen" modules in this list, and then resolve
371 // them after the locations pass. Have to do it this way because
372 // resolving breakpoints will add new locations potentially.
373
374 const size_t num_locs = m_locations.GetSize();
375 size_t num_modules = module_list.GetSize();
376 for (size_t i = 0; i < num_modules; i++)
377 {
378 bool seen = false;
379 ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i));
380 if (!m_filter_sp->ModulePasses (module_sp))
381 continue;
382
383 for (size_t loc_idx = 0; loc_idx < num_locs; loc_idx++)
384 {
385 BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx);
386 if (!break_loc->IsEnabled())
387 continue;
388 SectionSP section_sp (break_loc->GetAddress().GetSection());
389 if (!section_sp || section_sp->GetModule() == module_sp)
390 {
391 if (!seen)
392 seen = true;
393
394 if (!break_loc->ResolveBreakpointSite())
395 {
396 Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
397 if (log)
398 log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n",
399 break_loc->GetID(), GetID());
400 }
401 }
402 }
403
404 if (!seen)
405 new_modules.AppendIfNeeded (module_sp);
406
407 }
408
409 if (new_modules.GetSize() > 0)
410 {
411 // If this is not an internal breakpoint, set up to record the new locations, then dispatch
412 // an event with the new locations.
413 if (!IsInternal())
414 {
415 BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded,
416 shared_from_this());
417
418 m_locations.StartRecordingNewLocations(new_locations_event->GetBreakpointLocationCollection());
419
420 ResolveBreakpointInModules(new_modules);
421
422 m_locations.StopRecordingNewLocations();
423 if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0)
424 {
425 SendBreakpointChangedEvent (new_locations_event);
426 }
427 else
428 delete new_locations_event;
429 }
430 else
431 ResolveBreakpointInModules(new_modules);
432
433 }
434 }
435 else
436 {
437 // Go through the currently set locations and if any have breakpoints in
438 // the module list, then remove their breakpoint sites, and their locations if asked to.
439
440 BreakpointEventData *removed_locations_event;
441 if (!IsInternal())
442 removed_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved,
443 shared_from_this());
444 else
445 removed_locations_event = NULL;
446
447 size_t num_modules = module_list.GetSize();
448 for (size_t i = 0; i < num_modules; i++)
449 {
450 ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i));
451 if (m_filter_sp->ModulePasses (module_sp))
452 {
453 size_t loc_idx = 0;
454 size_t num_locations = m_locations.GetSize();
455 BreakpointLocationCollection locations_to_remove;
456 for (loc_idx = 0; loc_idx < num_locations; loc_idx++)
457 {
458 BreakpointLocationSP break_loc_sp (m_locations.GetByIndex(loc_idx));
459 SectionSP section_sp (break_loc_sp->GetAddress().GetSection());
460 if (section_sp && section_sp->GetModule() == module_sp)
461 {
462 // Remove this breakpoint since the shared library is
463 // unloaded, but keep the breakpoint location around
464 // so we always get complete hit count and breakpoint
465 // lifetime info
466 break_loc_sp->ClearBreakpointSite();
467 if (removed_locations_event)
468 {
469 removed_locations_event->GetBreakpointLocationCollection().Add(break_loc_sp);
470 }
471 if (delete_locations)
472 locations_to_remove.Add (break_loc_sp);
473
474 }
475 }
476
477 if (delete_locations)
478 {
479 size_t num_locations_to_remove = locations_to_remove.GetSize();
480 for (loc_idx = 0; loc_idx < num_locations_to_remove; loc_idx++)
481 m_locations.RemoveLocation (locations_to_remove.GetByIndex(loc_idx));
482 }
483 }
484 }
485 SendBreakpointChangedEvent (removed_locations_event);
486 }
487 }
488
489 void
ModuleReplaced(ModuleSP old_module_sp,ModuleSP new_module_sp)490 Breakpoint::ModuleReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
491 {
492 ModuleList temp_list;
493 temp_list.Append (new_module_sp);
494 ModulesChanged (temp_list, true);
495
496 // TO DO: For now I'm just adding locations for the new module and removing the
497 // breakpoint locations that were in the old module.
498 // We should really go find the ones that are in the new module & if we can determine that they are "equivalent"
499 // carry over the options from the old location to the new.
500
501 temp_list.Clear();
502 temp_list.Append (old_module_sp);
503 ModulesChanged (temp_list, false, true);
504 }
505
506 void
Dump(Stream *)507 Breakpoint::Dump (Stream *)
508 {
509 }
510
511 size_t
GetNumResolvedLocations() const512 Breakpoint::GetNumResolvedLocations() const
513 {
514 // Return the number of breakpoints that are actually resolved and set
515 // down in the inferior process.
516 return m_locations.GetNumResolvedLocations();
517 }
518
519 size_t
GetNumLocations() const520 Breakpoint::GetNumLocations() const
521 {
522 return m_locations.GetSize();
523 }
524
525 void
GetDescription(Stream * s,lldb::DescriptionLevel level,bool show_locations)526 Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations)
527 {
528 assert (s != NULL);
529
530 if (!m_kind_description.empty())
531 {
532 if (eDescriptionLevelBrief)
533 {
534 s->PutCString (GetBreakpointKind());
535 return;
536 }
537 else
538 s->Printf("Kind: %s\n", GetBreakpointKind ());
539 }
540
541 const size_t num_locations = GetNumLocations ();
542 const size_t num_resolved_locations = GetNumResolvedLocations ();
543
544 // They just made the breakpoint, they don't need to be told HOW they made it...
545 // Also, we'll print the breakpoint number differently depending on whether there is 1 or more locations.
546 if (level != eDescriptionLevelInitial)
547 {
548 s->Printf("%i: ", GetID());
549 GetResolverDescription (s);
550 GetFilterDescription (s);
551 }
552
553 switch (level)
554 {
555 case lldb::eDescriptionLevelBrief:
556 case lldb::eDescriptionLevelFull:
557 if (num_locations > 0)
558 {
559 s->Printf(", locations = %" PRIu64, (uint64_t)num_locations);
560 if (num_resolved_locations > 0)
561 s->Printf(", resolved = %" PRIu64, (uint64_t)num_resolved_locations);
562 }
563 else
564 {
565 // Don't print the pending notification for exception resolvers since we don't generally
566 // know how to set them until the target is run.
567 if (m_resolver_sp->getResolverID() != BreakpointResolver::ExceptionResolver)
568 s->Printf(", locations = 0 (pending)");
569 }
570
571 GetOptions()->GetDescription(s, level);
572
573 if (level == lldb::eDescriptionLevelFull)
574 {
575 s->IndentLess();
576 s->EOL();
577 }
578 break;
579
580 case lldb::eDescriptionLevelInitial:
581 s->Printf ("Breakpoint %i: ", GetID());
582 if (num_locations == 0)
583 {
584 s->Printf ("no locations (pending).");
585 }
586 else if (num_locations == 1)
587 {
588 // If there is one location only, we'll just print that location information. But don't do this if
589 // show locations is true, then that will be handled below.
590 if (show_locations == false)
591 {
592 GetLocationAtIndex(0)->GetDescription(s, level);
593 }
594 else
595 {
596 s->Printf ("%zd locations.", num_locations);
597 }
598 }
599 else
600 {
601 s->Printf ("%zd locations.", num_locations);
602 }
603 s->EOL();
604 break;
605 case lldb::eDescriptionLevelVerbose:
606 // Verbose mode does a debug dump of the breakpoint
607 Dump (s);
608 s->EOL ();
609 //s->Indent();
610 GetOptions()->GetDescription(s, level);
611 break;
612
613 default:
614 break;
615 }
616
617 // The brief description is just the location name (1.2 or whatever). That's pointless to
618 // show in the breakpoint's description, so suppress it.
619 if (show_locations && level != lldb::eDescriptionLevelBrief)
620 {
621 s->IndentMore();
622 for (size_t i = 0; i < num_locations; ++i)
623 {
624 BreakpointLocation *loc = GetLocationAtIndex(i).get();
625 loc->GetDescription(s, level);
626 s->EOL();
627 }
628 s->IndentLess();
629 }
630 }
631
632 void
GetResolverDescription(Stream * s)633 Breakpoint::GetResolverDescription (Stream *s)
634 {
635 if (m_resolver_sp)
636 m_resolver_sp->GetDescription (s);
637 }
638
639
640 bool
GetMatchingFileLine(const ConstString & filename,uint32_t line_number,BreakpointLocationCollection & loc_coll)641 Breakpoint::GetMatchingFileLine (const ConstString &filename, uint32_t line_number, BreakpointLocationCollection &loc_coll)
642 {
643 // TODO: To be correct, this method needs to fill the breakpoint location collection
644 // with the location IDs which match the filename and line_number.
645 //
646
647 if (m_resolver_sp)
648 {
649 BreakpointResolverFileLine *resolverFileLine = dyn_cast<BreakpointResolverFileLine>(m_resolver_sp.get());
650 if (resolverFileLine &&
651 resolverFileLine->m_file_spec.GetFilename() == filename &&
652 resolverFileLine->m_line_number == line_number)
653 {
654 return true;
655 }
656 }
657 return false;
658 }
659
660 void
GetFilterDescription(Stream * s)661 Breakpoint::GetFilterDescription (Stream *s)
662 {
663 m_filter_sp->GetDescription (s);
664 }
665
666 void
SendBreakpointChangedEvent(lldb::BreakpointEventType eventKind)667 Breakpoint::SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind)
668 {
669 if (!m_being_created
670 && !IsInternal()
671 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
672 {
673 BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, shared_from_this());
674
675 GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
676 }
677 }
678
679 void
SendBreakpointChangedEvent(BreakpointEventData * data)680 Breakpoint::SendBreakpointChangedEvent (BreakpointEventData *data)
681 {
682
683 if (data == NULL)
684 return;
685
686 if (!m_being_created
687 && !IsInternal()
688 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
689 GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
690 else
691 delete data;
692 }
693
BreakpointEventData(BreakpointEventType sub_type,const BreakpointSP & new_breakpoint_sp)694 Breakpoint::BreakpointEventData::BreakpointEventData (BreakpointEventType sub_type,
695 const BreakpointSP &new_breakpoint_sp) :
696 EventData (),
697 m_breakpoint_event (sub_type),
698 m_new_breakpoint_sp (new_breakpoint_sp)
699 {
700 }
701
~BreakpointEventData()702 Breakpoint::BreakpointEventData::~BreakpointEventData ()
703 {
704 }
705
706 const ConstString &
GetFlavorString()707 Breakpoint::BreakpointEventData::GetFlavorString ()
708 {
709 static ConstString g_flavor ("Breakpoint::BreakpointEventData");
710 return g_flavor;
711 }
712
713 const ConstString &
GetFlavor() const714 Breakpoint::BreakpointEventData::GetFlavor () const
715 {
716 return BreakpointEventData::GetFlavorString ();
717 }
718
719
720 BreakpointSP &
GetBreakpoint()721 Breakpoint::BreakpointEventData::GetBreakpoint ()
722 {
723 return m_new_breakpoint_sp;
724 }
725
726 BreakpointEventType
GetBreakpointEventType() const727 Breakpoint::BreakpointEventData::GetBreakpointEventType () const
728 {
729 return m_breakpoint_event;
730 }
731
732 void
Dump(Stream * s) const733 Breakpoint::BreakpointEventData::Dump (Stream *s) const
734 {
735 }
736
737 const Breakpoint::BreakpointEventData *
GetEventDataFromEvent(const Event * event)738 Breakpoint::BreakpointEventData::GetEventDataFromEvent (const Event *event)
739 {
740 if (event)
741 {
742 const EventData *event_data = event->GetData();
743 if (event_data && event_data->GetFlavor() == BreakpointEventData::GetFlavorString())
744 return static_cast <const BreakpointEventData *> (event->GetData());
745 }
746 return NULL;
747 }
748
749 BreakpointEventType
GetBreakpointEventTypeFromEvent(const EventSP & event_sp)750 Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (const EventSP &event_sp)
751 {
752 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
753
754 if (data == NULL)
755 return eBreakpointEventTypeInvalidType;
756 else
757 return data->GetBreakpointEventType();
758 }
759
760 BreakpointSP
GetBreakpointFromEvent(const EventSP & event_sp)761 Breakpoint::BreakpointEventData::GetBreakpointFromEvent (const EventSP &event_sp)
762 {
763 BreakpointSP bp_sp;
764
765 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
766 if (data)
767 bp_sp = data->m_new_breakpoint_sp;
768
769 return bp_sp;
770 }
771
772 size_t
GetNumBreakpointLocationsFromEvent(const EventSP & event_sp)773 Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (const EventSP &event_sp)
774 {
775 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
776 if (data)
777 return data->m_locations.GetSize();
778
779 return 0;
780 }
781
782 lldb::BreakpointLocationSP
GetBreakpointLocationAtIndexFromEvent(const lldb::EventSP & event_sp,uint32_t bp_loc_idx)783 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t bp_loc_idx)
784 {
785 lldb::BreakpointLocationSP bp_loc_sp;
786
787 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
788 if (data)
789 {
790 bp_loc_sp = data->m_locations.GetByIndex(bp_loc_idx);
791 }
792
793 return bp_loc_sp;
794 }
795