BreakpointLocation.cpp revision 5bdfd665ca98f040f3e68ab052f6e192b23dcc3a
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{ 51 SetThreadID (tid); 52 m_being_created = false; 53} 54 55BreakpointLocation::~BreakpointLocation() 56{ 57 ClearBreakpointSite(); 58} 59 60lldb::addr_t 61BreakpointLocation::GetLoadAddress () const 62{ 63 return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()); 64} 65 66Address & 67BreakpointLocation::GetAddress () 68{ 69 return m_address; 70} 71 72Breakpoint & 73BreakpointLocation::GetBreakpoint () 74{ 75 return m_owner; 76} 77 78bool 79BreakpointLocation::IsEnabled () const 80{ 81 if (!m_owner.IsEnabled()) 82 return false; 83 else if (m_options_ap.get() != NULL) 84 return m_options_ap->IsEnabled(); 85 else 86 return true; 87} 88 89void 90BreakpointLocation::SetEnabled (bool enabled) 91{ 92 GetLocationOptions()->SetEnabled(enabled); 93 if (enabled) 94 { 95 ResolveBreakpointSite(); 96 } 97 else 98 { 99 ClearBreakpointSite(); 100 } 101 SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled); 102} 103 104void 105BreakpointLocation::SetThreadID (lldb::tid_t thread_id) 106{ 107 if (thread_id != LLDB_INVALID_THREAD_ID) 108 GetLocationOptions()->SetThreadID(thread_id); 109 else 110 { 111 // If we're resetting this to an invalid thread id, then 112 // don't make an options pointer just to do that. 113 if (m_options_ap.get() != NULL) 114 m_options_ap->SetThreadID (thread_id); 115 } 116 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); 117} 118 119lldb::tid_t 120BreakpointLocation::GetThreadID () 121{ 122 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 123 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(); 124 else 125 return LLDB_INVALID_THREAD_ID; 126} 127 128void 129BreakpointLocation::SetThreadIndex (uint32_t index) 130{ 131 if (index != 0) 132 GetLocationOptions()->GetThreadSpec()->SetIndex(index); 133 else 134 { 135 // If we're resetting this to an invalid thread id, then 136 // don't make an options pointer just to do that. 137 if (m_options_ap.get() != NULL) 138 m_options_ap->GetThreadSpec()->SetIndex(index); 139 } 140 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); 141 142} 143 144uint32_t 145BreakpointLocation::GetThreadIndex() const 146{ 147 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 148 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex(); 149 else 150 return 0; 151} 152 153void 154BreakpointLocation::SetThreadName (const char *thread_name) 155{ 156 if (thread_name != NULL) 157 GetLocationOptions()->GetThreadSpec()->SetName(thread_name); 158 else 159 { 160 // If we're resetting this to an invalid thread id, then 161 // don't make an options pointer just to do that. 162 if (m_options_ap.get() != NULL) 163 m_options_ap->GetThreadSpec()->SetName(thread_name); 164 } 165 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); 166} 167 168const char * 169BreakpointLocation::GetThreadName () const 170{ 171 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 172 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName(); 173 else 174 return NULL; 175} 176 177void 178BreakpointLocation::SetQueueName (const char *queue_name) 179{ 180 if (queue_name != NULL) 181 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name); 182 else 183 { 184 // If we're resetting this to an invalid thread id, then 185 // don't make an options pointer just to do that. 186 if (m_options_ap.get() != NULL) 187 m_options_ap->GetThreadSpec()->SetQueueName(queue_name); 188 } 189 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged); 190} 191 192const char * 193BreakpointLocation::GetQueueName () const 194{ 195 if (GetOptionsNoCreate()->GetThreadSpecNoCreate()) 196 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName(); 197 else 198 return NULL; 199} 200 201bool 202BreakpointLocation::InvokeCallback (StoppointCallbackContext *context) 203{ 204 if (m_options_ap.get() != NULL && m_options_ap->HasCallback()) 205 return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID()); 206 else 207 return m_owner.InvokeCallback (context, GetID()); 208} 209 210void 211BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton, 212 bool is_synchronous) 213{ 214 // The default "Baton" class will keep a copy of "baton" and won't free 215 // or delete it when it goes goes out of scope. 216 GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous); 217 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged); 218} 219 220void 221BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp, 222 bool is_synchronous) 223{ 224 GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous); 225 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged); 226} 227 228 229void 230BreakpointLocation::ClearCallback () 231{ 232 GetLocationOptions()->ClearCallback(); 233} 234 235void 236BreakpointLocation::SetCondition (const char *condition) 237{ 238 GetLocationOptions()->SetCondition (condition); 239 SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged); 240} 241 242const char * 243BreakpointLocation::GetConditionText (size_t *hash) const 244{ 245 return GetOptionsNoCreate()->GetConditionText(hash); 246} 247 248bool 249BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error) 250{ 251 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 252 253 size_t condition_hash; 254 const char *condition_text = GetConditionText(&condition_hash); 255 256 if (!condition_text) 257 { 258 m_user_expression_sp.reset(); 259 return false; 260 } 261 262 if (condition_hash != m_condition_hash || 263 !m_user_expression_sp || 264 !m_user_expression_sp->MatchesContext(exe_ctx)) 265 { 266 m_user_expression_sp.reset(new ClangUserExpression(condition_text, 267 NULL, 268 lldb::eLanguageTypeUnknown, 269 ClangUserExpression::eResultTypeAny)); 270 271 StreamString errors; 272 273 if (!m_user_expression_sp->Parse(errors, 274 exe_ctx, 275 eExecutionPolicyOnlyWhenNeeded, 276 true)) 277 { 278 error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s", 279 errors.GetData()); 280 m_user_expression_sp.reset(); 281 return false; 282 } 283 284 m_condition_hash = condition_hash; 285 } 286 287 // We need to make sure the user sees any parse errors in their condition, so we'll hook the 288 // constructor errors up to the debugger's Async I/O. 289 290 ValueObjectSP result_value_sp; 291 const bool unwind_on_error = true; 292 const bool ignore_breakpoints = true; 293 const bool try_all_threads = true; 294 295 Error expr_error; 296 297 StreamString execution_errors; 298 299 ClangExpressionVariableSP result_variable_sp; 300 301 ExecutionResults result_code = 302 m_user_expression_sp->Execute(execution_errors, 303 exe_ctx, 304 unwind_on_error, 305 ignore_breakpoints, 306 m_user_expression_sp, 307 result_variable_sp, 308 try_all_threads, 309 ClangUserExpression::kDefaultTimeout); 310 311 bool ret; 312 313 if (result_code == eExecutionCompleted) 314 { 315 if (!result_variable_sp) 316 { 317 ret = false; 318 error.SetErrorString("Expression did not return a result"); 319 } 320 321 result_value_sp = result_variable_sp->GetValueObject(); 322 323 if (result_value_sp) 324 { 325 Scalar scalar_value; 326 if (result_value_sp->ResolveValue (scalar_value)) 327 { 328 if (scalar_value.ULongLong(1) == 0) 329 ret = false; 330 else 331 ret = true; 332 if (log) 333 log->Printf("Condition successfully evaluated, result is %s.\n", 334 ret ? "true" : "false"); 335 } 336 else 337 { 338 ret = false; 339 error.SetErrorString("Failed to get an integer result from the expression"); 340 } 341 } 342 else 343 { 344 ret = false; 345 error.SetErrorString("Failed to get any result from the expression"); 346 } 347 } 348 else 349 { 350 ret = false; 351 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData()); 352 } 353 354 return ret; 355} 356 357uint32_t 358BreakpointLocation::GetIgnoreCount () 359{ 360 return GetOptionsNoCreate()->GetIgnoreCount(); 361} 362 363void 364BreakpointLocation::SetIgnoreCount (uint32_t n) 365{ 366 GetLocationOptions()->SetIgnoreCount(n); 367 SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged); 368} 369 370void 371BreakpointLocation::DecrementIgnoreCount() 372{ 373 if (m_options_ap.get() != NULL) 374 { 375 uint32_t loc_ignore = m_options_ap->GetIgnoreCount(); 376 if (loc_ignore != 0) 377 m_options_ap->SetIgnoreCount(loc_ignore - 1); 378 } 379} 380 381bool 382BreakpointLocation::IgnoreCountShouldStop() 383{ 384 if (m_options_ap.get() != NULL) 385 { 386 uint32_t loc_ignore = m_options_ap->GetIgnoreCount(); 387 if (loc_ignore != 0) 388 { 389 m_owner.DecrementIgnoreCount(); 390 DecrementIgnoreCount(); // Have to decrement our owners' ignore count, since it won't get a 391 // chance to. 392 return false; 393 } 394 } 395 return true; 396} 397 398const BreakpointOptions * 399BreakpointLocation::GetOptionsNoCreate () const 400{ 401 if (m_options_ap.get() != NULL) 402 return m_options_ap.get(); 403 else 404 return m_owner.GetOptions (); 405} 406 407BreakpointOptions * 408BreakpointLocation::GetLocationOptions () 409{ 410 // If we make the copy we don't copy the callbacks because that is potentially 411 // expensive and we don't want to do that for the simple case where someone is 412 // just disabling the location. 413 if (m_options_ap.get() == NULL) 414 m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ())); 415 416 return m_options_ap.get(); 417} 418 419bool 420BreakpointLocation::ValidForThisThread (Thread *thread) 421{ 422 return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate()); 423} 424 425// RETURNS - true if we should stop at this breakpoint, false if we 426// should continue. Note, we don't check the thread spec for the breakpoint 427// here, since if the breakpoint is not for this thread, then the event won't 428// even get reported, so the check is redundant. 429 430bool 431BreakpointLocation::ShouldStop (StoppointCallbackContext *context) 432{ 433 bool should_stop = true; 434 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); 435 436 IncrementHitCount(); 437 438 if (!IsEnabled()) 439 return false; 440 441 if (!IgnoreCountShouldStop()) 442 return false; 443 444 if (!m_owner.IgnoreCountShouldStop()) 445 return false; 446 447 // We only run synchronous callbacks in ShouldStop: 448 context->is_synchronous = true; 449 should_stop = InvokeCallback (context); 450 451 if (log) 452 { 453 StreamString s; 454 GetDescription (&s, lldb::eDescriptionLevelVerbose); 455 log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing"); 456 } 457 458 return should_stop; 459} 460 461bool 462BreakpointLocation::IsResolved () const 463{ 464 return m_bp_site_sp.get() != NULL; 465} 466 467lldb::BreakpointSiteSP 468BreakpointLocation::GetBreakpointSite() const 469{ 470 return m_bp_site_sp; 471} 472 473bool 474BreakpointLocation::ResolveBreakpointSite () 475{ 476 if (m_bp_site_sp) 477 return true; 478 479 Process *process = m_owner.GetTarget().GetProcessSP().get(); 480 if (process == NULL) 481 return false; 482 483 if (m_owner.GetTarget().GetSectionLoadList().IsEmpty()) 484 return false; 485 486 lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), false); 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