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