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