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