1 //===-- Breakpoint.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 11 // C Includes 12 // C++ Includes 13 // Other libraries and framework includes 14 // Project includes 15 16 #include "lldb/Core/Address.h" 17 #include "lldb/Breakpoint/Breakpoint.h" 18 #include "lldb/Breakpoint/BreakpointLocation.h" 19 #include "lldb/Breakpoint/BreakpointLocationCollection.h" 20 #include "lldb/Breakpoint/BreakpointResolver.h" 21 #include "lldb/Breakpoint/BreakpointResolverFileLine.h" 22 #include "lldb/Core/Log.h" 23 #include "lldb/Core/ModuleList.h" 24 #include "lldb/Core/SearchFilter.h" 25 #include "lldb/Core/Section.h" 26 #include "lldb/Core/Stream.h" 27 #include "lldb/Core/StreamString.h" 28 #include "lldb/Symbol/SymbolContext.h" 29 #include "lldb/Target/Target.h" 30 #include "lldb/Target/ThreadSpec.h" 31 #include "lldb/lldb-private-log.h" 32 #include "llvm/Support/Casting.h" 33 34 using namespace lldb; 35 using namespace lldb_private; 36 using namespace llvm; 37 38 const ConstString & 39 Breakpoint::GetEventIdentifier () 40 { 41 static ConstString g_identifier("event-identifier.breakpoint.changed"); 42 return g_identifier; 43 } 44 45 //---------------------------------------------------------------------- 46 // Breakpoint constructor 47 //---------------------------------------------------------------------- 48 Breakpoint::Breakpoint(Target &target, SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp) : 49 m_being_created(true), 50 m_target (target), 51 m_filter_sp (filter_sp), 52 m_resolver_sp (resolver_sp), 53 m_options (), 54 m_locations (*this) 55 { 56 m_being_created = false; 57 } 58 59 //---------------------------------------------------------------------- 60 // Destructor 61 //---------------------------------------------------------------------- 62 Breakpoint::~Breakpoint() 63 { 64 } 65 66 bool 67 Breakpoint::IsInternal () const 68 { 69 return LLDB_BREAK_ID_IS_INTERNAL(m_bid); 70 } 71 72 73 74 Target& 75 Breakpoint::GetTarget () 76 { 77 return m_target; 78 } 79 80 const Target& 81 Breakpoint::GetTarget () const 82 { 83 return m_target; 84 } 85 86 BreakpointLocationSP 87 Breakpoint::AddLocation (const Address &addr, bool *new_location) 88 { 89 return m_locations.AddLocation (addr, new_location); 90 } 91 92 BreakpointLocationSP 93 Breakpoint::FindLocationByAddress (const Address &addr) 94 { 95 return m_locations.FindByAddress(addr); 96 } 97 98 break_id_t 99 Breakpoint::FindLocationIDByAddress (const Address &addr) 100 { 101 return m_locations.FindIDByAddress(addr); 102 } 103 104 BreakpointLocationSP 105 Breakpoint::FindLocationByID (break_id_t bp_loc_id) 106 { 107 return m_locations.FindByID(bp_loc_id); 108 } 109 110 BreakpointLocationSP 111 Breakpoint::GetLocationAtIndex (uint32_t index) 112 { 113 return m_locations.GetByIndex(index); 114 } 115 116 // For each of the overall options we need to decide how they propagate to 117 // the location options. This will determine the precedence of options on 118 // the breakpoint vs. its locations. 119 120 // Disable at the breakpoint level should override the location settings. 121 // That way you can conveniently turn off a whole breakpoint without messing 122 // up the individual settings. 123 124 void 125 Breakpoint::SetEnabled (bool enable) 126 { 127 if (enable == m_options.IsEnabled()) 128 return; 129 130 m_options.SetEnabled(enable); 131 if (enable) 132 m_locations.ResolveAllBreakpointSites(); 133 else 134 m_locations.ClearAllBreakpointSites(); 135 136 SendBreakpointChangedEvent (enable ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled); 137 138 } 139 140 bool 141 Breakpoint::IsEnabled () 142 { 143 return m_options.IsEnabled(); 144 } 145 146 void 147 Breakpoint::SetIgnoreCount (uint32_t n) 148 { 149 if (m_options.GetIgnoreCount() == n) 150 return; 151 152 m_options.SetIgnoreCount(n); 153 SendBreakpointChangedEvent (eBreakpointEventTypeIgnoreChanged); 154 } 155 156 void 157 Breakpoint::DecrementIgnoreCount () 158 { 159 uint32_t ignore = m_options.GetIgnoreCount(); 160 if (ignore != 0) 161 m_options.SetIgnoreCount(ignore - 1); 162 } 163 164 uint32_t 165 Breakpoint::GetIgnoreCount () const 166 { 167 return m_options.GetIgnoreCount(); 168 } 169 170 bool 171 Breakpoint::IgnoreCountShouldStop () 172 { 173 uint32_t ignore = GetIgnoreCount(); 174 if (ignore != 0) 175 { 176 // When we get here we know the location that caused the stop doesn't have an ignore count, 177 // since by contract we call it first... So we don't have to find & decrement it, we only have 178 // to decrement our own ignore count. 179 DecrementIgnoreCount(); 180 return false; 181 } 182 else 183 return true; 184 } 185 186 uint32_t 187 Breakpoint::GetHitCount () const 188 { 189 return m_locations.GetHitCount(); 190 } 191 192 void 193 Breakpoint::SetThreadID (lldb::tid_t thread_id) 194 { 195 if (m_options.GetThreadSpec()->GetTID() == thread_id) 196 return; 197 198 m_options.GetThreadSpec()->SetTID(thread_id); 199 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged); 200 } 201 202 lldb::tid_t 203 Breakpoint::GetThreadID () const 204 { 205 if (m_options.GetThreadSpecNoCreate() == NULL) 206 return LLDB_INVALID_THREAD_ID; 207 else 208 return m_options.GetThreadSpecNoCreate()->GetTID(); 209 } 210 211 void 212 Breakpoint::SetThreadIndex (uint32_t index) 213 { 214 if (m_options.GetThreadSpec()->GetIndex() == index) 215 return; 216 217 m_options.GetThreadSpec()->SetIndex(index); 218 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged); 219 } 220 221 uint32_t 222 Breakpoint::GetThreadIndex() const 223 { 224 if (m_options.GetThreadSpecNoCreate() == NULL) 225 return 0; 226 else 227 return m_options.GetThreadSpecNoCreate()->GetIndex(); 228 } 229 230 void 231 Breakpoint::SetThreadName (const char *thread_name) 232 { 233 if (::strcmp (m_options.GetThreadSpec()->GetName(), thread_name) == 0) 234 return; 235 236 m_options.GetThreadSpec()->SetName (thread_name); 237 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged); 238 } 239 240 const char * 241 Breakpoint::GetThreadName () const 242 { 243 if (m_options.GetThreadSpecNoCreate() == NULL) 244 return NULL; 245 else 246 return m_options.GetThreadSpecNoCreate()->GetName(); 247 } 248 249 void 250 Breakpoint::SetQueueName (const char *queue_name) 251 { 252 if (::strcmp (m_options.GetThreadSpec()->GetQueueName(), queue_name) == 0) 253 return; 254 255 m_options.GetThreadSpec()->SetQueueName (queue_name); 256 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged); 257 } 258 259 const char * 260 Breakpoint::GetQueueName () const 261 { 262 if (m_options.GetThreadSpecNoCreate() == NULL) 263 return NULL; 264 else 265 return m_options.GetThreadSpecNoCreate()->GetQueueName(); 266 } 267 268 void 269 Breakpoint::SetCondition (const char *condition) 270 { 271 m_options.SetCondition (condition); 272 SendBreakpointChangedEvent (eBreakpointEventTypeConditionChanged); 273 } 274 275 const char * 276 Breakpoint::GetConditionText () const 277 { 278 return m_options.GetConditionText(); 279 } 280 281 // This function is used when "baton" doesn't need to be freed 282 void 283 Breakpoint::SetCallback (BreakpointHitCallback callback, void *baton, bool is_synchronous) 284 { 285 // The default "Baton" class will keep a copy of "baton" and won't free 286 // or delete it when it goes goes out of scope. 287 m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous); 288 289 SendBreakpointChangedEvent (eBreakpointEventTypeCommandChanged); 290 } 291 292 // This function is used when a baton needs to be freed and therefore is 293 // contained in a "Baton" subclass. 294 void 295 Breakpoint::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous) 296 { 297 m_options.SetCallback(callback, callback_baton_sp, is_synchronous); 298 } 299 300 void 301 Breakpoint::ClearCallback () 302 { 303 m_options.ClearCallback (); 304 } 305 306 bool 307 Breakpoint::InvokeCallback (StoppointCallbackContext *context, break_id_t bp_loc_id) 308 { 309 return m_options.InvokeCallback (context, GetID(), bp_loc_id); 310 } 311 312 BreakpointOptions * 313 Breakpoint::GetOptions () 314 { 315 return &m_options; 316 } 317 318 void 319 Breakpoint::ResolveBreakpoint () 320 { 321 if (m_resolver_sp) 322 m_resolver_sp->ResolveBreakpoint(*m_filter_sp); 323 } 324 325 void 326 Breakpoint::ResolveBreakpointInModules (ModuleList &module_list) 327 { 328 if (m_resolver_sp) 329 m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list); 330 } 331 332 void 333 Breakpoint::ClearAllBreakpointSites () 334 { 335 m_locations.ClearAllBreakpointSites(); 336 } 337 338 //---------------------------------------------------------------------- 339 // ModulesChanged: Pass in a list of new modules, and 340 //---------------------------------------------------------------------- 341 342 void 343 Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_locations) 344 { 345 Mutex::Locker modules_mutex(module_list.GetMutex()); 346 if (load) 347 { 348 // The logic for handling new modules is: 349 // 1) If the filter rejects this module, then skip it. 350 // 2) Run through the current location list and if there are any locations 351 // for that module, we mark the module as "seen" and we don't try to re-resolve 352 // breakpoint locations for that module. 353 // However, we do add breakpoint sites to these locations if needed. 354 // 3) If we don't see this module in our breakpoint location list, call ResolveInModules. 355 356 ModuleList new_modules; // We'll stuff the "unseen" modules in this list, and then resolve 357 // them after the locations pass. Have to do it this way because 358 // resolving breakpoints will add new locations potentially. 359 360 const size_t num_locs = m_locations.GetSize(); 361 size_t num_modules = module_list.GetSize(); 362 for (size_t i = 0; i < num_modules; i++) 363 { 364 bool seen = false; 365 ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i)); 366 if (!m_filter_sp->ModulePasses (module_sp)) 367 continue; 368 369 for (size_t loc_idx = 0; loc_idx < num_locs; loc_idx++) 370 { 371 BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx); 372 if (!break_loc->IsEnabled()) 373 continue; 374 SectionSP section_sp (break_loc->GetAddress().GetSection()); 375 if (!section_sp || section_sp->GetModule() == module_sp) 376 { 377 if (!seen) 378 seen = true; 379 380 if (!break_loc->ResolveBreakpointSite()) 381 { 382 LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 383 if (log) 384 log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n", 385 break_loc->GetID(), GetID()); 386 } 387 } 388 } 389 390 if (!seen) 391 new_modules.AppendIfNeeded (module_sp); 392 393 } 394 395 if (new_modules.GetSize() > 0) 396 { 397 // If this is not an internal breakpoint, set up to record the new locations, then dispatch 398 // an event with the new locations. 399 if (!IsInternal()) 400 { 401 BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded, 402 shared_from_this()); 403 404 m_locations.StartRecordingNewLocations(new_locations_event->GetBreakpointLocationCollection()); 405 406 ResolveBreakpointInModules(new_modules); 407 408 m_locations.StopRecordingNewLocations(); 409 if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0) 410 { 411 SendBreakpointChangedEvent (new_locations_event); 412 } 413 else 414 delete new_locations_event; 415 } 416 else 417 ResolveBreakpointInModules(new_modules); 418 419 } 420 } 421 else 422 { 423 // Go through the currently set locations and if any have breakpoints in 424 // the module list, then remove their breakpoint sites, and their locations if asked to. 425 426 BreakpointEventData *removed_locations_event; 427 if (!IsInternal()) 428 removed_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved, 429 shared_from_this()); 430 else 431 removed_locations_event = NULL; 432 433 size_t num_modules = module_list.GetSize(); 434 for (size_t i = 0; i < num_modules; i++) 435 { 436 ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i)); 437 if (m_filter_sp->ModulePasses (module_sp)) 438 { 439 size_t loc_idx = 0; 440 size_t num_locations = m_locations.GetSize(); 441 BreakpointLocationCollection locations_to_remove; 442 for (loc_idx = 0; loc_idx < num_locations; loc_idx++) 443 { 444 BreakpointLocationSP break_loc_sp (m_locations.GetByIndex(loc_idx)); 445 SectionSP section_sp (break_loc_sp->GetAddress().GetSection()); 446 if (section_sp && section_sp->GetModule() == module_sp) 447 { 448 // Remove this breakpoint since the shared library is 449 // unloaded, but keep the breakpoint location around 450 // so we always get complete hit count and breakpoint 451 // lifetime info 452 break_loc_sp->ClearBreakpointSite(); 453 if (removed_locations_event) 454 { 455 removed_locations_event->GetBreakpointLocationCollection().Add(break_loc_sp); 456 } 457 if (delete_locations) 458 locations_to_remove.Add (break_loc_sp); 459 460 } 461 } 462 463 if (delete_locations) 464 { 465 size_t num_locations_to_remove = locations_to_remove.GetSize(); 466 for (loc_idx = 0; loc_idx < num_locations_to_remove; loc_idx++) 467 m_locations.RemoveLocation (locations_to_remove.GetByIndex(loc_idx)); 468 } 469 } 470 } 471 SendBreakpointChangedEvent (removed_locations_event); 472 } 473 } 474 475 void 476 Breakpoint::ModuleReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp) 477 { 478 ModuleList temp_list; 479 temp_list.Append (new_module_sp); 480 ModulesChanged (temp_list, true); 481 482 // TO DO: For now I'm just adding locations for the new module and removing the 483 // breakpoint locations that were in the old module. 484 // We should really go find the ones that are in the new module & if we can determine that they are "equivalent" 485 // carry over the options from the old location to the new. 486 487 temp_list.Clear(); 488 temp_list.Append (old_module_sp); 489 ModulesChanged (temp_list, false, true); 490 } 491 492 void 493 Breakpoint::Dump (Stream *) 494 { 495 } 496 497 size_t 498 Breakpoint::GetNumResolvedLocations() const 499 { 500 // Return the number of breakpoints that are actually resolved and set 501 // down in the inferior process. 502 return m_locations.GetNumResolvedLocations(); 503 } 504 505 size_t 506 Breakpoint::GetNumLocations() const 507 { 508 return m_locations.GetSize(); 509 } 510 511 void 512 Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations) 513 { 514 assert (s != NULL); 515 s->Printf("%i: ", GetID()); 516 GetResolverDescription (s); 517 GetFilterDescription (s); 518 519 const size_t num_locations = GetNumLocations (); 520 const size_t num_resolved_locations = GetNumResolvedLocations (); 521 522 switch (level) 523 { 524 case lldb::eDescriptionLevelBrief: 525 case lldb::eDescriptionLevelFull: 526 if (num_locations > 0) 527 { 528 s->Printf(", locations = %llu", (uint64_t)num_locations); 529 if (num_resolved_locations > 0) 530 s->Printf(", resolved = %llu", (uint64_t)num_resolved_locations); 531 } 532 else 533 { 534 // Don't print the pending notification for exception resolvers since we don't generally 535 // know how to set them until the target is run. 536 if (m_resolver_sp->getResolverID() != BreakpointResolver::ExceptionResolver) 537 s->Printf(", locations = 0 (pending)"); 538 } 539 540 GetOptions()->GetDescription(s, level); 541 542 if (level == lldb::eDescriptionLevelFull) 543 { 544 s->IndentLess(); 545 s->EOL(); 546 } 547 break; 548 549 case lldb::eDescriptionLevelVerbose: 550 // Verbose mode does a debug dump of the breakpoint 551 Dump (s); 552 s->EOL (); 553 //s->Indent(); 554 GetOptions()->GetDescription(s, level); 555 break; 556 557 default: 558 break; 559 } 560 561 // The brief description is just the location name (1.2 or whatever). That's pointless to 562 // show in the breakpoint's description, so suppress it. 563 if (show_locations && level != lldb::eDescriptionLevelBrief) 564 { 565 s->IndentMore(); 566 for (size_t i = 0; i < num_locations; ++i) 567 { 568 BreakpointLocation *loc = GetLocationAtIndex(i).get(); 569 loc->GetDescription(s, level); 570 s->EOL(); 571 } 572 s->IndentLess(); 573 } 574 } 575 576 void 577 Breakpoint::GetResolverDescription (Stream *s) 578 { 579 if (m_resolver_sp) 580 m_resolver_sp->GetDescription (s); 581 } 582 583 584 bool 585 Breakpoint::GetMatchingFileLine (const ConstString &filename, uint32_t line_number, BreakpointLocationCollection &loc_coll) 586 { 587 // TODO: To be correct, this method needs to fill the breakpoint location collection 588 // with the location IDs which match the filename and line_number. 589 // 590 591 if (m_resolver_sp) 592 { 593 BreakpointResolverFileLine *resolverFileLine = dyn_cast<BreakpointResolverFileLine>(m_resolver_sp.get()); 594 if (resolverFileLine && 595 resolverFileLine->m_file_spec.GetFilename() == filename && 596 resolverFileLine->m_line_number == line_number) 597 { 598 return true; 599 } 600 } 601 return false; 602 } 603 604 void 605 Breakpoint::GetFilterDescription (Stream *s) 606 { 607 m_filter_sp->GetDescription (s); 608 } 609 610 void 611 Breakpoint::SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind) 612 { 613 if (!m_being_created 614 && !IsInternal() 615 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 616 { 617 BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, shared_from_this()); 618 619 GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); 620 } 621 } 622 623 void 624 Breakpoint::SendBreakpointChangedEvent (BreakpointEventData *data) 625 { 626 627 if (data == NULL) 628 return; 629 630 if (!m_being_created 631 && !IsInternal() 632 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 633 GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); 634 else 635 delete data; 636 } 637 638 Breakpoint::BreakpointEventData::BreakpointEventData (BreakpointEventType sub_type, 639 const BreakpointSP &new_breakpoint_sp) : 640 EventData (), 641 m_breakpoint_event (sub_type), 642 m_new_breakpoint_sp (new_breakpoint_sp) 643 { 644 } 645 646 Breakpoint::BreakpointEventData::~BreakpointEventData () 647 { 648 } 649 650 const ConstString & 651 Breakpoint::BreakpointEventData::GetFlavorString () 652 { 653 static ConstString g_flavor ("Breakpoint::BreakpointEventData"); 654 return g_flavor; 655 } 656 657 const ConstString & 658 Breakpoint::BreakpointEventData::GetFlavor () const 659 { 660 return BreakpointEventData::GetFlavorString (); 661 } 662 663 664 BreakpointSP & 665 Breakpoint::BreakpointEventData::GetBreakpoint () 666 { 667 return m_new_breakpoint_sp; 668 } 669 670 BreakpointEventType 671 Breakpoint::BreakpointEventData::GetBreakpointEventType () const 672 { 673 return m_breakpoint_event; 674 } 675 676 void 677 Breakpoint::BreakpointEventData::Dump (Stream *s) const 678 { 679 } 680 681 const Breakpoint::BreakpointEventData * 682 Breakpoint::BreakpointEventData::GetEventDataFromEvent (const Event *event) 683 { 684 if (event) 685 { 686 const EventData *event_data = event->GetData(); 687 if (event_data && event_data->GetFlavor() == BreakpointEventData::GetFlavorString()) 688 return static_cast <const BreakpointEventData *> (event->GetData()); 689 } 690 return NULL; 691 } 692 693 BreakpointEventType 694 Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (const EventSP &event_sp) 695 { 696 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 697 698 if (data == NULL) 699 return eBreakpointEventTypeInvalidType; 700 else 701 return data->GetBreakpointEventType(); 702 } 703 704 BreakpointSP 705 Breakpoint::BreakpointEventData::GetBreakpointFromEvent (const EventSP &event_sp) 706 { 707 BreakpointSP bp_sp; 708 709 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 710 if (data) 711 bp_sp = data->m_new_breakpoint_sp; 712 713 return bp_sp; 714 } 715 716 uint32_t 717 Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (const EventSP &event_sp) 718 { 719 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 720 if (data) 721 return data->m_locations.GetSize(); 722 723 return 0; 724 } 725 726 lldb::BreakpointLocationSP 727 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t bp_loc_idx) 728 { 729 lldb::BreakpointLocationSP bp_loc_sp; 730 731 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 732 if (data) 733 { 734 bp_loc_sp = data->m_locations.GetByIndex(bp_loc_idx); 735 } 736 737 return bp_loc_sp; 738 } 739