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