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