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/Breakpoint/BreakpointLocation.h" 19 #include "lldb/Breakpoint/BreakpointID.h" 20 #include "lldb/Breakpoint/StoppointCallbackContext.h" 21 #include "lldb/Core/Debugger.h" 22 #include "lldb/Core/Log.h" 23 #include "lldb/Core/Module.h" 24 #include "lldb/Core/StreamString.h" 25 #include "lldb/Core/ValueObject.h" 26 #include "lldb/Expression/ClangUserExpression.h" 27 #include "lldb/Symbol/CompileUnit.h" 28 #include "lldb/Symbol/Symbol.h" 29 #include "lldb/Target/Target.h" 30 #include "lldb/Target/Process.h" 31 #include "lldb/Target/Thread.h" 32 #include "lldb/Target/ThreadSpec.h" 33 34 using namespace lldb; 35 using namespace lldb_private; 36 37 BreakpointLocation::BreakpointLocation 38 ( 39 break_id_t loc_id, 40 Breakpoint &owner, 41 const Address &addr, 42 lldb::tid_t tid, 43 bool hardware, 44 bool check_for_resolver 45 ) : 46 StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware), 47 m_being_created(true), 48 m_should_resolve_indirect_functions (false), 49 m_is_reexported (false), 50 m_is_indirect (false), 51 m_address (addr), 52 m_owner (owner), 53 m_options_ap (), 54 m_bp_site_sp (), 55 m_condition_mutex () 56 { 57 if (check_for_resolver) 58 { 59 Symbol *symbol = m_address.CalculateSymbolContextSymbol(); 60 if (symbol && symbol->IsIndirect()) 61 { 62 SetShouldResolveIndirectFunctions (true); 63 } 64 } 65 66 SetThreadID (tid); 67 m_being_created = false; 68 } 69 70 BreakpointLocation::~BreakpointLocation() 71 { 72 ClearBreakpointSite(); 73 } 74 75 lldb::addr_t 76 BreakpointLocation::GetLoadAddress () const 77 { 78 return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()); 79 } 80 81 Address & 82 BreakpointLocation::GetAddress () 83 { 84 return m_address; 85 } 86 87 Breakpoint & 88 BreakpointLocation::GetBreakpoint () 89 { 90 return m_owner; 91 } 92 93 bool 94 BreakpointLocation::IsEnabled () const 95 { 96 if (!m_owner.IsEnabled()) 97 return false; 98 else if (m_options_ap.get() != NULL) 99 return m_options_ap->IsEnabled(); 100 else 101 return true; 102 } 103 104 void 105 BreakpointLocation::SetEnabled (bool enabled) 106 { 107 GetLocationOptions()->SetEnabled(enabled); 108 if (enabled) 109 { 110 ResolveBreakpointSite(); 111 } 112 else 113 { 114 ClearBreakpointSite(); 115 } 116 SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled); 117 } 118 119 void 120 BreakpointLocation::SetThreadID (lldb::tid_t thread_id) 121 { 122 if (thread_id != LLDB_INVALID_THREAD_ID) 123 GetLocationOptions()->SetThreadID(thread_id); 124 else 125 { 126 // If we're resetting this to an invalid thread id, then 127 // don't make an options pointer just to do that. 128 if (m_options_ap.get() != NULL) 129 m_options_ap->SetThreadID (thread_id); 130 } 131 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); 132 } 133 134 lldb::tid_t 135 BreakpointLocation::GetThreadID () 136 { 137 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 138 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(); 139 else 140 return LLDB_INVALID_THREAD_ID; 141 } 142 143 void 144 BreakpointLocation::SetThreadIndex (uint32_t index) 145 { 146 if (index != 0) 147 GetLocationOptions()->GetThreadSpec()->SetIndex(index); 148 else 149 { 150 // If we're resetting this to an invalid thread id, then 151 // don't make an options pointer just to do that. 152 if (m_options_ap.get() != NULL) 153 m_options_ap->GetThreadSpec()->SetIndex(index); 154 } 155 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); 156 157 } 158 159 uint32_t 160 BreakpointLocation::GetThreadIndex() const 161 { 162 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 163 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex(); 164 else 165 return 0; 166 } 167 168 void 169 BreakpointLocation::SetThreadName (const char *thread_name) 170 { 171 if (thread_name != NULL) 172 GetLocationOptions()->GetThreadSpec()->SetName(thread_name); 173 else 174 { 175 // If we're resetting this to an invalid thread id, then 176 // don't make an options pointer just to do that. 177 if (m_options_ap.get() != NULL) 178 m_options_ap->GetThreadSpec()->SetName(thread_name); 179 } 180 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); 181 } 182 183 const char * 184 BreakpointLocation::GetThreadName () const 185 { 186 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 187 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName(); 188 else 189 return NULL; 190 } 191 192 void 193 BreakpointLocation::SetQueueName (const char *queue_name) 194 { 195 if (queue_name != NULL) 196 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name); 197 else 198 { 199 // If we're resetting this to an invalid thread id, then 200 // don't make an options pointer just to do that. 201 if (m_options_ap.get() != NULL) 202 m_options_ap->GetThreadSpec()->SetQueueName(queue_name); 203 } 204 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); 205 } 206 207 const char * 208 BreakpointLocation::GetQueueName () const 209 { 210 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 211 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName(); 212 else 213 return NULL; 214 } 215 216 bool 217 BreakpointLocation::InvokeCallback (StoppointCallbackContext *context) 218 { 219 if (m_options_ap.get() != NULL && m_options_ap->HasCallback()) 220 return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID()); 221 else 222 return m_owner.InvokeCallback (context, GetID()); 223 } 224 225 void 226 BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton, 227 bool is_synchronous) 228 { 229 // The default "Baton" class will keep a copy of "baton" and won't free 230 // or delete it when it goes goes out of scope. 231 GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous); 232 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged); 233 } 234 235 void 236 BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp, 237 bool is_synchronous) 238 { 239 GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous); 240 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged); 241 } 242 243 244 void 245 BreakpointLocation::ClearCallback () 246 { 247 GetLocationOptions()->ClearCallback(); 248 } 249 250 void 251 BreakpointLocation::SetCondition (const char *condition) 252 { 253 GetLocationOptions()->SetCondition (condition); 254 SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged); 255 } 256 257 const char * 258 BreakpointLocation::GetConditionText (size_t *hash) const 259 { 260 return GetOptionsNoCreate()->GetConditionText(hash); 261 } 262 263 bool 264 BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error) 265 { 266 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 267 268 Mutex::Locker evaluation_locker(m_condition_mutex); 269 270 size_t condition_hash; 271 const char *condition_text = GetConditionText(&condition_hash); 272 273 if (!condition_text) 274 { 275 m_user_expression_sp.reset(); 276 return false; 277 } 278 279 if (condition_hash != m_condition_hash || 280 !m_user_expression_sp || 281 !m_user_expression_sp->MatchesContext(exe_ctx)) 282 { 283 m_user_expression_sp.reset(new ClangUserExpression(condition_text, 284 NULL, 285 lldb::eLanguageTypeUnknown, 286 ClangUserExpression::eResultTypeAny)); 287 288 StreamString errors; 289 290 if (!m_user_expression_sp->Parse(errors, 291 exe_ctx, 292 eExecutionPolicyOnlyWhenNeeded, 293 true, 294 false)) 295 { 296 error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s", 297 errors.GetData()); 298 m_user_expression_sp.reset(); 299 return false; 300 } 301 302 m_condition_hash = condition_hash; 303 } 304 305 // We need to make sure the user sees any parse errors in their condition, so we'll hook the 306 // constructor errors up to the debugger's Async I/O. 307 308 ValueObjectSP result_value_sp; 309 310 EvaluateExpressionOptions options; 311 options.SetUnwindOnError(true); 312 options.SetIgnoreBreakpoints(true); 313 options.SetTryAllThreads(true); 314 315 Error expr_error; 316 317 StreamString execution_errors; 318 319 ClangExpressionVariableSP result_variable_sp; 320 321 ExpressionResults result_code = 322 m_user_expression_sp->Execute(execution_errors, 323 exe_ctx, 324 options, 325 m_user_expression_sp, 326 result_variable_sp); 327 328 bool ret; 329 330 if (result_code == eExpressionCompleted) 331 { 332 if (!result_variable_sp) 333 { 334 error.SetErrorString("Expression did not return a result"); 335 return false; 336 } 337 338 result_value_sp = result_variable_sp->GetValueObject(); 339 340 if (result_value_sp) 341 { 342 Scalar scalar_value; 343 if (result_value_sp->ResolveValue (scalar_value)) 344 { 345 if (scalar_value.ULongLong(1) == 0) 346 ret = false; 347 else 348 ret = true; 349 if (log) 350 log->Printf("Condition successfully evaluated, result is %s.\n", 351 ret ? "true" : "false"); 352 } 353 else 354 { 355 ret = false; 356 error.SetErrorString("Failed to get an integer result from the expression"); 357 } 358 } 359 else 360 { 361 ret = false; 362 error.SetErrorString("Failed to get any result from the expression"); 363 } 364 } 365 else 366 { 367 ret = false; 368 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData()); 369 } 370 371 return ret; 372 } 373 374 uint32_t 375 BreakpointLocation::GetIgnoreCount () 376 { 377 return GetOptionsNoCreate()->GetIgnoreCount(); 378 } 379 380 void 381 BreakpointLocation::SetIgnoreCount (uint32_t n) 382 { 383 GetLocationOptions()->SetIgnoreCount(n); 384 SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged); 385 } 386 387 void 388 BreakpointLocation::DecrementIgnoreCount() 389 { 390 if (m_options_ap.get() != NULL) 391 { 392 uint32_t loc_ignore = m_options_ap->GetIgnoreCount(); 393 if (loc_ignore != 0) 394 m_options_ap->SetIgnoreCount(loc_ignore - 1); 395 } 396 } 397 398 bool 399 BreakpointLocation::IgnoreCountShouldStop() 400 { 401 if (m_options_ap.get() != NULL) 402 { 403 uint32_t loc_ignore = m_options_ap->GetIgnoreCount(); 404 if (loc_ignore != 0) 405 { 406 m_owner.DecrementIgnoreCount(); 407 DecrementIgnoreCount(); // Have to decrement our owners' ignore count, since it won't get a 408 // chance to. 409 return false; 410 } 411 } 412 return true; 413 } 414 415 const BreakpointOptions * 416 BreakpointLocation::GetOptionsNoCreate () const 417 { 418 if (m_options_ap.get() != NULL) 419 return m_options_ap.get(); 420 else 421 return m_owner.GetOptions (); 422 } 423 424 BreakpointOptions * 425 BreakpointLocation::GetLocationOptions () 426 { 427 // If we make the copy we don't copy the callbacks because that is potentially 428 // expensive and we don't want to do that for the simple case where someone is 429 // just disabling the location. 430 if (m_options_ap.get() == NULL) 431 m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ())); 432 433 return m_options_ap.get(); 434 } 435 436 bool 437 BreakpointLocation::ValidForThisThread (Thread *thread) 438 { 439 return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate()); 440 } 441 442 // RETURNS - true if we should stop at this breakpoint, false if we 443 // should continue. Note, we don't check the thread spec for the breakpoint 444 // here, since if the breakpoint is not for this thread, then the event won't 445 // even get reported, so the check is redundant. 446 447 bool 448 BreakpointLocation::ShouldStop (StoppointCallbackContext *context) 449 { 450 bool should_stop = true; 451 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 452 453 // Do this first, if a location is disabled, it shouldn't increment its hit count. 454 if (!IsEnabled()) 455 return false; 456 457 if (!IgnoreCountShouldStop()) 458 return false; 459 460 if (!m_owner.IgnoreCountShouldStop()) 461 return false; 462 463 // We only run synchronous callbacks in ShouldStop: 464 context->is_synchronous = true; 465 should_stop = InvokeCallback (context); 466 467 if (log) 468 { 469 StreamString s; 470 GetDescription (&s, lldb::eDescriptionLevelVerbose); 471 log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing"); 472 } 473 474 return should_stop; 475 } 476 477 void 478 BreakpointLocation::BumpHitCount() 479 { 480 if (IsEnabled()) 481 { 482 // Step our hit count, and also step the hit count of the owner. 483 IncrementHitCount(); 484 m_owner.IncrementHitCount(); 485 } 486 } 487 488 void 489 BreakpointLocation::UndoBumpHitCount() 490 { 491 if (IsEnabled()) 492 { 493 // Step our hit count, and also step the hit count of the owner. 494 DecrementHitCount(); 495 m_owner.DecrementHitCount(); 496 } 497 } 498 499 bool 500 BreakpointLocation::IsResolved () const 501 { 502 return m_bp_site_sp.get() != NULL; 503 } 504 505 lldb::BreakpointSiteSP 506 BreakpointLocation::GetBreakpointSite() const 507 { 508 return m_bp_site_sp; 509 } 510 511 bool 512 BreakpointLocation::ResolveBreakpointSite () 513 { 514 if (m_bp_site_sp) 515 return true; 516 517 Process *process = m_owner.GetTarget().GetProcessSP().get(); 518 if (process == NULL) 519 return false; 520 521 lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), m_owner.IsHardware()); 522 523 if (new_id == LLDB_INVALID_BREAK_ID) 524 { 525 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 526 if (log) 527 log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n", 528 m_address.GetOpcodeLoadAddress (&m_owner.GetTarget())); 529 return false; 530 } 531 532 return true; 533 } 534 535 bool 536 BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp) 537 { 538 m_bp_site_sp = bp_site_sp; 539 SendBreakpointLocationChangedEvent (eBreakpointEventTypeLocationsResolved); 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