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/Module.h"
24 #include "lldb/Core/ModuleList.h"
25 #include "lldb/Core/SearchFilter.h"
26 #include "lldb/Core/Section.h"
27 #include "lldb/Core/Stream.h"
28 #include "lldb/Core/StreamString.h"
29 #include "lldb/Symbol/CompileUnit.h"
30 #include "lldb/Symbol/Function.h"
31 #include "lldb/Symbol/SymbolContext.h"
32 #include "lldb/Target/Target.h"
33 #include "lldb/Target/ThreadSpec.h"
34 #include "lldb/lldb-private-log.h"
35 #include "llvm/Support/Casting.h"
36 
37 using namespace lldb;
38 using namespace lldb_private;
39 using namespace llvm;
40 
41 const ConstString &
42 Breakpoint::GetEventIdentifier ()
43 {
44     static ConstString g_identifier("event-identifier.breakpoint.changed");
45     return g_identifier;
46 }
47 
48 //----------------------------------------------------------------------
49 // Breakpoint constructor
50 //----------------------------------------------------------------------
51 Breakpoint::Breakpoint(Target &target,
52                        SearchFilterSP &filter_sp,
53                        BreakpointResolverSP &resolver_sp,
54                        bool hardware,
55                        bool resolve_indirect_symbols) :
56     m_being_created(true),
57     m_hardware(hardware),
58     m_target (target),
59     m_filter_sp (filter_sp),
60     m_resolver_sp (resolver_sp),
61     m_options (),
62     m_locations (*this),
63     m_resolve_indirect_symbols(resolve_indirect_symbols)
64 {
65     m_being_created = false;
66 }
67 
68 Breakpoint::Breakpoint (Target &new_target, Breakpoint &source_bp) :
69     m_being_created(true),
70     m_hardware(source_bp.m_hardware),
71     m_target(new_target),
72     m_options (source_bp.m_options),
73     m_locations(*this),
74     m_resolve_indirect_symbols(source_bp.m_resolve_indirect_symbols)
75 {
76     // Now go through and copy the filter & resolver:
77     m_resolver_sp = source_bp.m_resolver_sp->CopyForBreakpoint(*this);
78     m_filter_sp = source_bp.m_filter_sp->CopyForBreakpoint(*this);
79 }
80 
81 //----------------------------------------------------------------------
82 // Destructor
83 //----------------------------------------------------------------------
84 Breakpoint::~Breakpoint()
85 {
86 }
87 
88 const lldb::TargetSP
89 Breakpoint::GetTargetSP ()
90 {
91     return m_target.shared_from_this();
92 }
93 
94 bool
95 Breakpoint::IsInternal () const
96 {
97     return LLDB_BREAK_ID_IS_INTERNAL(m_bid);
98 }
99 
100 BreakpointLocationSP
101 Breakpoint::AddLocation (const Address &addr, bool *new_location)
102 {
103     return m_locations.AddLocation (addr, m_resolve_indirect_symbols, new_location);
104 }
105 
106 BreakpointLocationSP
107 Breakpoint::FindLocationByAddress (const Address &addr)
108 {
109     return m_locations.FindByAddress(addr);
110 }
111 
112 break_id_t
113 Breakpoint::FindLocationIDByAddress (const Address &addr)
114 {
115     return m_locations.FindIDByAddress(addr);
116 }
117 
118 BreakpointLocationSP
119 Breakpoint::FindLocationByID (break_id_t bp_loc_id)
120 {
121     return m_locations.FindByID(bp_loc_id);
122 }
123 
124 BreakpointLocationSP
125 Breakpoint::GetLocationAtIndex (size_t index)
126 {
127     return m_locations.GetByIndex(index);
128 }
129 
130 void
131 Breakpoint::RemoveInvalidLocations (const ArchSpec &arch)
132 {
133     m_locations.RemoveInvalidLocations(arch);
134 }
135 
136 // For each of the overall options we need to decide how they propagate to
137 // the location options.  This will determine the precedence of options on
138 // the breakpoint vs. its locations.
139 
140 // Disable at the breakpoint level should override the location settings.
141 // That way you can conveniently turn off a whole breakpoint without messing
142 // up the individual settings.
143 
144 void
145 Breakpoint::SetEnabled (bool enable)
146 {
147     if (enable == m_options.IsEnabled())
148         return;
149 
150     m_options.SetEnabled(enable);
151     if (enable)
152         m_locations.ResolveAllBreakpointSites();
153     else
154         m_locations.ClearAllBreakpointSites();
155 
156     SendBreakpointChangedEvent (enable ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
157 
158 }
159 
160 bool
161 Breakpoint::IsEnabled ()
162 {
163     return m_options.IsEnabled();
164 }
165 
166 void
167 Breakpoint::SetIgnoreCount (uint32_t n)
168 {
169     if (m_options.GetIgnoreCount() == n)
170         return;
171 
172     m_options.SetIgnoreCount(n);
173     SendBreakpointChangedEvent (eBreakpointEventTypeIgnoreChanged);
174 }
175 
176 void
177 Breakpoint::DecrementIgnoreCount ()
178 {
179     uint32_t ignore = m_options.GetIgnoreCount();
180     if (ignore != 0)
181         m_options.SetIgnoreCount(ignore - 1);
182 }
183 
184 uint32_t
185 Breakpoint::GetIgnoreCount () const
186 {
187     return m_options.GetIgnoreCount();
188 }
189 
190 bool
191 Breakpoint::IgnoreCountShouldStop ()
192 {
193     uint32_t ignore = GetIgnoreCount();
194     if (ignore != 0)
195     {
196         // When we get here we know the location that caused the stop doesn't have an ignore count,
197         // since by contract we call it first...  So we don't have to find & decrement it, we only have
198         // to decrement our own ignore count.
199         DecrementIgnoreCount();
200         return false;
201     }
202     else
203         return true;
204 }
205 
206 uint32_t
207 Breakpoint::GetHitCount () const
208 {
209     return m_locations.GetHitCount();
210 }
211 
212 bool
213 Breakpoint::IsOneShot () const
214 {
215     return m_options.IsOneShot();
216 }
217 
218 void
219 Breakpoint::SetOneShot (bool one_shot)
220 {
221     m_options.SetOneShot (one_shot);
222 }
223 
224 void
225 Breakpoint::SetThreadID (lldb::tid_t thread_id)
226 {
227     if (m_options.GetThreadSpec()->GetTID() == thread_id)
228         return;
229 
230     m_options.GetThreadSpec()->SetTID(thread_id);
231     SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
232 }
233 
234 lldb::tid_t
235 Breakpoint::GetThreadID () const
236 {
237     if (m_options.GetThreadSpecNoCreate() == NULL)
238         return LLDB_INVALID_THREAD_ID;
239     else
240         return m_options.GetThreadSpecNoCreate()->GetTID();
241 }
242 
243 void
244 Breakpoint::SetThreadIndex (uint32_t index)
245 {
246     if (m_options.GetThreadSpec()->GetIndex() == index)
247         return;
248 
249     m_options.GetThreadSpec()->SetIndex(index);
250     SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
251 }
252 
253 uint32_t
254 Breakpoint::GetThreadIndex() const
255 {
256     if (m_options.GetThreadSpecNoCreate() == NULL)
257         return 0;
258     else
259         return m_options.GetThreadSpecNoCreate()->GetIndex();
260 }
261 
262 void
263 Breakpoint::SetThreadName (const char *thread_name)
264 {
265     if (m_options.GetThreadSpec()->GetName() != NULL
266         && ::strcmp (m_options.GetThreadSpec()->GetName(), thread_name) == 0)
267         return;
268 
269     m_options.GetThreadSpec()->SetName (thread_name);
270     SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
271 }
272 
273 const char *
274 Breakpoint::GetThreadName () const
275 {
276     if (m_options.GetThreadSpecNoCreate() == NULL)
277         return NULL;
278     else
279         return m_options.GetThreadSpecNoCreate()->GetName();
280 }
281 
282 void
283 Breakpoint::SetQueueName (const char *queue_name)
284 {
285     if (m_options.GetThreadSpec()->GetQueueName() != NULL
286         && ::strcmp (m_options.GetThreadSpec()->GetQueueName(), queue_name) == 0)
287         return;
288 
289     m_options.GetThreadSpec()->SetQueueName (queue_name);
290     SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged);
291 }
292 
293 const char *
294 Breakpoint::GetQueueName () const
295 {
296     if (m_options.GetThreadSpecNoCreate() == NULL)
297         return NULL;
298     else
299         return m_options.GetThreadSpecNoCreate()->GetQueueName();
300 }
301 
302 void
303 Breakpoint::SetCondition (const char *condition)
304 {
305     m_options.SetCondition (condition);
306     SendBreakpointChangedEvent (eBreakpointEventTypeConditionChanged);
307 }
308 
309 const char *
310 Breakpoint::GetConditionText () const
311 {
312     return m_options.GetConditionText();
313 }
314 
315 // This function is used when "baton" doesn't need to be freed
316 void
317 Breakpoint::SetCallback (BreakpointHitCallback callback, void *baton, bool is_synchronous)
318 {
319     // The default "Baton" class will keep a copy of "baton" and won't free
320     // or delete it when it goes goes out of scope.
321     m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
322 
323     SendBreakpointChangedEvent (eBreakpointEventTypeCommandChanged);
324 }
325 
326 // This function is used when a baton needs to be freed and therefore is
327 // contained in a "Baton" subclass.
328 void
329 Breakpoint::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous)
330 {
331     m_options.SetCallback(callback, callback_baton_sp, is_synchronous);
332 }
333 
334 void
335 Breakpoint::ClearCallback ()
336 {
337     m_options.ClearCallback ();
338 }
339 
340 bool
341 Breakpoint::InvokeCallback (StoppointCallbackContext *context, break_id_t bp_loc_id)
342 {
343     return m_options.InvokeCallback (context, GetID(), bp_loc_id);
344 }
345 
346 BreakpointOptions *
347 Breakpoint::GetOptions ()
348 {
349     return &m_options;
350 }
351 
352 void
353 Breakpoint::ResolveBreakpoint ()
354 {
355     if (m_resolver_sp)
356         m_resolver_sp->ResolveBreakpoint(*m_filter_sp);
357 }
358 
359 void
360 Breakpoint::ResolveBreakpointInModules (ModuleList &module_list, BreakpointLocationCollection &new_locations)
361 {
362     m_locations.StartRecordingNewLocations(new_locations);
363 
364     m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list);
365 
366     m_locations.StopRecordingNewLocations();
367 }
368 
369 void
370 Breakpoint::ResolveBreakpointInModules (ModuleList &module_list, bool send_event)
371 {
372     if (m_resolver_sp)
373     {
374         // If this is not an internal breakpoint, set up to record the new locations, then dispatch
375         // an event with the new locations.
376         if (!IsInternal() && send_event)
377         {
378             BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded,
379                                                                                 shared_from_this());
380 
381             ResolveBreakpointInModules (module_list, new_locations_event->GetBreakpointLocationCollection());
382 
383             if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0)
384             {
385                 SendBreakpointChangedEvent (new_locations_event);
386             }
387             else
388                 delete new_locations_event;
389         }
390         else
391         {
392             m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list);
393         }
394     }
395 }
396 
397 void
398 Breakpoint::ClearAllBreakpointSites ()
399 {
400     m_locations.ClearAllBreakpointSites();
401 }
402 
403 //----------------------------------------------------------------------
404 // ModulesChanged: Pass in a list of new modules, and
405 //----------------------------------------------------------------------
406 
407 void
408 Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_locations)
409 {
410     Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
411     if (log)
412         log->Printf ("Breakpoint::ModulesChanged: num_modules: %zu load: %i delete_locations: %i\n",
413                      module_list.GetSize(), load, delete_locations);
414 
415     Mutex::Locker modules_mutex(module_list.GetMutex());
416     if (load)
417     {
418         // The logic for handling new modules is:
419         // 1) If the filter rejects this module, then skip it.
420         // 2) Run through the current location list and if there are any locations
421         //    for that module, we mark the module as "seen" and we don't try to re-resolve
422         //    breakpoint locations for that module.
423         //    However, we do add breakpoint sites to these locations if needed.
424         // 3) If we don't see this module in our breakpoint location list, call ResolveInModules.
425 
426         ModuleList new_modules;  // We'll stuff the "unseen" modules in this list, and then resolve
427                                  // them after the locations pass.  Have to do it this way because
428                                  // resolving breakpoints will add new locations potentially.
429 
430         for (ModuleSP module_sp : module_list.ModulesNoLocking())
431         {
432             bool seen = false;
433             if (!m_filter_sp->ModulePasses (module_sp))
434                 continue;
435 
436             for (BreakpointLocationSP break_loc_sp : m_locations.BreakpointLocations())
437             {
438                 if (!break_loc_sp->IsEnabled())
439                     continue;
440                 SectionSP section_sp (break_loc_sp->GetAddress().GetSection());
441                 if (!section_sp || section_sp->GetModule() == module_sp)
442                 {
443                     if (!seen)
444                         seen = true;
445 
446                     if (!break_loc_sp->ResolveBreakpointSite())
447                     {
448                         if (log)
449                             log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n",
450                                          break_loc_sp->GetID(), GetID());
451                     }
452                 }
453             }
454 
455             if (!seen)
456                 new_modules.AppendIfNeeded (module_sp);
457 
458         }
459 
460         if (new_modules.GetSize() > 0)
461         {
462             ResolveBreakpointInModules(new_modules);
463         }
464     }
465     else
466     {
467         // Go through the currently set locations and if any have breakpoints in
468         // the module list, then remove their breakpoint sites, and their locations if asked to.
469 
470         BreakpointEventData *removed_locations_event;
471         if (!IsInternal())
472             removed_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved,
473                                                                shared_from_this());
474         else
475             removed_locations_event = NULL;
476 
477         size_t num_modules = module_list.GetSize();
478         for (size_t i = 0; i < num_modules; i++)
479         {
480             ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i));
481             if (m_filter_sp->ModulePasses (module_sp))
482             {
483                 size_t loc_idx = 0;
484                 size_t num_locations = m_locations.GetSize();
485                 BreakpointLocationCollection locations_to_remove;
486                 for (loc_idx = 0; loc_idx < num_locations; loc_idx++)
487                 {
488                     BreakpointLocationSP break_loc_sp (m_locations.GetByIndex(loc_idx));
489                     SectionSP section_sp (break_loc_sp->GetAddress().GetSection());
490                     if (section_sp && section_sp->GetModule() == module_sp)
491                     {
492                         // Remove this breakpoint since the shared library is
493                         // unloaded, but keep the breakpoint location around
494                         // so we always get complete hit count and breakpoint
495                         // lifetime info
496                         break_loc_sp->ClearBreakpointSite();
497                         if (removed_locations_event)
498                         {
499                             removed_locations_event->GetBreakpointLocationCollection().Add(break_loc_sp);
500                         }
501                         if (delete_locations)
502                             locations_to_remove.Add (break_loc_sp);
503 
504                     }
505                 }
506 
507                 if (delete_locations)
508                 {
509                     size_t num_locations_to_remove = locations_to_remove.GetSize();
510                     for (loc_idx = 0; loc_idx < num_locations_to_remove; loc_idx++)
511                         m_locations.RemoveLocation  (locations_to_remove.GetByIndex(loc_idx));
512                 }
513             }
514         }
515         SendBreakpointChangedEvent (removed_locations_event);
516     }
517 }
518 
519 namespace
520 {
521 static bool
522 SymbolContextsMightBeEquivalent(SymbolContext &old_sc, SymbolContext &new_sc)
523 {
524     bool equivalent_scs = false;
525 
526     if (old_sc.module_sp.get() == new_sc.module_sp.get())
527     {
528         // If these come from the same module, we can directly compare the pointers:
529         if (old_sc.comp_unit && new_sc.comp_unit
530             && (old_sc.comp_unit == new_sc.comp_unit))
531         {
532             if (old_sc.function && new_sc.function
533                 && (old_sc.function == new_sc.function))
534             {
535                 equivalent_scs = true;
536             }
537         }
538         else if (old_sc.symbol && new_sc.symbol
539                 && (old_sc.symbol == new_sc.symbol))
540         {
541             equivalent_scs = true;
542         }
543     }
544     else
545     {
546         // Otherwise we will compare by name...
547         if (old_sc.comp_unit && new_sc.comp_unit)
548         {
549             if (FileSpec::Equal(*old_sc.comp_unit, *new_sc.comp_unit, true))
550             {
551                 // Now check the functions:
552                 if (old_sc.function && new_sc.function
553                     && (old_sc.function->GetName() == new_sc.function->GetName()))
554                 {
555                     equivalent_scs = true;
556                 }
557             }
558         }
559         else if (old_sc.symbol && new_sc.symbol)
560         {
561             if (Mangled::Compare(old_sc.symbol->GetMangled(), new_sc.symbol->GetMangled()) == 0)
562             {
563                 equivalent_scs = true;
564             }
565         }
566     }
567     return equivalent_scs;
568 }
569 }
570 
571 void
572 Breakpoint::ModuleReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
573 {
574     Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
575     if (log)
576         log->Printf ("Breakpoint::ModulesReplaced for %s\n",
577                      old_module_sp->GetSpecificationDescription().c_str());
578     // First find all the locations that are in the old module
579 
580     BreakpointLocationCollection old_break_locs;
581     for (BreakpointLocationSP break_loc_sp : m_locations.BreakpointLocations())
582     {
583         SectionSP section_sp = break_loc_sp->GetAddress().GetSection();
584         if (section_sp && section_sp->GetModule() == old_module_sp)
585         {
586             old_break_locs.Add(break_loc_sp);
587         }
588     }
589 
590     size_t num_old_locations = old_break_locs.GetSize();
591 
592     if (num_old_locations == 0)
593     {
594         // There were no locations in the old module, so we just need to check if there were any in the new module.
595         ModuleList temp_list;
596         temp_list.Append (new_module_sp);
597         ResolveBreakpointInModules(temp_list);
598     }
599     else
600     {
601         // First search the new module for locations.
602         // Then compare this with the old list, copy over locations that "look the same"
603         // Then delete the old locations.
604         // Finally remember to post the creation event.
605         //
606         // Two locations are the same if they have the same comp unit & function (by name) and there are the same number
607         // of locations in the old function as in the new one.
608 
609         ModuleList temp_list;
610         temp_list.Append (new_module_sp);
611         BreakpointLocationCollection new_break_locs;
612         ResolveBreakpointInModules(temp_list, new_break_locs);
613         BreakpointLocationCollection locations_to_remove;
614         BreakpointLocationCollection locations_to_announce;
615 
616         size_t num_new_locations = new_break_locs.GetSize();
617 
618         if (num_new_locations > 0)
619         {
620             // Break out the case of one location -> one location since that's the most common one, and there's no need
621             // to build up the structures needed for the merge in that case.
622             if (num_new_locations == 1 && num_old_locations == 1)
623             {
624                 bool equivalent_locations = false;
625                 SymbolContext old_sc, new_sc;
626                 // The only way the old and new location can be equivalent is if they have the same amount of information:
627                 BreakpointLocationSP old_loc_sp = old_break_locs.GetByIndex(0);
628                 BreakpointLocationSP new_loc_sp = new_break_locs.GetByIndex(0);
629 
630                 if (old_loc_sp->GetAddress().CalculateSymbolContext(&old_sc)
631                     == new_loc_sp->GetAddress().CalculateSymbolContext(&new_sc))
632                 {
633                     equivalent_locations = SymbolContextsMightBeEquivalent(old_sc, new_sc);
634                 }
635 
636                 if (equivalent_locations)
637                 {
638                     m_locations.SwapLocation (old_loc_sp, new_loc_sp);
639                 }
640                 else
641                 {
642                     locations_to_remove.Add(old_loc_sp);
643                     locations_to_announce.Add(new_loc_sp);
644                 }
645             }
646             else
647             {
648                 //We don't want to have to keep computing the SymbolContexts for these addresses over and over,
649                 // so lets get them up front:
650 
651                 typedef std::map<lldb::break_id_t, SymbolContext> IDToSCMap;
652                 IDToSCMap old_sc_map;
653                 for (size_t idx = 0; idx < num_old_locations; idx++)
654                 {
655                     SymbolContext sc;
656                     BreakpointLocationSP bp_loc_sp = old_break_locs.GetByIndex(idx);
657                     lldb::break_id_t loc_id = bp_loc_sp->GetID();
658                     bp_loc_sp->GetAddress().CalculateSymbolContext(&old_sc_map[loc_id]);
659                 }
660 
661                 std::map<lldb::break_id_t, SymbolContext> new_sc_map;
662                 for (size_t idx = 0; idx < num_new_locations; idx++)
663                 {
664                     SymbolContext sc;
665                     BreakpointLocationSP bp_loc_sp = new_break_locs.GetByIndex(idx);
666                     lldb::break_id_t loc_id = bp_loc_sp->GetID();
667                     bp_loc_sp->GetAddress().CalculateSymbolContext(&new_sc_map[loc_id]);
668                 }
669                 // Take an element from the old Symbol Contexts
670                 while (old_sc_map.size() > 0)
671                 {
672                     lldb::break_id_t old_id = old_sc_map.begin()->first;
673                     SymbolContext &old_sc = old_sc_map.begin()->second;
674 
675                     // Count the number of entries equivalent to this SC for the old list:
676                     std::vector<lldb::break_id_t> old_id_vec;
677                     old_id_vec.push_back(old_id);
678 
679                     IDToSCMap::iterator tmp_iter;
680                     for (tmp_iter = ++old_sc_map.begin(); tmp_iter != old_sc_map.end(); tmp_iter++)
681                     {
682                         if (SymbolContextsMightBeEquivalent (old_sc, tmp_iter->second))
683                             old_id_vec.push_back (tmp_iter->first);
684                     }
685 
686                     // Now find all the equivalent locations in the new list.
687                     std::vector<lldb::break_id_t> new_id_vec;
688                     for (tmp_iter = new_sc_map.begin(); tmp_iter != new_sc_map.end(); tmp_iter++)
689                     {
690                         if (SymbolContextsMightBeEquivalent (old_sc, tmp_iter->second))
691                             new_id_vec.push_back(tmp_iter->first);
692                     }
693 
694                     // Alright, if we have the same number of potentially equivalent locations in the old
695                     // and new modules, we'll just map them one to one in ascending ID order (assuming the
696                     // resolver's order would match the equivalent ones.
697                     // Otherwise, we'll dump all the old ones, and just take the new ones, erasing the elements
698                     // from both maps as we go.
699 
700                     if (old_id_vec.size() == new_id_vec.size())
701                     {
702                         sort(old_id_vec.begin(), old_id_vec.end());
703                         sort(new_id_vec.begin(), new_id_vec.end());
704                         size_t num_elements = old_id_vec.size();
705                         for (size_t idx = 0; idx < num_elements; idx++)
706                         {
707                             BreakpointLocationSP old_loc_sp = old_break_locs.FindByIDPair(GetID(), old_id_vec[idx]);
708                             BreakpointLocationSP new_loc_sp = new_break_locs.FindByIDPair(GetID(), new_id_vec[idx]);
709                             m_locations.SwapLocation(old_loc_sp, new_loc_sp);
710                             old_sc_map.erase(old_id_vec[idx]);
711                             new_sc_map.erase(new_id_vec[idx]);
712                         }
713                     }
714                     else
715                     {
716                         for (lldb::break_id_t old_id : old_id_vec)
717                         {
718                             locations_to_remove.Add(old_break_locs.FindByIDPair(GetID(), old_id));
719                             old_sc_map.erase(old_id);
720                         }
721                         for (lldb::break_id_t new_id : new_id_vec)
722                         {
723                             locations_to_announce.Add(new_break_locs.FindByIDPair(GetID(), new_id));
724                             new_sc_map.erase(new_id);
725                         }
726                     }
727                 }
728             }
729         }
730 
731         // Now remove the remaining old locations, and cons up a removed locations event.
732         // Note, we don't put the new locations that were swapped with an old location on the locations_to_remove
733         // list, so we don't need to worry about telling the world about removing a location we didn't tell them
734         // about adding.
735 
736         BreakpointEventData *locations_event;
737         if (!IsInternal())
738             locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved,
739                                                                shared_from_this());
740         else
741             locations_event = NULL;
742 
743         for (BreakpointLocationSP loc_sp : locations_to_remove.BreakpointLocations())
744         {
745             m_locations.RemoveLocation(loc_sp);
746             if (locations_event)
747                 locations_event->GetBreakpointLocationCollection().Add(loc_sp);
748         }
749         SendBreakpointChangedEvent (locations_event);
750 
751         // And announce the new ones.
752 
753         if (!IsInternal())
754         {
755             locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded,
756                                                                shared_from_this());
757             for (BreakpointLocationSP loc_sp : locations_to_announce.BreakpointLocations())
758                     locations_event->GetBreakpointLocationCollection().Add(loc_sp);
759 
760             SendBreakpointChangedEvent (locations_event);
761         }
762         m_locations.Compact();
763     }
764 }
765 
766 void
767 Breakpoint::Dump (Stream *)
768 {
769 }
770 
771 size_t
772 Breakpoint::GetNumResolvedLocations() const
773 {
774     // Return the number of breakpoints that are actually resolved and set
775     // down in the inferior process.
776     return m_locations.GetNumResolvedLocations();
777 }
778 
779 size_t
780 Breakpoint::GetNumLocations() const
781 {
782     return m_locations.GetSize();
783 }
784 
785 void
786 Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations)
787 {
788     assert (s != NULL);
789 
790     if (!m_kind_description.empty())
791     {
792         if (level == eDescriptionLevelBrief)
793         {
794             s->PutCString (GetBreakpointKind());
795             return;
796         }
797         else
798             s->Printf("Kind: %s\n", GetBreakpointKind ());
799     }
800 
801     const size_t num_locations = GetNumLocations ();
802     const size_t num_resolved_locations = GetNumResolvedLocations ();
803 
804     // They just made the breakpoint, they don't need to be told HOW they made it...
805     // Also, we'll print the breakpoint number differently depending on whether there is 1 or more locations.
806     if (level != eDescriptionLevelInitial)
807     {
808         s->Printf("%i: ", GetID());
809         GetResolverDescription (s);
810         GetFilterDescription (s);
811     }
812 
813     switch (level)
814     {
815     case lldb::eDescriptionLevelBrief:
816     case lldb::eDescriptionLevelFull:
817         if (num_locations > 0)
818         {
819             s->Printf(", locations = %" PRIu64, (uint64_t)num_locations);
820             if (num_resolved_locations > 0)
821                 s->Printf(", resolved = %" PRIu64 ", hit count = %d", (uint64_t)num_resolved_locations, GetHitCount());
822         }
823         else
824         {
825             // Don't print the pending notification for exception resolvers since we don't generally
826             // know how to set them until the target is run.
827             if (m_resolver_sp->getResolverID() != BreakpointResolver::ExceptionResolver)
828                 s->Printf(", locations = 0 (pending)");
829         }
830 
831         GetOptions()->GetDescription(s, level);
832 
833         if (level == lldb::eDescriptionLevelFull)
834         {
835             s->IndentLess();
836             s->EOL();
837         }
838         break;
839 
840     case lldb::eDescriptionLevelInitial:
841         s->Printf ("Breakpoint %i: ", GetID());
842         if (num_locations == 0)
843         {
844             s->Printf ("no locations (pending).");
845         }
846         else if (num_locations == 1)
847         {
848             // If there is one location only, we'll just print that location information.  But don't do this if
849             // show locations is true, then that will be handled below.
850             if (show_locations == false)
851             {
852                 GetLocationAtIndex(0)->GetDescription(s, level);
853             }
854             else
855             {
856                 s->Printf ("%zd locations.", num_locations);
857             }
858         }
859         else
860         {
861             s->Printf ("%zd locations.", num_locations);
862         }
863         s->EOL();
864         break;
865     case lldb::eDescriptionLevelVerbose:
866         // Verbose mode does a debug dump of the breakpoint
867         Dump (s);
868         s->EOL ();
869             //s->Indent();
870         GetOptions()->GetDescription(s, level);
871         break;
872 
873     default:
874         break;
875     }
876 
877     // The brief description is just the location name (1.2 or whatever).  That's pointless to
878     // show in the breakpoint's description, so suppress it.
879     if (show_locations && level != lldb::eDescriptionLevelBrief)
880     {
881         s->IndentMore();
882         for (size_t i = 0; i < num_locations; ++i)
883         {
884             BreakpointLocation *loc = GetLocationAtIndex(i).get();
885             loc->GetDescription(s, level);
886             s->EOL();
887         }
888         s->IndentLess();
889     }
890 }
891 
892 void
893 Breakpoint::GetResolverDescription (Stream *s)
894 {
895     if (m_resolver_sp)
896         m_resolver_sp->GetDescription (s);
897 }
898 
899 
900 bool
901 Breakpoint::GetMatchingFileLine (const ConstString &filename, uint32_t line_number, BreakpointLocationCollection &loc_coll)
902 {
903     // TODO: To be correct, this method needs to fill the breakpoint location collection
904     //       with the location IDs which match the filename and line_number.
905     //
906 
907     if (m_resolver_sp)
908     {
909         BreakpointResolverFileLine *resolverFileLine = dyn_cast<BreakpointResolverFileLine>(m_resolver_sp.get());
910         if (resolverFileLine &&
911             resolverFileLine->m_file_spec.GetFilename() == filename &&
912             resolverFileLine->m_line_number == line_number)
913         {
914             return true;
915         }
916     }
917     return false;
918 }
919 
920 void
921 Breakpoint::GetFilterDescription (Stream *s)
922 {
923     m_filter_sp->GetDescription (s);
924 }
925 
926 void
927 Breakpoint::SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind)
928 {
929     if (!m_being_created
930         && !IsInternal()
931         && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
932     {
933         BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, shared_from_this());
934 
935         GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
936     }
937 }
938 
939 void
940 Breakpoint::SendBreakpointChangedEvent (BreakpointEventData *data)
941 {
942 
943     if (data == NULL)
944         return;
945 
946     if (!m_being_created
947         && !IsInternal()
948         && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
949         GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
950     else
951         delete data;
952 }
953 
954 Breakpoint::BreakpointEventData::BreakpointEventData (BreakpointEventType sub_type,
955                                                       const BreakpointSP &new_breakpoint_sp) :
956     EventData (),
957     m_breakpoint_event (sub_type),
958     m_new_breakpoint_sp (new_breakpoint_sp)
959 {
960 }
961 
962 Breakpoint::BreakpointEventData::~BreakpointEventData ()
963 {
964 }
965 
966 const ConstString &
967 Breakpoint::BreakpointEventData::GetFlavorString ()
968 {
969     static ConstString g_flavor ("Breakpoint::BreakpointEventData");
970     return g_flavor;
971 }
972 
973 const ConstString &
974 Breakpoint::BreakpointEventData::GetFlavor () const
975 {
976     return BreakpointEventData::GetFlavorString ();
977 }
978 
979 
980 BreakpointSP &
981 Breakpoint::BreakpointEventData::GetBreakpoint ()
982 {
983     return m_new_breakpoint_sp;
984 }
985 
986 BreakpointEventType
987 Breakpoint::BreakpointEventData::GetBreakpointEventType () const
988 {
989     return m_breakpoint_event;
990 }
991 
992 void
993 Breakpoint::BreakpointEventData::Dump (Stream *s) const
994 {
995 }
996 
997 const Breakpoint::BreakpointEventData *
998 Breakpoint::BreakpointEventData::GetEventDataFromEvent (const Event *event)
999 {
1000     if (event)
1001     {
1002         const EventData *event_data = event->GetData();
1003         if (event_data && event_data->GetFlavor() == BreakpointEventData::GetFlavorString())
1004             return static_cast <const BreakpointEventData *> (event->GetData());
1005     }
1006     return NULL;
1007 }
1008 
1009 BreakpointEventType
1010 Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (const EventSP &event_sp)
1011 {
1012     const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
1013 
1014     if (data == NULL)
1015         return eBreakpointEventTypeInvalidType;
1016     else
1017         return data->GetBreakpointEventType();
1018 }
1019 
1020 BreakpointSP
1021 Breakpoint::BreakpointEventData::GetBreakpointFromEvent (const EventSP &event_sp)
1022 {
1023     BreakpointSP bp_sp;
1024 
1025     const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
1026     if (data)
1027         bp_sp = data->m_new_breakpoint_sp;
1028 
1029     return bp_sp;
1030 }
1031 
1032 size_t
1033 Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (const EventSP &event_sp)
1034 {
1035     const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
1036     if (data)
1037         return data->m_locations.GetSize();
1038 
1039     return 0;
1040 }
1041 
1042 lldb::BreakpointLocationSP
1043 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t bp_loc_idx)
1044 {
1045     lldb::BreakpointLocationSP bp_loc_sp;
1046 
1047     const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
1048     if (data)
1049     {
1050         bp_loc_sp = data->m_locations.GetByIndex(bp_loc_idx);
1051     }
1052 
1053     return bp_loc_sp;
1054 }
1055