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