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