1 //===-- BreakpointLocation.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 "lldb/Breakpoint/BreakpointLocation.h"
10 #include "lldb/Breakpoint/BreakpointID.h"
11 #include "lldb/Breakpoint/StoppointCallbackContext.h"
12 #include "lldb/Core/Debugger.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/ValueObject.h"
15 #include "lldb/Expression/DiagnosticManager.h"
16 #include "lldb/Expression/ExpressionVariable.h"
17 #include "lldb/Expression/UserExpression.h"
18 #include "lldb/Symbol/CompileUnit.h"
19 #include "lldb/Symbol/Symbol.h"
20 #include "lldb/Symbol/TypeSystem.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/Target.h"
23 #include "lldb/Target/Thread.h"
24 #include "lldb/Target/ThreadSpec.h"
25 #include "lldb/Utility/Log.h"
26 #include "lldb/Utility/StreamString.h"
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 BreakpointLocation::BreakpointLocation(break_id_t loc_id, Breakpoint &owner,
32                                        const Address &addr, lldb::tid_t tid,
33                                        bool hardware, bool check_for_resolver)
34     : StoppointLocation(loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()),
35                         hardware),
36       m_being_created(true), m_should_resolve_indirect_functions(false),
37       m_is_reexported(false), m_is_indirect(false), m_address(addr),
38       m_owner(owner), m_options_up(), m_bp_site_sp(), m_condition_mutex() {
39   if (check_for_resolver) {
40     Symbol *symbol = m_address.CalculateSymbolContextSymbol();
41     if (symbol && symbol->IsIndirect()) {
42       SetShouldResolveIndirectFunctions(true);
43     }
44   }
45 
46   SetThreadID(tid);
47   m_being_created = false;
48 }
49 
50 BreakpointLocation::~BreakpointLocation() { ClearBreakpointSite(); }
51 
52 lldb::addr_t BreakpointLocation::GetLoadAddress() const {
53   return m_address.GetOpcodeLoadAddress(&m_owner.GetTarget());
54 }
55 
56 const BreakpointOptions *
57 BreakpointLocation::GetOptionsSpecifyingKind(BreakpointOptions::OptionKind kind)
58 const {
59   if (m_options_up && m_options_up->IsOptionSet(kind))
60     return m_options_up.get();
61   else
62     return m_owner.GetOptions();
63 }
64 
65 Address &BreakpointLocation::GetAddress() { return m_address; }
66 
67 Breakpoint &BreakpointLocation::GetBreakpoint() { return m_owner; }
68 
69 Target &BreakpointLocation::GetTarget() { return m_owner.GetTarget(); }
70 
71 bool BreakpointLocation::IsHardware() const {
72   if (m_bp_site_sp)
73     return m_bp_site_sp->IsHardware();
74 
75   // If breakpoint location is not resolved yet, it cannot be hardware.
76   return false;
77 }
78 
79 bool BreakpointLocation::IsEnabled() const {
80   if (!m_owner.IsEnabled())
81     return false;
82   else if (m_options_up != nullptr)
83     return m_options_up->IsEnabled();
84   else
85     return true;
86 }
87 
88 void BreakpointLocation::SetEnabled(bool enabled) {
89   GetLocationOptions()->SetEnabled(enabled);
90   if (enabled) {
91     ResolveBreakpointSite();
92   } else {
93     ClearBreakpointSite();
94   }
95   SendBreakpointLocationChangedEvent(enabled ? eBreakpointEventTypeEnabled
96                                              : eBreakpointEventTypeDisabled);
97 }
98 
99 bool BreakpointLocation::IsAutoContinue() const {
100   if (m_options_up &&
101       m_options_up->IsOptionSet(BreakpointOptions::eAutoContinue))
102     return m_options_up->IsAutoContinue();
103   else
104     return m_owner.IsAutoContinue();
105 }
106 
107 void BreakpointLocation::SetAutoContinue(bool auto_continue) {
108   GetLocationOptions()->SetAutoContinue(auto_continue);
109   SendBreakpointLocationChangedEvent(eBreakpointEventTypeAutoContinueChanged);
110 }
111 
112 void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) {
113   if (thread_id != LLDB_INVALID_THREAD_ID)
114     GetLocationOptions()->SetThreadID(thread_id);
115   else {
116     // If we're resetting this to an invalid thread id, then don't make an
117     // options pointer just to do that.
118     if (m_options_up != nullptr)
119       m_options_up->SetThreadID(thread_id);
120   }
121   SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
122 }
123 
124 lldb::tid_t BreakpointLocation::GetThreadID() {
125   const ThreadSpec *thread_spec =
126       GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
127           ->GetThreadSpecNoCreate();
128   if (thread_spec)
129     return thread_spec->GetTID();
130   else
131     return LLDB_INVALID_THREAD_ID;
132 }
133 
134 void BreakpointLocation::SetThreadIndex(uint32_t index) {
135   if (index != 0)
136     GetLocationOptions()->GetThreadSpec()->SetIndex(index);
137   else {
138     // If we're resetting this to an invalid thread id, then don't make an
139     // options pointer just to do that.
140     if (m_options_up != nullptr)
141       m_options_up->GetThreadSpec()->SetIndex(index);
142   }
143   SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
144 }
145 
146 uint32_t BreakpointLocation::GetThreadIndex() const {
147   const ThreadSpec *thread_spec =
148       GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
149           ->GetThreadSpecNoCreate();
150   if (thread_spec)
151     return thread_spec->GetIndex();
152   else
153     return 0;
154 }
155 
156 void BreakpointLocation::SetThreadName(const char *thread_name) {
157   if (thread_name != nullptr)
158     GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
159   else {
160     // If we're resetting this to an invalid thread id, then don't make an
161     // options pointer just to do that.
162     if (m_options_up != nullptr)
163       m_options_up->GetThreadSpec()->SetName(thread_name);
164   }
165   SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
166 }
167 
168 const char *BreakpointLocation::GetThreadName() const {
169   const ThreadSpec *thread_spec =
170       GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
171           ->GetThreadSpecNoCreate();
172   if (thread_spec)
173     return thread_spec->GetName();
174   else
175     return nullptr;
176 }
177 
178 void BreakpointLocation::SetQueueName(const char *queue_name) {
179   if (queue_name != nullptr)
180     GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
181   else {
182     // If we're resetting this to an invalid thread id, then don't make an
183     // options pointer just to do that.
184     if (m_options_up != nullptr)
185       m_options_up->GetThreadSpec()->SetQueueName(queue_name);
186   }
187   SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
188 }
189 
190 const char *BreakpointLocation::GetQueueName() const {
191   const ThreadSpec *thread_spec =
192       GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
193           ->GetThreadSpecNoCreate();
194   if (thread_spec)
195     return thread_spec->GetQueueName();
196   else
197     return nullptr;
198 }
199 
200 bool BreakpointLocation::InvokeCallback(StoppointCallbackContext *context) {
201   if (m_options_up != nullptr && m_options_up->HasCallback())
202     return m_options_up->InvokeCallback(context, m_owner.GetID(), GetID());
203   else
204     return m_owner.InvokeCallback(context, GetID());
205 }
206 
207 void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
208                                      void *baton, bool is_synchronous) {
209   // The default "Baton" class will keep a copy of "baton" and won't free or
210   // delete it when it goes goes out of scope.
211   GetLocationOptions()->SetCallback(
212       callback, std::make_shared<UntypedBaton>(baton), is_synchronous);
213   SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
214 }
215 
216 void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
217                                      const BatonSP &baton_sp,
218                                      bool is_synchronous) {
219   GetLocationOptions()->SetCallback(callback, baton_sp, is_synchronous);
220   SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
221 }
222 
223 void BreakpointLocation::ClearCallback() {
224   GetLocationOptions()->ClearCallback();
225 }
226 
227 void BreakpointLocation::SetCondition(const char *condition) {
228   GetLocationOptions()->SetCondition(condition);
229   SendBreakpointLocationChangedEvent(eBreakpointEventTypeConditionChanged);
230 }
231 
232 const char *BreakpointLocation::GetConditionText(size_t *hash) const {
233   return GetOptionsSpecifyingKind(BreakpointOptions::eCondition)
234       ->GetConditionText(hash);
235 }
236 
237 bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
238                                            Status &error) {
239   Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
240 
241   std::lock_guard<std::mutex> guard(m_condition_mutex);
242 
243   size_t condition_hash;
244   const char *condition_text = GetConditionText(&condition_hash);
245 
246   if (!condition_text) {
247     m_user_expression_sp.reset();
248     return false;
249   }
250 
251   error.Clear();
252 
253   DiagnosticManager diagnostics;
254 
255   if (condition_hash != m_condition_hash || !m_user_expression_sp ||
256       !m_user_expression_sp->MatchesContext(exe_ctx)) {
257     LanguageType language = eLanguageTypeUnknown;
258     // See if we can figure out the language from the frame, otherwise use the
259     // default language:
260     CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit();
261     if (comp_unit)
262       language = comp_unit->GetLanguage();
263 
264     m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(
265         condition_text, llvm::StringRef(), language, Expression::eResultTypeAny,
266         EvaluateExpressionOptions(), nullptr, error));
267     if (error.Fail()) {
268       LLDB_LOGF(log, "Error getting condition expression: %s.",
269                 error.AsCString());
270       m_user_expression_sp.reset();
271       return true;
272     }
273 
274     if (!m_user_expression_sp->Parse(diagnostics, exe_ctx,
275                                      eExecutionPolicyOnlyWhenNeeded, true,
276                                      false)) {
277       error.SetErrorStringWithFormat(
278           "Couldn't parse conditional expression:\n%s",
279           diagnostics.GetString().c_str());
280       m_user_expression_sp.reset();
281       return true;
282     }
283 
284     m_condition_hash = condition_hash;
285   }
286 
287   // We need to make sure the user sees any parse errors in their condition, so
288   // we'll hook the constructor errors up to the debugger's Async I/O.
289 
290   ValueObjectSP result_value_sp;
291 
292   EvaluateExpressionOptions options;
293   options.SetUnwindOnError(true);
294   options.SetIgnoreBreakpoints(true);
295   options.SetTryAllThreads(true);
296   options.SetResultIsInternal(
297       true); // Don't generate a user variable for condition expressions.
298 
299   Status expr_error;
300 
301   diagnostics.Clear();
302 
303   ExpressionVariableSP result_variable_sp;
304 
305   ExpressionResults result_code = m_user_expression_sp->Execute(
306       diagnostics, exe_ctx, options, m_user_expression_sp, result_variable_sp);
307 
308   bool ret;
309 
310   if (result_code == eExpressionCompleted) {
311     if (!result_variable_sp) {
312       error.SetErrorString("Expression did not return a result");
313       return false;
314     }
315 
316     result_value_sp = result_variable_sp->GetValueObject();
317 
318     if (result_value_sp) {
319       ret = result_value_sp->IsLogicalTrue(error);
320       if (log) {
321         if (error.Success()) {
322           LLDB_LOGF(log, "Condition successfully evaluated, result is %s.\n",
323                     ret ? "true" : "false");
324         } else {
325           error.SetErrorString(
326               "Failed to get an integer result from the expression");
327           ret = false;
328         }
329       }
330     } else {
331       ret = false;
332       error.SetErrorString("Failed to get any result from the expression");
333     }
334   } else {
335     ret = false;
336     error.SetErrorStringWithFormat("Couldn't execute expression:\n%s",
337                                    diagnostics.GetString().c_str());
338   }
339 
340   return ret;
341 }
342 
343 uint32_t BreakpointLocation::GetIgnoreCount() {
344   return GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
345       ->GetIgnoreCount();
346 }
347 
348 void BreakpointLocation::SetIgnoreCount(uint32_t n) {
349   GetLocationOptions()->SetIgnoreCount(n);
350   SendBreakpointLocationChangedEvent(eBreakpointEventTypeIgnoreChanged);
351 }
352 
353 void BreakpointLocation::DecrementIgnoreCount() {
354   if (m_options_up != nullptr) {
355     uint32_t loc_ignore = m_options_up->GetIgnoreCount();
356     if (loc_ignore != 0)
357       m_options_up->SetIgnoreCount(loc_ignore - 1);
358   }
359 }
360 
361 bool BreakpointLocation::IgnoreCountShouldStop() {
362   if (m_options_up != nullptr) {
363     uint32_t loc_ignore = m_options_up->GetIgnoreCount();
364     if (loc_ignore != 0) {
365       m_owner.DecrementIgnoreCount();
366       DecrementIgnoreCount(); // Have to decrement our owners' ignore count,
367                               // since it won't get a
368                               // chance to.
369       return false;
370     }
371   }
372   return true;
373 }
374 
375 BreakpointOptions *BreakpointLocation::GetLocationOptions() {
376   // If we make the copy we don't copy the callbacks because that is
377   // potentially expensive and we don't want to do that for the simple case
378   // where someone is just disabling the location.
379   if (m_options_up == nullptr)
380     m_options_up = std::make_unique<BreakpointOptions>(false);
381 
382   return m_options_up.get();
383 }
384 
385 bool BreakpointLocation::ValidForThisThread(Thread *thread) {
386   return thread
387       ->MatchesSpec(GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
388       ->GetThreadSpecNoCreate());
389 }
390 
391 // RETURNS - true if we should stop at this breakpoint, false if we
392 // should continue.  Note, we don't check the thread spec for the breakpoint
393 // here, since if the breakpoint is not for this thread, then the event won't
394 // even get reported, so the check is redundant.
395 
396 bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) {
397   bool should_stop = true;
398   Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
399 
400   // Do this first, if a location is disabled, it shouldn't increment its hit
401   // count.
402   if (!IsEnabled())
403     return false;
404 
405   if (!IgnoreCountShouldStop())
406     return false;
407 
408   if (!m_owner.IgnoreCountShouldStop())
409     return false;
410 
411   // We only run synchronous callbacks in ShouldStop:
412   context->is_synchronous = true;
413   should_stop = InvokeCallback(context);
414 
415   if (log) {
416     StreamString s;
417     GetDescription(&s, lldb::eDescriptionLevelVerbose);
418     LLDB_LOGF(log, "Hit breakpoint location: %s, %s.\n", s.GetData(),
419               should_stop ? "stopping" : "continuing");
420   }
421 
422   return should_stop;
423 }
424 
425 void BreakpointLocation::BumpHitCount() {
426   if (IsEnabled()) {
427     // Step our hit count, and also step the hit count of the owner.
428     IncrementHitCount();
429     m_owner.IncrementHitCount();
430   }
431 }
432 
433 void BreakpointLocation::UndoBumpHitCount() {
434   if (IsEnabled()) {
435     // Step our hit count, and also step the hit count of the owner.
436     DecrementHitCount();
437     m_owner.DecrementHitCount();
438   }
439 }
440 
441 bool BreakpointLocation::IsResolved() const {
442   return m_bp_site_sp.get() != nullptr;
443 }
444 
445 lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const {
446   return m_bp_site_sp;
447 }
448 
449 bool BreakpointLocation::ResolveBreakpointSite() {
450   if (m_bp_site_sp)
451     return true;
452 
453   Process *process = m_owner.GetTarget().GetProcessSP().get();
454   if (process == nullptr)
455     return false;
456 
457   lldb::break_id_t new_id =
458       process->CreateBreakpointSite(shared_from_this(), m_owner.IsHardware());
459 
460   if (new_id == LLDB_INVALID_BREAK_ID) {
461     Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
462     if (log)
463       log->Warning("Failed to add breakpoint site at 0x%" PRIx64,
464                    m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()));
465   }
466 
467   return IsResolved();
468 }
469 
470 bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) {
471   m_bp_site_sp = bp_site_sp;
472   SendBreakpointLocationChangedEvent(eBreakpointEventTypeLocationsResolved);
473   return true;
474 }
475 
476 bool BreakpointLocation::ClearBreakpointSite() {
477   if (m_bp_site_sp.get()) {
478     ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
479     // If the process exists, get it to remove the owner, it will remove the
480     // physical implementation of the breakpoint as well if there are no more
481     // owners.  Otherwise just remove this owner.
482     if (process_sp)
483       process_sp->RemoveOwnerFromBreakpointSite(GetBreakpoint().GetID(),
484                                                 GetID(), m_bp_site_sp);
485     else
486       m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
487 
488     m_bp_site_sp.reset();
489     return true;
490   }
491   return false;
492 }
493 
494 void BreakpointLocation::GetDescription(Stream *s,
495                                         lldb::DescriptionLevel level) {
496   SymbolContext sc;
497 
498   // If the description level is "initial" then the breakpoint is printing out
499   // our initial state, and we should let it decide how it wants to print our
500   // label.
501   if (level != eDescriptionLevelInitial) {
502     s->Indent();
503     BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
504   }
505 
506   if (level == lldb::eDescriptionLevelBrief)
507     return;
508 
509   if (level != eDescriptionLevelInitial)
510     s->PutCString(": ");
511 
512   if (level == lldb::eDescriptionLevelVerbose)
513     s->IndentMore();
514 
515   if (m_address.IsSectionOffset()) {
516     m_address.CalculateSymbolContext(&sc);
517 
518     if (level == lldb::eDescriptionLevelFull ||
519         level == eDescriptionLevelInitial) {
520       if (IsReExported())
521         s->PutCString("re-exported target = ");
522       else
523         s->PutCString("where = ");
524       sc.DumpStopContext(s, m_owner.GetTarget().GetProcessSP().get(), m_address,
525                          false, true, false, true, true);
526     } else {
527       if (sc.module_sp) {
528         s->EOL();
529         s->Indent("module = ");
530         sc.module_sp->GetFileSpec().Dump(s->AsRawOstream());
531       }
532 
533       if (sc.comp_unit != nullptr) {
534         s->EOL();
535         s->Indent("compile unit = ");
536         sc.comp_unit->GetPrimaryFile().GetFilename().Dump(s);
537 
538         if (sc.function != nullptr) {
539           s->EOL();
540           s->Indent("function = ");
541           s->PutCString(sc.function->GetName().AsCString("<unknown>"));
542         }
543 
544         if (sc.line_entry.line > 0) {
545           s->EOL();
546           s->Indent("location = ");
547           sc.line_entry.DumpStopContext(s, true);
548         }
549 
550       } else {
551         // If we don't have a comp unit, see if we have a symbol we can print.
552         if (sc.symbol) {
553           s->EOL();
554           if (IsReExported())
555             s->Indent("re-exported target = ");
556           else
557             s->Indent("symbol = ");
558           s->PutCString(sc.symbol->GetName().AsCString("<unknown>"));
559         }
560       }
561     }
562   }
563 
564   if (level == lldb::eDescriptionLevelVerbose) {
565     s->EOL();
566     s->Indent();
567   }
568 
569   if (m_address.IsSectionOffset() &&
570       (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
571     s->Printf(", ");
572   s->Printf("address = ");
573 
574   ExecutionContextScope *exe_scope = nullptr;
575   Target *target = &m_owner.GetTarget();
576   if (target)
577     exe_scope = target->GetProcessSP().get();
578   if (exe_scope == nullptr)
579     exe_scope = target;
580 
581   if (level == eDescriptionLevelInitial)
582     m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
583                    Address::DumpStyleFileAddress);
584   else
585     m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
586                    Address::DumpStyleModuleWithFileAddress);
587 
588   if (IsIndirect() && m_bp_site_sp) {
589     Address resolved_address;
590     resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
591     Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
592     if (resolved_symbol) {
593       if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
594         s->Printf(", ");
595       else if (level == lldb::eDescriptionLevelVerbose) {
596         s->EOL();
597         s->Indent();
598       }
599       s->Printf("indirect target = %s",
600                 resolved_symbol->GetName().GetCString());
601     }
602   }
603 
604   if (level == lldb::eDescriptionLevelVerbose) {
605     s->EOL();
606     s->Indent();
607     s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
608     s->Indent();
609     s->Printf("hardware = %s\n", IsHardware() ? "true" : "false");
610     s->Indent();
611     s->Printf("hit count = %-4u\n", GetHitCount());
612 
613     if (m_options_up) {
614       s->Indent();
615       m_options_up->GetDescription(s, level);
616       s->EOL();
617     }
618     s->IndentLess();
619   } else if (level != eDescriptionLevelInitial) {
620     s->Printf(", %sresolved, %shit count = %u ", (IsResolved() ? "" : "un"),
621               (IsHardware() ? "hardware, " : ""), GetHitCount());
622     if (m_options_up) {
623       m_options_up->GetDescription(s, level);
624     }
625   }
626 }
627 
628 void BreakpointLocation::Dump(Stream *s) const {
629   if (s == nullptr)
630     return;
631 
632   lldb::tid_t tid = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
633       ->GetThreadSpecNoCreate()->GetTID();
634   s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64
635             "  load addr = 0x%8.8" PRIx64 "  state = %s  type = %s breakpoint  "
636             "hw_index = %i  hit_count = %-4u  ignore_count = %-4u",
637             GetID(), tid,
638             (uint64_t)m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()),
639             (m_options_up ? m_options_up->IsEnabled() : m_owner.IsEnabled())
640                 ? "enabled "
641                 : "disabled",
642             IsHardware() ? "hardware" : "software", GetHardwareIndex(),
643             GetHitCount(),
644             GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
645                 ->GetIgnoreCount());
646 }
647 
648 void BreakpointLocation::SendBreakpointLocationChangedEvent(
649     lldb::BreakpointEventType eventKind) {
650   if (!m_being_created && !m_owner.IsInternal() &&
651       m_owner.GetTarget().EventTypeHasListeners(
652           Target::eBroadcastBitBreakpointChanged)) {
653     Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData(
654         eventKind, m_owner.shared_from_this());
655     data->GetBreakpointLocationCollection().Add(shared_from_this());
656     m_owner.GetTarget().BroadcastEvent(Target::eBroadcastBitBreakpointChanged,
657                                        data);
658   }
659 }
660 
661 void BreakpointLocation::SwapLocation(BreakpointLocationSP swap_from) {
662   m_address = swap_from->m_address;
663   m_should_resolve_indirect_functions =
664       swap_from->m_should_resolve_indirect_functions;
665   m_is_reexported = swap_from->m_is_reexported;
666   m_is_indirect = swap_from->m_is_indirect;
667   m_user_expression_sp.reset();
668 }
669