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