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