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                                                                             EvaluateExpressionOptions(),
297                                                                             error));
298         if (error.Fail())
299         {
300             if (log)
301                 log->Printf("Error getting condition expression: %s.", error.AsCString());
302             m_user_expression_sp.reset();
303             return true;
304         }
305 
306         StreamString errors;
307 
308         if (!m_user_expression_sp->Parse(errors,
309                                          exe_ctx,
310                                          eExecutionPolicyOnlyWhenNeeded,
311                                          true,
312                                          false))
313         {
314             error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s",
315                                            errors.GetData());
316             m_user_expression_sp.reset();
317             return false;
318         }
319 
320         m_condition_hash = condition_hash;
321     }
322 
323     // We need to make sure the user sees any parse errors in their condition, so we'll hook the
324     // constructor errors up to the debugger's Async I/O.
325 
326     ValueObjectSP result_value_sp;
327 
328     EvaluateExpressionOptions options;
329     options.SetUnwindOnError(true);
330     options.SetIgnoreBreakpoints(true);
331     options.SetTryAllThreads(true);
332 
333     Error expr_error;
334 
335     StreamString execution_errors;
336 
337     ExpressionVariableSP result_variable_sp;
338 
339     ExpressionResults result_code =
340     m_user_expression_sp->Execute(execution_errors,
341                                   exe_ctx,
342                                   options,
343                                   m_user_expression_sp,
344                                   result_variable_sp);
345 
346     bool ret;
347 
348     if (result_code == eExpressionCompleted)
349     {
350         if (!result_variable_sp)
351         {
352             error.SetErrorString("Expression did not return a result");
353             return false;
354         }
355 
356         result_value_sp = result_variable_sp->GetValueObject();
357 
358         if (result_value_sp)
359         {
360             ret = result_value_sp->IsLogicalTrue(error);
361             if (log)
362             {
363                 if (error.Success())
364                 {
365                     log->Printf("Condition successfully evaluated, result is %s.\n",
366                                 ret ? "true" : "false");
367                 }
368                 else
369                 {
370                     error.SetErrorString("Failed to get an integer result from the expression");
371                     ret = false;
372                 }
373 
374             }
375         }
376         else
377         {
378             ret = false;
379             error.SetErrorString("Failed to get any result from the expression");
380         }
381     }
382     else
383     {
384         ret = false;
385         error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData());
386     }
387 
388     return ret;
389 }
390 
391 uint32_t
392 BreakpointLocation::GetIgnoreCount ()
393 {
394     return GetOptionsNoCreate()->GetIgnoreCount();
395 }
396 
397 void
398 BreakpointLocation::SetIgnoreCount (uint32_t n)
399 {
400     GetLocationOptions()->SetIgnoreCount(n);
401     SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged);
402 }
403 
404 void
405 BreakpointLocation::DecrementIgnoreCount()
406 {
407     if (m_options_ap.get() != nullptr)
408     {
409         uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
410         if (loc_ignore != 0)
411             m_options_ap->SetIgnoreCount(loc_ignore - 1);
412     }
413 }
414 
415 bool
416 BreakpointLocation::IgnoreCountShouldStop()
417 {
418     if (m_options_ap.get() != nullptr)
419     {
420         uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
421         if (loc_ignore != 0)
422         {
423             m_owner.DecrementIgnoreCount();
424             DecrementIgnoreCount();          // Have to decrement our owners' ignore count, since it won't get a
425                                              // chance to.
426             return false;
427         }
428     }
429     return true;
430 }
431 
432 const BreakpointOptions *
433 BreakpointLocation::GetOptionsNoCreate () const
434 {
435     if (m_options_ap.get() != nullptr)
436         return m_options_ap.get();
437     else
438         return m_owner.GetOptions ();
439 }
440 
441 BreakpointOptions *
442 BreakpointLocation::GetLocationOptions ()
443 {
444     // If we make the copy we don't copy the callbacks because that is potentially
445     // expensive and we don't want to do that for the simple case where someone is
446     // just disabling the location.
447     if (m_options_ap.get() == nullptr)
448         m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ()));
449 
450     return m_options_ap.get();
451 }
452 
453 bool
454 BreakpointLocation::ValidForThisThread (Thread *thread)
455 {
456     return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
457 }
458 
459 // RETURNS - true if we should stop at this breakpoint, false if we
460 // should continue.  Note, we don't check the thread spec for the breakpoint
461 // here, since if the breakpoint is not for this thread, then the event won't
462 // even get reported, so the check is redundant.
463 
464 bool
465 BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
466 {
467     bool should_stop = true;
468     Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
469 
470     // Do this first, if a location is disabled, it shouldn't increment its hit count.
471     if (!IsEnabled())
472         return false;
473 
474     if (!IgnoreCountShouldStop())
475         return false;
476 
477     if (!m_owner.IgnoreCountShouldStop())
478         return false;
479 
480     // We only run synchronous callbacks in ShouldStop:
481     context->is_synchronous = true;
482     should_stop = InvokeCallback (context);
483 
484     if (log)
485     {
486         StreamString s;
487         GetDescription (&s, lldb::eDescriptionLevelVerbose);
488         log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing");
489     }
490 
491     return should_stop;
492 }
493 
494 void
495 BreakpointLocation::BumpHitCount()
496 {
497     if (IsEnabled())
498     {
499         // Step our hit count, and also step the hit count of the owner.
500         IncrementHitCount();
501         m_owner.IncrementHitCount();
502     }
503 }
504 
505 void
506 BreakpointLocation::UndoBumpHitCount()
507 {
508     if (IsEnabled())
509     {
510         // Step our hit count, and also step the hit count of the owner.
511         DecrementHitCount();
512         m_owner.DecrementHitCount();
513     }
514 }
515 
516 bool
517 BreakpointLocation::IsResolved () const
518 {
519     return m_bp_site_sp.get() != nullptr;
520 }
521 
522 lldb::BreakpointSiteSP
523 BreakpointLocation::GetBreakpointSite() const
524 {
525     return m_bp_site_sp;
526 }
527 
528 bool
529 BreakpointLocation::ResolveBreakpointSite ()
530 {
531     if (m_bp_site_sp)
532         return true;
533 
534     Process *process = m_owner.GetTarget().GetProcessSP().get();
535     if (process == nullptr)
536         return false;
537 
538     lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), m_owner.IsHardware());
539 
540     if (new_id == LLDB_INVALID_BREAK_ID)
541     {
542         Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
543         if (log)
544             log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n",
545                           m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()));
546         return false;
547     }
548 
549     return true;
550 }
551 
552 bool
553 BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp)
554 {
555     m_bp_site_sp = bp_site_sp;
556     SendBreakpointLocationChangedEvent (eBreakpointEventTypeLocationsResolved);
557     return true;
558 }
559 
560 bool
561 BreakpointLocation::ClearBreakpointSite ()
562 {
563     if (m_bp_site_sp.get())
564     {
565         ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
566         // If the process exists, get it to remove the owner, it will remove the physical implementation
567         // of the breakpoint as well if there are no more owners.  Otherwise just remove this owner.
568         if (process_sp)
569             process_sp->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(),
570                                                                            GetID(), m_bp_site_sp);
571         else
572             m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
573 
574         m_bp_site_sp.reset();
575         return true;
576     }
577     return false;
578 }
579 
580 void
581 BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
582 {
583     SymbolContext sc;
584 
585     // If the description level is "initial" then the breakpoint is printing out our initial state,
586     // and we should let it decide how it wants to print our label.
587     if (level != eDescriptionLevelInitial)
588     {
589         s->Indent();
590         BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
591     }
592 
593     if (level == lldb::eDescriptionLevelBrief)
594         return;
595 
596     if (level != eDescriptionLevelInitial)
597         s->PutCString(": ");
598 
599     if (level == lldb::eDescriptionLevelVerbose)
600         s->IndentMore();
601 
602     if (m_address.IsSectionOffset())
603     {
604         m_address.CalculateSymbolContext(&sc);
605 
606         if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
607         {
608             if (IsReExported())
609                 s->PutCString ("re-exported target = ");
610             else
611                 s->PutCString("where = ");
612             sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false, true, true);
613         }
614         else
615         {
616             if (sc.module_sp)
617             {
618                 s->EOL();
619                 s->Indent("module = ");
620                 sc.module_sp->GetFileSpec().Dump (s);
621             }
622 
623             if (sc.comp_unit != nullptr)
624             {
625                 s->EOL();
626                 s->Indent("compile unit = ");
627                 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);
628 
629                 if (sc.function != nullptr)
630                 {
631                     s->EOL();
632                     s->Indent("function = ");
633                     s->PutCString (sc.function->GetName().AsCString("<unknown>"));
634                 }
635 
636                 if (sc.line_entry.line > 0)
637                 {
638                     s->EOL();
639                     s->Indent("location = ");
640                     sc.line_entry.DumpStopContext (s, true);
641                 }
642 
643             }
644             else
645             {
646                 // If we don't have a comp unit, see if we have a symbol we can print.
647                 if (sc.symbol)
648                 {
649                     s->EOL();
650                     if (IsReExported())
651                         s->Indent ("re-exported target = ");
652                     else
653                         s->Indent("symbol = ");
654                     s->PutCString(sc.symbol->GetName().AsCString("<unknown>"));
655                 }
656             }
657         }
658     }
659 
660     if (level == lldb::eDescriptionLevelVerbose)
661     {
662         s->EOL();
663         s->Indent();
664     }
665 
666     if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
667         s->Printf (", ");
668     s->Printf ("address = ");
669 
670     ExecutionContextScope *exe_scope = nullptr;
671     Target *target = &m_owner.GetTarget();
672     if (target)
673         exe_scope = target->GetProcessSP().get();
674     if (exe_scope == nullptr)
675         exe_scope = target;
676 
677     if (level == eDescriptionLevelInitial)
678         m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
679     else
680         m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
681 
682     if (IsIndirect() && m_bp_site_sp)
683     {
684         Address resolved_address;
685         resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
686         Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
687         if (resolved_symbol)
688         {
689             if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
690                 s->Printf (", ");
691             else if (level == lldb::eDescriptionLevelVerbose)
692             {
693                 s->EOL();
694                 s->Indent();
695             }
696             s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString());
697         }
698     }
699 
700     if (level == lldb::eDescriptionLevelVerbose)
701     {
702         s->EOL();
703         s->Indent();
704         s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
705 
706         s->Indent();
707         s->Printf ("hit count = %-4u\n", GetHitCount());
708 
709         if (m_options_ap.get())
710         {
711             s->Indent();
712             m_options_ap->GetDescription (s, level);
713             s->EOL();
714         }
715         s->IndentLess();
716     }
717     else if (level != eDescriptionLevelInitial)
718     {
719         s->Printf(", %sresolved, hit count = %u ",
720                   (IsResolved() ? "" : "un"),
721                   GetHitCount());
722         if (m_options_ap.get())
723         {
724             m_options_ap->GetDescription (s, level);
725         }
726     }
727 }
728 
729 void
730 BreakpointLocation::Dump(Stream *s) const
731 {
732     if (s == nullptr)
733         return;
734 
735     s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64 "  load addr = 0x%8.8" PRIx64 "  state = %s  type = %s breakpoint  "
736               "hw_index = %i  hit_count = %-4u  ignore_count = %-4u",
737               GetID(),
738               GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
739               (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()),
740               (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled",
741               IsHardware() ? "hardware" : "software",
742               GetHardwareIndex(),
743               GetHitCount(),
744               GetOptionsNoCreate()->GetIgnoreCount());
745 }
746 
747 void
748 BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind)
749 {
750     if (!m_being_created
751         && !m_owner.IsInternal()
752         && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
753     {
754         Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind,
755                                                                                      m_owner.shared_from_this());
756         data->GetBreakpointLocationCollection().Add (shared_from_this());
757         m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
758     }
759 }
760 
761 void
762 BreakpointLocation::SwapLocation (BreakpointLocationSP swap_from)
763 {
764     m_address = swap_from->m_address;
765     m_should_resolve_indirect_functions = swap_from->m_should_resolve_indirect_functions;
766     m_is_reexported = swap_from->m_is_reexported;
767     m_is_indirect = swap_from->m_is_indirect;
768     m_user_expression_sp.reset();
769 }
770