BreakpointLocation.cpp revision 269024
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 { 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 ExecutionResults 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 == eExecutionCompleted) 329 { 330 if (!result_variable_sp) 331 { 332 ret = false; 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 m_owner.GetTarget().GetProcessSP()->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(), 526 GetID(), m_bp_site_sp); 527 m_bp_site_sp.reset(); 528 return true; 529 } 530 return false; 531} 532 533void 534BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level) 535{ 536 SymbolContext sc; 537 538 // If the description level is "initial" then the breakpoint is printing out our initial state, 539 // and we should let it decide how it wants to print our label. 540 if (level != eDescriptionLevelInitial) 541 { 542 s->Indent(); 543 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID()); 544 } 545 546 if (level == lldb::eDescriptionLevelBrief) 547 return; 548 549 if (level != eDescriptionLevelInitial) 550 s->PutCString(": "); 551 552 if (level == lldb::eDescriptionLevelVerbose) 553 s->IndentMore(); 554 555 if (m_address.IsSectionOffset()) 556 { 557 m_address.CalculateSymbolContext(&sc); 558 559 if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial) 560 { 561 if (IsReExported()) 562 s->PutCString ("re-exported target = "); 563 else 564 s->PutCString("where = "); 565 sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false); 566 } 567 else 568 { 569 if (sc.module_sp) 570 { 571 s->EOL(); 572 s->Indent("module = "); 573 sc.module_sp->GetFileSpec().Dump (s); 574 } 575 576 if (sc.comp_unit != NULL) 577 { 578 s->EOL(); 579 s->Indent("compile unit = "); 580 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s); 581 582 if (sc.function != NULL) 583 { 584 s->EOL(); 585 s->Indent("function = "); 586 s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>")); 587 } 588 589 if (sc.line_entry.line > 0) 590 { 591 s->EOL(); 592 s->Indent("location = "); 593 sc.line_entry.DumpStopContext (s, true); 594 } 595 596 } 597 else 598 { 599 // If we don't have a comp unit, see if we have a symbol we can print. 600 if (sc.symbol) 601 { 602 s->EOL(); 603 if (IsReExported()) 604 s->Indent ("re-exported target = "); 605 else 606 s->Indent("symbol = "); 607 s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>")); 608 } 609 } 610 } 611 } 612 613 if (level == lldb::eDescriptionLevelVerbose) 614 { 615 s->EOL(); 616 s->Indent(); 617 } 618 619 if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)) 620 s->Printf (", "); 621 s->Printf ("address = "); 622 623 ExecutionContextScope *exe_scope = NULL; 624 Target *target = &m_owner.GetTarget(); 625 if (target) 626 exe_scope = target->GetProcessSP().get(); 627 if (exe_scope == NULL) 628 exe_scope = target; 629 630 if (eDescriptionLevelInitial) 631 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); 632 else 633 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress); 634 635 if (IsIndirect() && m_bp_site_sp) 636 { 637 Address resolved_address; 638 resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target); 639 Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol(); 640 if (resolved_symbol) 641 { 642 if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial) 643 s->Printf (", "); 644 else if (level == lldb::eDescriptionLevelVerbose) 645 { 646 s->EOL(); 647 s->Indent(); 648 } 649 s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString()); 650 } 651 } 652 653 if (level == lldb::eDescriptionLevelVerbose) 654 { 655 s->EOL(); 656 s->Indent(); 657 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false"); 658 659 s->Indent(); 660 s->Printf ("hit count = %-4u\n", GetHitCount()); 661 662 if (m_options_ap.get()) 663 { 664 s->Indent(); 665 m_options_ap->GetDescription (s, level); 666 s->EOL(); 667 } 668 s->IndentLess(); 669 } 670 else if (level != eDescriptionLevelInitial) 671 { 672 s->Printf(", %sresolved, hit count = %u ", 673 (IsResolved() ? "" : "un"), 674 GetHitCount()); 675 if (m_options_ap.get()) 676 { 677 m_options_ap->GetDescription (s, level); 678 } 679 } 680} 681 682void 683BreakpointLocation::Dump(Stream *s) const 684{ 685 if (s == NULL) 686 return; 687 688 s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64 " load addr = 0x%8.8" PRIx64 " state = %s type = %s breakpoint " 689 "hw_index = %i hit_count = %-4u ignore_count = %-4u", 690 GetID(), 691 GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(), 692 (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()), 693 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled", 694 IsHardware() ? "hardware" : "software", 695 GetHardwareIndex(), 696 GetHitCount(), 697 GetOptionsNoCreate()->GetIgnoreCount()); 698} 699 700void 701BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind) 702{ 703 if (!m_being_created 704 && !m_owner.IsInternal() 705 && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 706 { 707 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, 708 m_owner.shared_from_this()); 709 data->GetBreakpointLocationCollection().Add (shared_from_this()); 710 m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); 711 } 712} 713 714