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