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