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