BreakpointLocation.cpp revision 276479
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 33using namespace lldb; 34using namespace lldb_private; 35 36BreakpointLocation::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 69BreakpointLocation::~BreakpointLocation() 70{ 71 ClearBreakpointSite(); 72} 73 74lldb::addr_t 75BreakpointLocation::GetLoadAddress () const 76{ 77 return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()); 78} 79 80Address & 81BreakpointLocation::GetAddress () 82{ 83 return m_address; 84} 85 86Breakpoint & 87BreakpointLocation::GetBreakpoint () 88{ 89 return m_owner; 90} 91 92bool 93BreakpointLocation::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 103void 104BreakpointLocation::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 118void 119BreakpointLocation::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 133lldb::tid_t 134BreakpointLocation::GetThreadID () 135{ 136 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 137 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(); 138 else 139 return LLDB_INVALID_THREAD_ID; 140} 141 142void 143BreakpointLocation::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 158uint32_t 159BreakpointLocation::GetThreadIndex() const 160{ 161 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 162 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex(); 163 else 164 return 0; 165} 166 167void 168BreakpointLocation::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 182const char * 183BreakpointLocation::GetThreadName () const 184{ 185 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 186 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName(); 187 else 188 return NULL; 189} 190 191void 192BreakpointLocation::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 206const char * 207BreakpointLocation::GetQueueName () const 208{ 209 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 210 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName(); 211 else 212 return NULL; 213} 214 215bool 216BreakpointLocation::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 224void 225BreakpointLocation::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 234void 235BreakpointLocation::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 243void 244BreakpointLocation::ClearCallback () 245{ 246 GetLocationOptions()->ClearCallback(); 247} 248 249void 250BreakpointLocation::SetCondition (const char *condition) 251{ 252 GetLocationOptions()->SetCondition (condition); 253 SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged); 254} 255 256const char * 257BreakpointLocation::GetConditionText (size_t *hash) const 258{ 259 return GetOptionsNoCreate()->GetConditionText(hash); 260} 261 262bool 263BreakpointLocation::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 373uint32_t 374BreakpointLocation::GetIgnoreCount () 375{ 376 return GetOptionsNoCreate()->GetIgnoreCount(); 377} 378 379void 380BreakpointLocation::SetIgnoreCount (uint32_t n) 381{ 382 GetLocationOptions()->SetIgnoreCount(n); 383 SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged); 384} 385 386void 387BreakpointLocation::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 397bool 398BreakpointLocation::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 414const BreakpointOptions * 415BreakpointLocation::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 423BreakpointOptions * 424BreakpointLocation::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 435bool 436BreakpointLocation::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 446bool 447BreakpointLocation::ShouldStop (StoppointCallbackContext *context) 448{ 449 bool should_stop = true; 450 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 451 452 IncrementHitCount(); 453 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 477bool 478BreakpointLocation::IsResolved () const 479{ 480 return m_bp_site_sp.get() != NULL; 481} 482 483lldb::BreakpointSiteSP 484BreakpointLocation::GetBreakpointSite() const 485{ 486 return m_bp_site_sp; 487} 488 489bool 490BreakpointLocation::ResolveBreakpointSite () 491{ 492 if (m_bp_site_sp) 493 return true; 494 495 Process *process = m_owner.GetTarget().GetProcessSP().get(); 496 if (process == NULL) 497 return false; 498 499 lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), m_owner.IsHardware()); 500 501 if (new_id == LLDB_INVALID_BREAK_ID) 502 { 503 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 504 if (log) 505 log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n", 506 m_address.GetOpcodeLoadAddress (&m_owner.GetTarget())); 507 return false; 508 } 509 510 return true; 511} 512 513bool 514BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp) 515{ 516 m_bp_site_sp = bp_site_sp; 517 return true; 518} 519 520bool 521BreakpointLocation::ClearBreakpointSite () 522{ 523 if (m_bp_site_sp.get()) 524 { 525 ProcessSP process_sp(m_owner.GetTarget().GetProcessSP()); 526 // If the process exists, get it to remove the owner, it will remove the physical implementation 527 // of the breakpoint as well if there are no more owners. Otherwise just remove this owner. 528 if (process_sp) 529 process_sp->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(), 530 GetID(), m_bp_site_sp); 531 else 532 m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID()); 533 534 m_bp_site_sp.reset(); 535 return true; 536 } 537 return false; 538} 539 540void 541BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level) 542{ 543 SymbolContext sc; 544 545 // If the description level is "initial" then the breakpoint is printing out our initial state, 546 // and we should let it decide how it wants to print our label. 547 if (level != eDescriptionLevelInitial) 548 { 549 s->Indent(); 550 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID()); 551 } 552 553 if (level == lldb::eDescriptionLevelBrief) 554 return; 555 556 if (level != eDescriptionLevelInitial) 557 s->PutCString(": "); 558 559 if (level == lldb::eDescriptionLevelVerbose) 560 s->IndentMore(); 561 562 if (m_address.IsSectionOffset()) 563 { 564 m_address.CalculateSymbolContext(&sc); 565 566 if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial) 567 { 568 if (IsReExported()) 569 s->PutCString ("re-exported target = "); 570 else 571 s->PutCString("where = "); 572 sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false); 573 } 574 else 575 { 576 if (sc.module_sp) 577 { 578 s->EOL(); 579 s->Indent("module = "); 580 sc.module_sp->GetFileSpec().Dump (s); 581 } 582 583 if (sc.comp_unit != NULL) 584 { 585 s->EOL(); 586 s->Indent("compile unit = "); 587 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s); 588 589 if (sc.function != NULL) 590 { 591 s->EOL(); 592 s->Indent("function = "); 593 s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>")); 594 } 595 596 if (sc.line_entry.line > 0) 597 { 598 s->EOL(); 599 s->Indent("location = "); 600 sc.line_entry.DumpStopContext (s, true); 601 } 602 603 } 604 else 605 { 606 // If we don't have a comp unit, see if we have a symbol we can print. 607 if (sc.symbol) 608 { 609 s->EOL(); 610 if (IsReExported()) 611 s->Indent ("re-exported target = "); 612 else 613 s->Indent("symbol = "); 614 s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>")); 615 } 616 } 617 } 618 } 619 620 if (level == lldb::eDescriptionLevelVerbose) 621 { 622 s->EOL(); 623 s->Indent(); 624 } 625 626 if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)) 627 s->Printf (", "); 628 s->Printf ("address = "); 629 630 ExecutionContextScope *exe_scope = NULL; 631 Target *target = &m_owner.GetTarget(); 632 if (target) 633 exe_scope = target->GetProcessSP().get(); 634 if (exe_scope == NULL) 635 exe_scope = target; 636 637 if (level == eDescriptionLevelInitial) 638 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); 639 else 640 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress); 641 642 if (IsIndirect() && m_bp_site_sp) 643 { 644 Address resolved_address; 645 resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target); 646 Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol(); 647 if (resolved_symbol) 648 { 649 if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial) 650 s->Printf (", "); 651 else if (level == lldb::eDescriptionLevelVerbose) 652 { 653 s->EOL(); 654 s->Indent(); 655 } 656 s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString()); 657 } 658 } 659 660 if (level == lldb::eDescriptionLevelVerbose) 661 { 662 s->EOL(); 663 s->Indent(); 664 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false"); 665 666 s->Indent(); 667 s->Printf ("hit count = %-4u\n", GetHitCount()); 668 669 if (m_options_ap.get()) 670 { 671 s->Indent(); 672 m_options_ap->GetDescription (s, level); 673 s->EOL(); 674 } 675 s->IndentLess(); 676 } 677 else if (level != eDescriptionLevelInitial) 678 { 679 s->Printf(", %sresolved, hit count = %u ", 680 (IsResolved() ? "" : "un"), 681 GetHitCount()); 682 if (m_options_ap.get()) 683 { 684 m_options_ap->GetDescription (s, level); 685 } 686 } 687} 688 689void 690BreakpointLocation::Dump(Stream *s) const 691{ 692 if (s == NULL) 693 return; 694 695 s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64 " load addr = 0x%8.8" PRIx64 " state = %s type = %s breakpoint " 696 "hw_index = %i hit_count = %-4u ignore_count = %-4u", 697 GetID(), 698 GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(), 699 (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()), 700 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled", 701 IsHardware() ? "hardware" : "software", 702 GetHardwareIndex(), 703 GetHitCount(), 704 GetOptionsNoCreate()->GetIgnoreCount()); 705} 706 707void 708BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind) 709{ 710 if (!m_being_created 711 && !m_owner.IsInternal() 712 && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 713 { 714 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, 715 m_owner.shared_from_this()); 716 data->GetBreakpointLocationCollection().Add (shared_from_this()); 717 m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); 718 } 719} 720 721