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