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