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