BreakpointLocation.cpp revision 263363
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) : 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 56BreakpointLocation::~BreakpointLocation() 57{ 58 ClearBreakpointSite(); 59} 60 61lldb::addr_t 62BreakpointLocation::GetLoadAddress () const 63{ 64 return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()); 65} 66 67Address & 68BreakpointLocation::GetAddress () 69{ 70 return m_address; 71} 72 73Breakpoint & 74BreakpointLocation::GetBreakpoint () 75{ 76 return m_owner; 77} 78 79bool 80BreakpointLocation::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 90void 91BreakpointLocation::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 105void 106BreakpointLocation::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 120lldb::tid_t 121BreakpointLocation::GetThreadID () 122{ 123 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 124 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(); 125 else 126 return LLDB_INVALID_THREAD_ID; 127} 128 129void 130BreakpointLocation::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 145uint32_t 146BreakpointLocation::GetThreadIndex() const 147{ 148 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 149 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex(); 150 else 151 return 0; 152} 153 154void 155BreakpointLocation::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 169const char * 170BreakpointLocation::GetThreadName () const 171{ 172 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 173 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName(); 174 else 175 return NULL; 176} 177 178void 179BreakpointLocation::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 193const char * 194BreakpointLocation::GetQueueName () const 195{ 196 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 197 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName(); 198 else 199 return NULL; 200} 201 202bool 203BreakpointLocation::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 211void 212BreakpointLocation::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 221void 222BreakpointLocation::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 230void 231BreakpointLocation::ClearCallback () 232{ 233 GetLocationOptions()->ClearCallback(); 234} 235 236void 237BreakpointLocation::SetCondition (const char *condition) 238{ 239 GetLocationOptions()->SetCondition (condition); 240 SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged); 241} 242 243const char * 244BreakpointLocation::GetConditionText (size_t *hash) const 245{ 246 return GetOptionsNoCreate()->GetConditionText(hash); 247} 248 249bool 250BreakpointLocation::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 295 EvaluateExpressionOptions options; 296 options.SetUnwindOnError(true); 297 options.SetIgnoreBreakpoints(true); 298 options.SetRunOthers(true); 299 300 Error expr_error; 301 302 StreamString execution_errors; 303 304 ClangExpressionVariableSP result_variable_sp; 305 306 ExecutionResults result_code = 307 m_user_expression_sp->Execute(execution_errors, 308 exe_ctx, 309 options, 310 m_user_expression_sp, 311 result_variable_sp); 312 313 bool ret; 314 315 if (result_code == eExecutionCompleted) 316 { 317 if (!result_variable_sp) 318 { 319 ret = false; 320 error.SetErrorString("Expression did not return a result"); 321 return false; 322 } 323 324 result_value_sp = result_variable_sp->GetValueObject(); 325 326 if (result_value_sp) 327 { 328 Scalar scalar_value; 329 if (result_value_sp->ResolveValue (scalar_value)) 330 { 331 if (scalar_value.ULongLong(1) == 0) 332 ret = false; 333 else 334 ret = true; 335 if (log) 336 log->Printf("Condition successfully evaluated, result is %s.\n", 337 ret ? "true" : "false"); 338 } 339 else 340 { 341 ret = false; 342 error.SetErrorString("Failed to get an integer result from the expression"); 343 } 344 } 345 else 346 { 347 ret = false; 348 error.SetErrorString("Failed to get any result from the expression"); 349 } 350 } 351 else 352 { 353 ret = false; 354 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData()); 355 } 356 357 return ret; 358} 359 360uint32_t 361BreakpointLocation::GetIgnoreCount () 362{ 363 return GetOptionsNoCreate()->GetIgnoreCount(); 364} 365 366void 367BreakpointLocation::SetIgnoreCount (uint32_t n) 368{ 369 GetLocationOptions()->SetIgnoreCount(n); 370 SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged); 371} 372 373void 374BreakpointLocation::DecrementIgnoreCount() 375{ 376 if (m_options_ap.get() != NULL) 377 { 378 uint32_t loc_ignore = m_options_ap->GetIgnoreCount(); 379 if (loc_ignore != 0) 380 m_options_ap->SetIgnoreCount(loc_ignore - 1); 381 } 382} 383 384bool 385BreakpointLocation::IgnoreCountShouldStop() 386{ 387 if (m_options_ap.get() != NULL) 388 { 389 uint32_t loc_ignore = m_options_ap->GetIgnoreCount(); 390 if (loc_ignore != 0) 391 { 392 m_owner.DecrementIgnoreCount(); 393 DecrementIgnoreCount(); // Have to decrement our owners' ignore count, since it won't get a 394 // chance to. 395 return false; 396 } 397 } 398 return true; 399} 400 401const BreakpointOptions * 402BreakpointLocation::GetOptionsNoCreate () const 403{ 404 if (m_options_ap.get() != NULL) 405 return m_options_ap.get(); 406 else 407 return m_owner.GetOptions (); 408} 409 410BreakpointOptions * 411BreakpointLocation::GetLocationOptions () 412{ 413 // If we make the copy we don't copy the callbacks because that is potentially 414 // expensive and we don't want to do that for the simple case where someone is 415 // just disabling the location. 416 if (m_options_ap.get() == NULL) 417 m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ())); 418 419 return m_options_ap.get(); 420} 421 422bool 423BreakpointLocation::ValidForThisThread (Thread *thread) 424{ 425 return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate()); 426} 427 428// RETURNS - true if we should stop at this breakpoint, false if we 429// should continue. Note, we don't check the thread spec for the breakpoint 430// here, since if the breakpoint is not for this thread, then the event won't 431// even get reported, so the check is redundant. 432 433bool 434BreakpointLocation::ShouldStop (StoppointCallbackContext *context) 435{ 436 bool should_stop = true; 437 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 438 439 IncrementHitCount(); 440 441 if (!IsEnabled()) 442 return false; 443 444 if (!IgnoreCountShouldStop()) 445 return false; 446 447 if (!m_owner.IgnoreCountShouldStop()) 448 return false; 449 450 // We only run synchronous callbacks in ShouldStop: 451 context->is_synchronous = true; 452 should_stop = InvokeCallback (context); 453 454 if (log) 455 { 456 StreamString s; 457 GetDescription (&s, lldb::eDescriptionLevelVerbose); 458 log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing"); 459 } 460 461 return should_stop; 462} 463 464bool 465BreakpointLocation::IsResolved () const 466{ 467 return m_bp_site_sp.get() != NULL; 468} 469 470lldb::BreakpointSiteSP 471BreakpointLocation::GetBreakpointSite() const 472{ 473 return m_bp_site_sp; 474} 475 476bool 477BreakpointLocation::ResolveBreakpointSite () 478{ 479 if (m_bp_site_sp) 480 return true; 481 482 Process *process = m_owner.GetTarget().GetProcessSP().get(); 483 if (process == NULL) 484 return false; 485 486 lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), m_owner.IsHardware()); 487 488 if (new_id == LLDB_INVALID_BREAK_ID) 489 { 490 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 491 if (log) 492 log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n", 493 m_address.GetOpcodeLoadAddress (&m_owner.GetTarget())); 494 return false; 495 } 496 497 return true; 498} 499 500bool 501BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp) 502{ 503 m_bp_site_sp = bp_site_sp; 504 return true; 505} 506 507bool 508BreakpointLocation::ClearBreakpointSite () 509{ 510 if (m_bp_site_sp.get()) 511 { 512 m_owner.GetTarget().GetProcessSP()->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(), 513 GetID(), m_bp_site_sp); 514 m_bp_site_sp.reset(); 515 return true; 516 } 517 return false; 518} 519 520void 521BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level) 522{ 523 SymbolContext sc; 524 525 // If the description level is "initial" then the breakpoint is printing out our initial state, 526 // and we should let it decide how it wants to print our label. 527 if (level != eDescriptionLevelInitial) 528 { 529 s->Indent(); 530 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID()); 531 } 532 533 if (level == lldb::eDescriptionLevelBrief) 534 return; 535 536 if (level != eDescriptionLevelInitial) 537 s->PutCString(": "); 538 539 if (level == lldb::eDescriptionLevelVerbose) 540 s->IndentMore(); 541 542 if (m_address.IsSectionOffset()) 543 { 544 m_address.CalculateSymbolContext(&sc); 545 546 if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial) 547 { 548 s->PutCString("where = "); 549 sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false); 550 } 551 else 552 { 553 if (sc.module_sp) 554 { 555 s->EOL(); 556 s->Indent("module = "); 557 sc.module_sp->GetFileSpec().Dump (s); 558 } 559 560 if (sc.comp_unit != NULL) 561 { 562 s->EOL(); 563 s->Indent("compile unit = "); 564 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s); 565 566 if (sc.function != NULL) 567 { 568 s->EOL(); 569 s->Indent("function = "); 570 s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>")); 571 } 572 573 if (sc.line_entry.line > 0) 574 { 575 s->EOL(); 576 s->Indent("location = "); 577 sc.line_entry.DumpStopContext (s, true); 578 } 579 580 } 581 else 582 { 583 // If we don't have a comp unit, see if we have a symbol we can print. 584 if (sc.symbol) 585 { 586 s->EOL(); 587 s->Indent("symbol = "); 588 s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>")); 589 } 590 } 591 } 592 } 593 594 if (level == lldb::eDescriptionLevelVerbose) 595 { 596 s->EOL(); 597 s->Indent(); 598 } 599 600 if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)) 601 s->Printf (", "); 602 s->Printf ("address = "); 603 604 ExecutionContextScope *exe_scope = NULL; 605 Target *target = &m_owner.GetTarget(); 606 if (target) 607 exe_scope = target->GetProcessSP().get(); 608 if (exe_scope == NULL) 609 exe_scope = target; 610 611 if (eDescriptionLevelInitial) 612 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); 613 else 614 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress); 615 616 if (level == lldb::eDescriptionLevelVerbose) 617 { 618 s->EOL(); 619 s->Indent(); 620 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false"); 621 622 s->Indent(); 623 s->Printf ("hit count = %-4u\n", GetHitCount()); 624 625 if (m_options_ap.get()) 626 { 627 s->Indent(); 628 m_options_ap->GetDescription (s, level); 629 s->EOL(); 630 } 631 s->IndentLess(); 632 } 633 else if (level != eDescriptionLevelInitial) 634 { 635 s->Printf(", %sresolved, hit count = %u ", 636 (IsResolved() ? "" : "un"), 637 GetHitCount()); 638 if (m_options_ap.get()) 639 { 640 m_options_ap->GetDescription (s, level); 641 } 642 } 643} 644 645void 646BreakpointLocation::Dump(Stream *s) const 647{ 648 if (s == NULL) 649 return; 650 651 s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64 " load addr = 0x%8.8" PRIx64 " state = %s type = %s breakpoint " 652 "hw_index = %i hit_count = %-4u ignore_count = %-4u", 653 GetID(), 654 GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(), 655 (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()), 656 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled", 657 IsHardware() ? "hardware" : "software", 658 GetHardwareIndex(), 659 GetHitCount(), 660 GetOptionsNoCreate()->GetIgnoreCount()); 661} 662 663void 664BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind) 665{ 666 if (!m_being_created 667 && !m_owner.IsInternal() 668 && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 669 { 670 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, 671 m_owner.shared_from_this()); 672 data->GetBreakpointLocationCollection().Add (shared_from_this()); 673 m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); 674 } 675} 676 677