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