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 bool BreakpointLocation::IsCallbackSynchronous() { 199 if (m_options_up != nullptr && m_options_up->HasCallback()) 200 return m_options_up->IsCallbackSynchronous(); 201 else 202 return m_owner.GetOptions()->IsCallbackSynchronous(); 203 } 204 205 void BreakpointLocation::SetCallback(BreakpointHitCallback callback, 206 void *baton, bool is_synchronous) { 207 // The default "Baton" class will keep a copy of "baton" and won't free or 208 // delete it when it goes goes out of scope. 209 GetLocationOptions()->SetCallback( 210 callback, std::make_shared<UntypedBaton>(baton), is_synchronous); 211 SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged); 212 } 213 214 void BreakpointLocation::SetCallback(BreakpointHitCallback callback, 215 const BatonSP &baton_sp, 216 bool is_synchronous) { 217 GetLocationOptions()->SetCallback(callback, baton_sp, is_synchronous); 218 SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged); 219 } 220 221 void BreakpointLocation::ClearCallback() { 222 GetLocationOptions()->ClearCallback(); 223 } 224 225 void BreakpointLocation::SetCondition(const char *condition) { 226 GetLocationOptions()->SetCondition(condition); 227 SendBreakpointLocationChangedEvent(eBreakpointEventTypeConditionChanged); 228 } 229 230 const char *BreakpointLocation::GetConditionText(size_t *hash) const { 231 return GetOptionsSpecifyingKind(BreakpointOptions::eCondition) 232 ->GetConditionText(hash); 233 } 234 235 bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx, 236 Status &error) { 237 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS); 238 239 std::lock_guard<std::mutex> guard(m_condition_mutex); 240 241 size_t condition_hash; 242 const char *condition_text = GetConditionText(&condition_hash); 243 244 if (!condition_text) { 245 m_user_expression_sp.reset(); 246 return false; 247 } 248 249 error.Clear(); 250 251 DiagnosticManager diagnostics; 252 253 if (condition_hash != m_condition_hash || !m_user_expression_sp || 254 !m_user_expression_sp->MatchesContext(exe_ctx)) { 255 LanguageType language = eLanguageTypeUnknown; 256 // See if we can figure out the language from the frame, otherwise use the 257 // default language: 258 CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit(); 259 if (comp_unit) 260 language = comp_unit->GetLanguage(); 261 262 m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage( 263 condition_text, llvm::StringRef(), language, Expression::eResultTypeAny, 264 EvaluateExpressionOptions(), nullptr, error)); 265 if (error.Fail()) { 266 LLDB_LOGF(log, "Error getting condition expression: %s.", 267 error.AsCString()); 268 m_user_expression_sp.reset(); 269 return true; 270 } 271 272 if (!m_user_expression_sp->Parse(diagnostics, exe_ctx, 273 eExecutionPolicyOnlyWhenNeeded, true, 274 false)) { 275 error.SetErrorStringWithFormat( 276 "Couldn't parse conditional expression:\n%s", 277 diagnostics.GetString().c_str()); 278 m_user_expression_sp.reset(); 279 return true; 280 } 281 282 m_condition_hash = condition_hash; 283 } 284 285 // We need to make sure the user sees any parse errors in their condition, so 286 // we'll hook the constructor errors up to the debugger's Async I/O. 287 288 ValueObjectSP result_value_sp; 289 290 EvaluateExpressionOptions options; 291 options.SetUnwindOnError(true); 292 options.SetIgnoreBreakpoints(true); 293 options.SetTryAllThreads(true); 294 options.SetResultIsInternal( 295 true); // Don't generate a user variable for condition expressions. 296 297 Status expr_error; 298 299 diagnostics.Clear(); 300 301 ExpressionVariableSP result_variable_sp; 302 303 ExpressionResults result_code = m_user_expression_sp->Execute( 304 diagnostics, exe_ctx, options, m_user_expression_sp, result_variable_sp); 305 306 bool ret; 307 308 if (result_code == eExpressionCompleted) { 309 if (!result_variable_sp) { 310 error.SetErrorString("Expression did not return a result"); 311 return false; 312 } 313 314 result_value_sp = result_variable_sp->GetValueObject(); 315 316 if (result_value_sp) { 317 ret = result_value_sp->IsLogicalTrue(error); 318 if (log) { 319 if (error.Success()) { 320 LLDB_LOGF(log, "Condition successfully evaluated, result is %s.\n", 321 ret ? "true" : "false"); 322 } else { 323 error.SetErrorString( 324 "Failed to get an integer result from the expression"); 325 ret = false; 326 } 327 } 328 } else { 329 ret = false; 330 error.SetErrorString("Failed to get any result from the expression"); 331 } 332 } else { 333 ret = false; 334 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", 335 diagnostics.GetString().c_str()); 336 } 337 338 return ret; 339 } 340 341 uint32_t BreakpointLocation::GetIgnoreCount() const { 342 return GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount) 343 ->GetIgnoreCount(); 344 } 345 346 void BreakpointLocation::SetIgnoreCount(uint32_t n) { 347 GetLocationOptions()->SetIgnoreCount(n); 348 SendBreakpointLocationChangedEvent(eBreakpointEventTypeIgnoreChanged); 349 } 350 351 void BreakpointLocation::DecrementIgnoreCount() { 352 if (m_options_up != nullptr) { 353 uint32_t loc_ignore = m_options_up->GetIgnoreCount(); 354 if (loc_ignore != 0) 355 m_options_up->SetIgnoreCount(loc_ignore - 1); 356 } 357 } 358 359 bool BreakpointLocation::IgnoreCountShouldStop() { 360 if (m_options_up != nullptr) { 361 uint32_t loc_ignore = m_options_up->GetIgnoreCount(); 362 if (loc_ignore != 0) { 363 m_owner.DecrementIgnoreCount(); 364 DecrementIgnoreCount(); // Have to decrement our owners' ignore count, 365 // since it won't get a 366 // chance to. 367 return false; 368 } 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.get(); 381 } 382 383 bool BreakpointLocation::ValidForThisThread(Thread *thread) { 384 return thread 385 ->MatchesSpec(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 = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_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 if (!IgnoreCountShouldStop()) 404 return false; 405 406 if (!m_owner.IgnoreCountShouldStop()) 407 return false; 408 409 // We only run synchronous callbacks in ShouldStop: 410 context->is_synchronous = true; 411 should_stop = InvokeCallback(context); 412 413 if (log) { 414 StreamString s; 415 GetDescription(&s, lldb::eDescriptionLevelVerbose); 416 LLDB_LOGF(log, "Hit breakpoint location: %s, %s.\n", s.GetData(), 417 should_stop ? "stopping" : "continuing"); 418 } 419 420 return should_stop; 421 } 422 423 void BreakpointLocation::BumpHitCount() { 424 if (IsEnabled()) { 425 // Step our hit count, and also step the hit count of the owner. 426 m_hit_counter.Increment(); 427 m_owner.m_hit_counter.Increment(); 428 } 429 } 430 431 void BreakpointLocation::UndoBumpHitCount() { 432 if (IsEnabled()) { 433 // Step our hit count, and also step the hit count of the owner. 434 m_hit_counter.Decrement(); 435 m_owner.m_hit_counter.Decrement(); 436 } 437 } 438 439 bool BreakpointLocation::IsResolved() const { 440 return m_bp_site_sp.get() != nullptr; 441 } 442 443 lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const { 444 return m_bp_site_sp; 445 } 446 447 bool BreakpointLocation::ResolveBreakpointSite() { 448 if (m_bp_site_sp) 449 return true; 450 451 Process *process = m_owner.GetTarget().GetProcessSP().get(); 452 if (process == nullptr) 453 return false; 454 455 lldb::break_id_t new_id = 456 process->CreateBreakpointSite(shared_from_this(), m_owner.IsHardware()); 457 458 if (new_id == LLDB_INVALID_BREAK_ID) { 459 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS); 460 if (log) 461 log->Warning("Failed to add breakpoint site at 0x%" PRIx64, 462 m_address.GetOpcodeLoadAddress(&m_owner.GetTarget())); 463 } 464 465 return IsResolved(); 466 } 467 468 bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) { 469 m_bp_site_sp = bp_site_sp; 470 SendBreakpointLocationChangedEvent(eBreakpointEventTypeLocationsResolved); 471 return true; 472 } 473 474 bool BreakpointLocation::ClearBreakpointSite() { 475 if (m_bp_site_sp.get()) { 476 ProcessSP process_sp(m_owner.GetTarget().GetProcessSP()); 477 // If the process exists, get it to remove the owner, it will remove the 478 // physical implementation of the breakpoint as well if there are no more 479 // owners. Otherwise just remove this owner. 480 if (process_sp) 481 process_sp->RemoveOwnerFromBreakpointSite(GetBreakpoint().GetID(), 482 GetID(), m_bp_site_sp); 483 else 484 m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID()); 485 486 m_bp_site_sp.reset(); 487 return true; 488 } 489 return false; 490 } 491 492 void BreakpointLocation::GetDescription(Stream *s, 493 lldb::DescriptionLevel level) { 494 SymbolContext sc; 495 496 // If the description level is "initial" then the breakpoint is printing out 497 // our initial state, and we should let it decide how it wants to print our 498 // label. 499 if (level != eDescriptionLevelInitial) { 500 s->Indent(); 501 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID()); 502 } 503 504 if (level == lldb::eDescriptionLevelBrief) 505 return; 506 507 if (level != eDescriptionLevelInitial) 508 s->PutCString(": "); 509 510 if (level == lldb::eDescriptionLevelVerbose) 511 s->IndentMore(); 512 513 if (m_address.IsSectionOffset()) { 514 m_address.CalculateSymbolContext(&sc); 515 516 if (level == lldb::eDescriptionLevelFull || 517 level == eDescriptionLevelInitial) { 518 if (IsReExported()) 519 s->PutCString("re-exported target = "); 520 else 521 s->PutCString("where = "); 522 sc.DumpStopContext(s, m_owner.GetTarget().GetProcessSP().get(), m_address, 523 false, true, false, true, true); 524 } else { 525 if (sc.module_sp) { 526 s->EOL(); 527 s->Indent("module = "); 528 sc.module_sp->GetFileSpec().Dump(s->AsRawOstream()); 529 } 530 531 if (sc.comp_unit != nullptr) { 532 s->EOL(); 533 s->Indent("compile unit = "); 534 sc.comp_unit->GetPrimaryFile().GetFilename().Dump(s); 535 536 if (sc.function != nullptr) { 537 s->EOL(); 538 s->Indent("function = "); 539 s->PutCString(sc.function->GetName().AsCString("<unknown>")); 540 } 541 542 if (sc.line_entry.line > 0) { 543 s->EOL(); 544 s->Indent("location = "); 545 sc.line_entry.DumpStopContext(s, true); 546 } 547 548 } else { 549 // If we don't have a comp unit, see if we have a symbol we can print. 550 if (sc.symbol) { 551 s->EOL(); 552 if (IsReExported()) 553 s->Indent("re-exported target = "); 554 else 555 s->Indent("symbol = "); 556 s->PutCString(sc.symbol->GetName().AsCString("<unknown>")); 557 } 558 } 559 } 560 } 561 562 if (level == lldb::eDescriptionLevelVerbose) { 563 s->EOL(); 564 s->Indent(); 565 } 566 567 if (m_address.IsSectionOffset() && 568 (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)) 569 s->Printf(", "); 570 s->Printf("address = "); 571 572 ExecutionContextScope *exe_scope = nullptr; 573 Target *target = &m_owner.GetTarget(); 574 if (target) 575 exe_scope = target->GetProcessSP().get(); 576 if (exe_scope == nullptr) 577 exe_scope = target; 578 579 if (level == eDescriptionLevelInitial) 580 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, 581 Address::DumpStyleFileAddress); 582 else 583 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, 584 Address::DumpStyleModuleWithFileAddress); 585 586 if (IsIndirect() && m_bp_site_sp) { 587 Address resolved_address; 588 resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target); 589 Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol(); 590 if (resolved_symbol) { 591 if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial) 592 s->Printf(", "); 593 else if (level == lldb::eDescriptionLevelVerbose) { 594 s->EOL(); 595 s->Indent(); 596 } 597 s->Printf("indirect target = %s", 598 resolved_symbol->GetName().GetCString()); 599 } 600 } 601 602 bool is_resolved = IsResolved(); 603 bool is_hardware = is_resolved && m_bp_site_sp->IsHardware(); 604 605 if (level == lldb::eDescriptionLevelVerbose) { 606 s->EOL(); 607 s->Indent(); 608 s->Printf("resolved = %s\n", is_resolved ? "true" : "false"); 609 s->Indent(); 610 s->Printf("hardware = %s\n", is_hardware ? "true" : "false"); 611 s->Indent(); 612 s->Printf("hit count = %-4u\n", GetHitCount()); 613 614 if (m_options_up) { 615 s->Indent(); 616 m_options_up->GetDescription(s, level); 617 s->EOL(); 618 } 619 s->IndentLess(); 620 } else if (level != eDescriptionLevelInitial) { 621 s->Printf(", %sresolved, %shit count = %u ", (is_resolved ? "" : "un"), 622 (is_hardware ? "hardware, " : ""), GetHitCount()); 623 if (m_options_up) { 624 m_options_up->GetDescription(s, level); 625 } 626 } 627 } 628 629 void BreakpointLocation::Dump(Stream *s) const { 630 if (s == nullptr) 631 return; 632 633 bool is_resolved = IsResolved(); 634 bool is_hardware = is_resolved && m_bp_site_sp->IsHardware(); 635 auto hardware_index = is_resolved ? 636 m_bp_site_sp->GetHardwareIndex() : LLDB_INVALID_INDEX32; 637 638 lldb::tid_t tid = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec) 639 ->GetThreadSpecNoCreate()->GetTID(); 640 s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64 641 " load addr = 0x%8.8" PRIx64 " state = %s type = %s breakpoint " 642 "hw_index = %i hit_count = %-4u ignore_count = %-4u", 643 GetID(), tid, 644 (uint64_t)m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()), 645 (m_options_up ? m_options_up->IsEnabled() : m_owner.IsEnabled()) 646 ? "enabled " 647 : "disabled", 648 is_hardware ? "hardware" : "software", hardware_index, GetHitCount(), 649 GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount) 650 ->GetIgnoreCount()); 651 } 652 653 void BreakpointLocation::SendBreakpointLocationChangedEvent( 654 lldb::BreakpointEventType eventKind) { 655 if (!m_being_created && !m_owner.IsInternal() && 656 m_owner.GetTarget().EventTypeHasListeners( 657 Target::eBroadcastBitBreakpointChanged)) { 658 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData( 659 eventKind, m_owner.shared_from_this()); 660 data->GetBreakpointLocationCollection().Add(shared_from_this()); 661 m_owner.GetTarget().BroadcastEvent(Target::eBroadcastBitBreakpointChanged, 662 data); 663 } 664 } 665 666 void BreakpointLocation::SwapLocation(BreakpointLocationSP swap_from) { 667 m_address = swap_from->m_address; 668 m_should_resolve_indirect_functions = 669 swap_from->m_should_resolve_indirect_functions; 670 m_is_reexported = swap_from->m_is_reexported; 671 m_is_indirect = swap_from->m_is_indirect; 672 m_user_expression_sp.reset(); 673 } 674