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 { 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 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 372 uint32_t 373 BreakpointLocation::GetIgnoreCount () 374 { 375 return GetOptionsNoCreate()->GetIgnoreCount(); 376 } 377 378 void 379 BreakpointLocation::SetIgnoreCount (uint32_t n) 380 { 381 GetLocationOptions()->SetIgnoreCount(n); 382 SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged); 383 } 384 385 void 386 BreakpointLocation::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 396 bool 397 BreakpointLocation::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 413 const BreakpointOptions * 414 BreakpointLocation::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 422 BreakpointOptions * 423 BreakpointLocation::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 434 bool 435 BreakpointLocation::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 445 bool 446 BreakpointLocation::ShouldStop (StoppointCallbackContext *context) 447 { 448 bool should_stop = true; 449 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 450 451 IncrementHitCount(); 452 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 bool 477 BreakpointLocation::IsResolved () const 478 { 479 return m_bp_site_sp.get() != NULL; 480 } 481 482 lldb::BreakpointSiteSP 483 BreakpointLocation::GetBreakpointSite() const 484 { 485 return m_bp_site_sp; 486 } 487 488 bool 489 BreakpointLocation::ResolveBreakpointSite () 490 { 491 if (m_bp_site_sp) 492 return true; 493 494 Process *process = m_owner.GetTarget().GetProcessSP().get(); 495 if (process == NULL) 496 return false; 497 498 lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), m_owner.IsHardware()); 499 500 if (new_id == LLDB_INVALID_BREAK_ID) 501 { 502 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 503 if (log) 504 log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n", 505 m_address.GetOpcodeLoadAddress (&m_owner.GetTarget())); 506 return false; 507 } 508 509 return true; 510 } 511 512 bool 513 BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp) 514 { 515 m_bp_site_sp = bp_site_sp; 516 return true; 517 } 518 519 bool 520 BreakpointLocation::ClearBreakpointSite () 521 { 522 if (m_bp_site_sp.get()) 523 { 524 ProcessSP process_sp(m_owner.GetTarget().GetProcessSP()); 525 // If the process exists, get it to remove the owner, it will remove the physical implementation 526 // of the breakpoint as well if there are no more owners. Otherwise just remove this owner. 527 if (process_sp) 528 process_sp->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(), 529 GetID(), m_bp_site_sp); 530 else 531 m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID()); 532 533 m_bp_site_sp.reset(); 534 return true; 535 } 536 return false; 537 } 538 539 void 540 BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level) 541 { 542 SymbolContext sc; 543 544 // If the description level is "initial" then the breakpoint is printing out our initial state, 545 // and we should let it decide how it wants to print our label. 546 if (level != eDescriptionLevelInitial) 547 { 548 s->Indent(); 549 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID()); 550 } 551 552 if (level == lldb::eDescriptionLevelBrief) 553 return; 554 555 if (level != eDescriptionLevelInitial) 556 s->PutCString(": "); 557 558 if (level == lldb::eDescriptionLevelVerbose) 559 s->IndentMore(); 560 561 if (m_address.IsSectionOffset()) 562 { 563 m_address.CalculateSymbolContext(&sc); 564 565 if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial) 566 { 567 if (IsReExported()) 568 s->PutCString ("re-exported target = "); 569 else 570 s->PutCString("where = "); 571 sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false); 572 } 573 else 574 { 575 if (sc.module_sp) 576 { 577 s->EOL(); 578 s->Indent("module = "); 579 sc.module_sp->GetFileSpec().Dump (s); 580 } 581 582 if (sc.comp_unit != NULL) 583 { 584 s->EOL(); 585 s->Indent("compile unit = "); 586 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s); 587 588 if (sc.function != NULL) 589 { 590 s->EOL(); 591 s->Indent("function = "); 592 s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>")); 593 } 594 595 if (sc.line_entry.line > 0) 596 { 597 s->EOL(); 598 s->Indent("location = "); 599 sc.line_entry.DumpStopContext (s, true); 600 } 601 602 } 603 else 604 { 605 // If we don't have a comp unit, see if we have a symbol we can print. 606 if (sc.symbol) 607 { 608 s->EOL(); 609 if (IsReExported()) 610 s->Indent ("re-exported target = "); 611 else 612 s->Indent("symbol = "); 613 s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>")); 614 } 615 } 616 } 617 } 618 619 if (level == lldb::eDescriptionLevelVerbose) 620 { 621 s->EOL(); 622 s->Indent(); 623 } 624 625 if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)) 626 s->Printf (", "); 627 s->Printf ("address = "); 628 629 ExecutionContextScope *exe_scope = NULL; 630 Target *target = &m_owner.GetTarget(); 631 if (target) 632 exe_scope = target->GetProcessSP().get(); 633 if (exe_scope == NULL) 634 exe_scope = target; 635 636 if (level == eDescriptionLevelInitial) 637 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); 638 else 639 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress); 640 641 if (IsIndirect() && m_bp_site_sp) 642 { 643 Address resolved_address; 644 resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target); 645 Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol(); 646 if (resolved_symbol) 647 { 648 if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial) 649 s->Printf (", "); 650 else if (level == lldb::eDescriptionLevelVerbose) 651 { 652 s->EOL(); 653 s->Indent(); 654 } 655 s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString()); 656 } 657 } 658 659 if (level == lldb::eDescriptionLevelVerbose) 660 { 661 s->EOL(); 662 s->Indent(); 663 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false"); 664 665 s->Indent(); 666 s->Printf ("hit count = %-4u\n", GetHitCount()); 667 668 if (m_options_ap.get()) 669 { 670 s->Indent(); 671 m_options_ap->GetDescription (s, level); 672 s->EOL(); 673 } 674 s->IndentLess(); 675 } 676 else if (level != eDescriptionLevelInitial) 677 { 678 s->Printf(", %sresolved, hit count = %u ", 679 (IsResolved() ? "" : "un"), 680 GetHitCount()); 681 if (m_options_ap.get()) 682 { 683 m_options_ap->GetDescription (s, level); 684 } 685 } 686 } 687 688 void 689 BreakpointLocation::Dump(Stream *s) const 690 { 691 if (s == NULL) 692 return; 693 694 s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64 " load addr = 0x%8.8" PRIx64 " state = %s type = %s breakpoint " 695 "hw_index = %i hit_count = %-4u ignore_count = %-4u", 696 GetID(), 697 GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(), 698 (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()), 699 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled", 700 IsHardware() ? "hardware" : "software", 701 GetHardwareIndex(), 702 GetHitCount(), 703 GetOptionsNoCreate()->GetIgnoreCount()); 704 } 705 706 void 707 BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind) 708 { 709 if (!m_being_created 710 && !m_owner.IsInternal() 711 && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 712 { 713 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, 714 m_owner.shared_from_this()); 715 data->GetBreakpointLocationCollection().Add (shared_from_this()); 716 m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); 717 } 718 } 719 720