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