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