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 // C Includes 11 // C++ Includes 12 // Other libraries and framework includes 13 #include "llvm/Support/Casting.h" 14 15 // Project includes 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/Module.h" 24 #include "lldb/Core/ModuleList.h" 25 #include "lldb/Core/SearchFilter.h" 26 #include "lldb/Core/Section.h" 27 #include "lldb/Core/Stream.h" 28 #include "lldb/Core/StreamString.h" 29 #include "lldb/Symbol/CompileUnit.h" 30 #include "lldb/Symbol/Function.h" 31 #include "lldb/Symbol/SymbolContext.h" 32 #include "lldb/Target/Target.h" 33 #include "lldb/Target/ThreadSpec.h" 34 35 using namespace lldb; 36 using namespace lldb_private; 37 using namespace llvm; 38 39 const ConstString & 40 Breakpoint::GetEventIdentifier () 41 { 42 static ConstString g_identifier("event-identifier.breakpoint.changed"); 43 return g_identifier; 44 } 45 46 //---------------------------------------------------------------------- 47 // Breakpoint constructor 48 //---------------------------------------------------------------------- 49 Breakpoint::Breakpoint(Target &target, 50 SearchFilterSP &filter_sp, 51 BreakpointResolverSP &resolver_sp, 52 bool hardware, 53 bool resolve_indirect_symbols) : 54 m_being_created(true), 55 m_hardware(hardware), 56 m_target (target), 57 m_filter_sp (filter_sp), 58 m_resolver_sp (resolver_sp), 59 m_options (), 60 m_locations (*this), 61 m_resolve_indirect_symbols(resolve_indirect_symbols), 62 m_hit_count(0) 63 { 64 m_being_created = false; 65 } 66 67 Breakpoint::Breakpoint (Target &new_target, Breakpoint &source_bp) : 68 m_being_created(true), 69 m_hardware(source_bp.m_hardware), 70 m_target(new_target), 71 m_name_list (source_bp.m_name_list), 72 m_options (source_bp.m_options), 73 m_locations(*this), 74 m_resolve_indirect_symbols(source_bp.m_resolve_indirect_symbols), 75 m_hit_count(0) 76 { 77 // Now go through and copy the filter & resolver: 78 m_resolver_sp = source_bp.m_resolver_sp->CopyForBreakpoint(*this); 79 m_filter_sp = source_bp.m_filter_sp->CopyForBreakpoint(*this); 80 } 81 82 //---------------------------------------------------------------------- 83 // Destructor 84 //---------------------------------------------------------------------- 85 Breakpoint::~Breakpoint() = default; 86 87 const lldb::TargetSP 88 Breakpoint::GetTargetSP () 89 { 90 return m_target.shared_from_this(); 91 } 92 93 bool 94 Breakpoint::IsInternal () const 95 { 96 return LLDB_BREAK_ID_IS_INTERNAL(m_bid); 97 } 98 99 BreakpointLocationSP 100 Breakpoint::AddLocation (const Address &addr, bool *new_location) 101 { 102 return m_locations.AddLocation (addr, m_resolve_indirect_symbols, new_location); 103 } 104 105 BreakpointLocationSP 106 Breakpoint::FindLocationByAddress (const Address &addr) 107 { 108 return m_locations.FindByAddress(addr); 109 } 110 111 break_id_t 112 Breakpoint::FindLocationIDByAddress (const Address &addr) 113 { 114 return m_locations.FindIDByAddress(addr); 115 } 116 117 BreakpointLocationSP 118 Breakpoint::FindLocationByID (break_id_t bp_loc_id) 119 { 120 return m_locations.FindByID(bp_loc_id); 121 } 122 123 BreakpointLocationSP 124 Breakpoint::GetLocationAtIndex (size_t index) 125 { 126 return m_locations.GetByIndex(index); 127 } 128 129 void 130 Breakpoint::RemoveInvalidLocations (const ArchSpec &arch) 131 { 132 m_locations.RemoveInvalidLocations(arch); 133 } 134 135 // For each of the overall options we need to decide how they propagate to 136 // the location options. This will determine the precedence of options on 137 // the breakpoint vs. its locations. 138 139 // Disable at the breakpoint level should override the location settings. 140 // That way you can conveniently turn off a whole breakpoint without messing 141 // up the individual settings. 142 143 void 144 Breakpoint::SetEnabled (bool enable) 145 { 146 if (enable == m_options.IsEnabled()) 147 return; 148 149 m_options.SetEnabled(enable); 150 if (enable) 151 m_locations.ResolveAllBreakpointSites(); 152 else 153 m_locations.ClearAllBreakpointSites(); 154 155 SendBreakpointChangedEvent (enable ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled); 156 157 } 158 159 bool 160 Breakpoint::IsEnabled () 161 { 162 return m_options.IsEnabled(); 163 } 164 165 void 166 Breakpoint::SetIgnoreCount (uint32_t n) 167 { 168 if (m_options.GetIgnoreCount() == n) 169 return; 170 171 m_options.SetIgnoreCount(n); 172 SendBreakpointChangedEvent (eBreakpointEventTypeIgnoreChanged); 173 } 174 175 void 176 Breakpoint::DecrementIgnoreCount () 177 { 178 uint32_t ignore = m_options.GetIgnoreCount(); 179 if (ignore != 0) 180 m_options.SetIgnoreCount(ignore - 1); 181 } 182 183 uint32_t 184 Breakpoint::GetIgnoreCount () const 185 { 186 return m_options.GetIgnoreCount(); 187 } 188 189 bool 190 Breakpoint::IgnoreCountShouldStop () 191 { 192 uint32_t ignore = GetIgnoreCount(); 193 if (ignore != 0) 194 { 195 // When we get here we know the location that caused the stop doesn't have an ignore count, 196 // since by contract we call it first... So we don't have to find & decrement it, we only have 197 // to decrement our own ignore count. 198 DecrementIgnoreCount(); 199 return false; 200 } 201 else 202 return true; 203 } 204 205 uint32_t 206 Breakpoint::GetHitCount () const 207 { 208 return m_hit_count; 209 } 210 211 bool 212 Breakpoint::IsOneShot () const 213 { 214 return m_options.IsOneShot(); 215 } 216 217 void 218 Breakpoint::SetOneShot (bool one_shot) 219 { 220 m_options.SetOneShot (one_shot); 221 } 222 223 void 224 Breakpoint::SetThreadID (lldb::tid_t thread_id) 225 { 226 if (m_options.GetThreadSpec()->GetTID() == thread_id) 227 return; 228 229 m_options.GetThreadSpec()->SetTID(thread_id); 230 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged); 231 } 232 233 lldb::tid_t 234 Breakpoint::GetThreadID () const 235 { 236 if (m_options.GetThreadSpecNoCreate() == nullptr) 237 return LLDB_INVALID_THREAD_ID; 238 else 239 return m_options.GetThreadSpecNoCreate()->GetTID(); 240 } 241 242 void 243 Breakpoint::SetThreadIndex (uint32_t index) 244 { 245 if (m_options.GetThreadSpec()->GetIndex() == index) 246 return; 247 248 m_options.GetThreadSpec()->SetIndex(index); 249 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged); 250 } 251 252 uint32_t 253 Breakpoint::GetThreadIndex() const 254 { 255 if (m_options.GetThreadSpecNoCreate() == nullptr) 256 return 0; 257 else 258 return m_options.GetThreadSpecNoCreate()->GetIndex(); 259 } 260 261 void 262 Breakpoint::SetThreadName (const char *thread_name) 263 { 264 if (m_options.GetThreadSpec()->GetName() != nullptr 265 && ::strcmp (m_options.GetThreadSpec()->GetName(), thread_name) == 0) 266 return; 267 268 m_options.GetThreadSpec()->SetName (thread_name); 269 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged); 270 } 271 272 const char * 273 Breakpoint::GetThreadName () const 274 { 275 if (m_options.GetThreadSpecNoCreate() == nullptr) 276 return nullptr; 277 else 278 return m_options.GetThreadSpecNoCreate()->GetName(); 279 } 280 281 void 282 Breakpoint::SetQueueName (const char *queue_name) 283 { 284 if (m_options.GetThreadSpec()->GetQueueName() != nullptr 285 && ::strcmp (m_options.GetThreadSpec()->GetQueueName(), queue_name) == 0) 286 return; 287 288 m_options.GetThreadSpec()->SetQueueName (queue_name); 289 SendBreakpointChangedEvent (eBreakpointEventTypeThreadChanged); 290 } 291 292 const char * 293 Breakpoint::GetQueueName () const 294 { 295 if (m_options.GetThreadSpecNoCreate() == nullptr) 296 return nullptr; 297 else 298 return m_options.GetThreadSpecNoCreate()->GetQueueName(); 299 } 300 301 void 302 Breakpoint::SetCondition (const char *condition) 303 { 304 m_options.SetCondition (condition); 305 SendBreakpointChangedEvent (eBreakpointEventTypeConditionChanged); 306 } 307 308 const char * 309 Breakpoint::GetConditionText () const 310 { 311 return m_options.GetConditionText(); 312 } 313 314 // This function is used when "baton" doesn't need to be freed 315 void 316 Breakpoint::SetCallback (BreakpointHitCallback callback, void *baton, bool is_synchronous) 317 { 318 // The default "Baton" class will keep a copy of "baton" and won't free 319 // or delete it when it goes goes out of scope. 320 m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous); 321 322 SendBreakpointChangedEvent (eBreakpointEventTypeCommandChanged); 323 } 324 325 // This function is used when a baton needs to be freed and therefore is 326 // contained in a "Baton" subclass. 327 void 328 Breakpoint::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous) 329 { 330 m_options.SetCallback(callback, callback_baton_sp, is_synchronous); 331 } 332 333 void 334 Breakpoint::ClearCallback () 335 { 336 m_options.ClearCallback (); 337 } 338 339 bool 340 Breakpoint::InvokeCallback (StoppointCallbackContext *context, break_id_t bp_loc_id) 341 { 342 return m_options.InvokeCallback (context, GetID(), bp_loc_id); 343 } 344 345 BreakpointOptions * 346 Breakpoint::GetOptions () 347 { 348 return &m_options; 349 } 350 351 void 352 Breakpoint::ResolveBreakpoint () 353 { 354 if (m_resolver_sp) 355 m_resolver_sp->ResolveBreakpoint(*m_filter_sp); 356 } 357 358 void 359 Breakpoint::ResolveBreakpointInModules (ModuleList &module_list, BreakpointLocationCollection &new_locations) 360 { 361 m_locations.StartRecordingNewLocations(new_locations); 362 363 m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list); 364 365 m_locations.StopRecordingNewLocations(); 366 } 367 368 void 369 Breakpoint::ResolveBreakpointInModules (ModuleList &module_list, bool send_event) 370 { 371 if (m_resolver_sp) 372 { 373 // If this is not an internal breakpoint, set up to record the new locations, then dispatch 374 // an event with the new locations. 375 if (!IsInternal() && send_event) 376 { 377 BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded, 378 shared_from_this()); 379 380 ResolveBreakpointInModules (module_list, new_locations_event->GetBreakpointLocationCollection()); 381 382 if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0) 383 { 384 SendBreakpointChangedEvent (new_locations_event); 385 } 386 else 387 delete new_locations_event; 388 } 389 else 390 { 391 m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list); 392 } 393 } 394 } 395 396 void 397 Breakpoint::ClearAllBreakpointSites () 398 { 399 m_locations.ClearAllBreakpointSites(); 400 } 401 402 //---------------------------------------------------------------------- 403 // ModulesChanged: Pass in a list of new modules, and 404 //---------------------------------------------------------------------- 405 406 void 407 Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_locations) 408 { 409 Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 410 if (log) 411 log->Printf ("Breakpoint::ModulesChanged: num_modules: %zu load: %i delete_locations: %i\n", 412 module_list.GetSize(), load, delete_locations); 413 414 Mutex::Locker modules_mutex(module_list.GetMutex()); 415 if (load) 416 { 417 // The logic for handling new modules is: 418 // 1) If the filter rejects this module, then skip it. 419 // 2) Run through the current location list and if there are any locations 420 // for that module, we mark the module as "seen" and we don't try to re-resolve 421 // breakpoint locations for that module. 422 // However, we do add breakpoint sites to these locations if needed. 423 // 3) If we don't see this module in our breakpoint location list, call ResolveInModules. 424 425 ModuleList new_modules; // We'll stuff the "unseen" modules in this list, and then resolve 426 // them after the locations pass. Have to do it this way because 427 // resolving breakpoints will add new locations potentially. 428 429 for (ModuleSP module_sp : module_list.ModulesNoLocking()) 430 { 431 bool seen = false; 432 if (!m_filter_sp->ModulePasses (module_sp)) 433 continue; 434 435 for (BreakpointLocationSP break_loc_sp : m_locations.BreakpointLocations()) 436 { 437 if (!break_loc_sp->IsEnabled()) 438 continue; 439 SectionSP section_sp (break_loc_sp->GetAddress().GetSection()); 440 if (!section_sp || section_sp->GetModule() == module_sp) 441 { 442 if (!seen) 443 seen = true; 444 445 if (!break_loc_sp->ResolveBreakpointSite()) 446 { 447 if (log) 448 log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n", 449 break_loc_sp->GetID(), GetID()); 450 } 451 } 452 } 453 454 if (!seen) 455 new_modules.AppendIfNeeded (module_sp); 456 } 457 458 if (new_modules.GetSize() > 0) 459 { 460 ResolveBreakpointInModules(new_modules); 461 } 462 } 463 else 464 { 465 // Go through the currently set locations and if any have breakpoints in 466 // the module list, then remove their breakpoint sites, and their locations if asked to. 467 468 BreakpointEventData *removed_locations_event; 469 if (!IsInternal()) 470 removed_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved, 471 shared_from_this()); 472 else 473 removed_locations_event = nullptr; 474 475 size_t num_modules = module_list.GetSize(); 476 for (size_t i = 0; i < num_modules; i++) 477 { 478 ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i)); 479 if (m_filter_sp->ModulePasses (module_sp)) 480 { 481 size_t loc_idx = 0; 482 size_t num_locations = m_locations.GetSize(); 483 BreakpointLocationCollection locations_to_remove; 484 for (loc_idx = 0; loc_idx < num_locations; loc_idx++) 485 { 486 BreakpointLocationSP break_loc_sp (m_locations.GetByIndex(loc_idx)); 487 SectionSP section_sp (break_loc_sp->GetAddress().GetSection()); 488 if (section_sp && section_sp->GetModule() == module_sp) 489 { 490 // Remove this breakpoint since the shared library is 491 // unloaded, but keep the breakpoint location around 492 // so we always get complete hit count and breakpoint 493 // lifetime info 494 break_loc_sp->ClearBreakpointSite(); 495 if (removed_locations_event) 496 { 497 removed_locations_event->GetBreakpointLocationCollection().Add(break_loc_sp); 498 } 499 if (delete_locations) 500 locations_to_remove.Add (break_loc_sp); 501 } 502 } 503 504 if (delete_locations) 505 { 506 size_t num_locations_to_remove = locations_to_remove.GetSize(); 507 for (loc_idx = 0; loc_idx < num_locations_to_remove; loc_idx++) 508 m_locations.RemoveLocation (locations_to_remove.GetByIndex(loc_idx)); 509 } 510 } 511 } 512 SendBreakpointChangedEvent (removed_locations_event); 513 } 514 } 515 516 namespace 517 { 518 static bool 519 SymbolContextsMightBeEquivalent(SymbolContext &old_sc, SymbolContext &new_sc) 520 { 521 bool equivalent_scs = false; 522 523 if (old_sc.module_sp.get() == new_sc.module_sp.get()) 524 { 525 // If these come from the same module, we can directly compare the pointers: 526 if (old_sc.comp_unit && new_sc.comp_unit 527 && (old_sc.comp_unit == new_sc.comp_unit)) 528 { 529 if (old_sc.function && new_sc.function 530 && (old_sc.function == new_sc.function)) 531 { 532 equivalent_scs = true; 533 } 534 } 535 else if (old_sc.symbol && new_sc.symbol 536 && (old_sc.symbol == new_sc.symbol)) 537 { 538 equivalent_scs = true; 539 } 540 } 541 else 542 { 543 // Otherwise we will compare by name... 544 if (old_sc.comp_unit && new_sc.comp_unit) 545 { 546 if (FileSpec::Equal(*old_sc.comp_unit, *new_sc.comp_unit, true)) 547 { 548 // Now check the functions: 549 if (old_sc.function && new_sc.function 550 && (old_sc.function->GetName() == new_sc.function->GetName())) 551 { 552 equivalent_scs = true; 553 } 554 } 555 } 556 else if (old_sc.symbol && new_sc.symbol) 557 { 558 if (Mangled::Compare(old_sc.symbol->GetMangled(), new_sc.symbol->GetMangled()) == 0) 559 { 560 equivalent_scs = true; 561 } 562 } 563 } 564 return equivalent_scs; 565 } 566 } // anonymous namespace 567 568 void 569 Breakpoint::ModuleReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp) 570 { 571 Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 572 if (log) 573 log->Printf ("Breakpoint::ModulesReplaced for %s\n", 574 old_module_sp->GetSpecificationDescription().c_str()); 575 // First find all the locations that are in the old module 576 577 BreakpointLocationCollection old_break_locs; 578 for (BreakpointLocationSP break_loc_sp : m_locations.BreakpointLocations()) 579 { 580 SectionSP section_sp = break_loc_sp->GetAddress().GetSection(); 581 if (section_sp && section_sp->GetModule() == old_module_sp) 582 { 583 old_break_locs.Add(break_loc_sp); 584 } 585 } 586 587 size_t num_old_locations = old_break_locs.GetSize(); 588 589 if (num_old_locations == 0) 590 { 591 // There were no locations in the old module, so we just need to check if there were any in the new module. 592 ModuleList temp_list; 593 temp_list.Append (new_module_sp); 594 ResolveBreakpointInModules(temp_list); 595 } 596 else 597 { 598 // First search the new module for locations. 599 // Then compare this with the old list, copy over locations that "look the same" 600 // Then delete the old locations. 601 // Finally remember to post the creation event. 602 // 603 // Two locations are the same if they have the same comp unit & function (by name) and there are the same number 604 // of locations in the old function as in the new one. 605 606 ModuleList temp_list; 607 temp_list.Append (new_module_sp); 608 BreakpointLocationCollection new_break_locs; 609 ResolveBreakpointInModules(temp_list, new_break_locs); 610 BreakpointLocationCollection locations_to_remove; 611 BreakpointLocationCollection locations_to_announce; 612 613 size_t num_new_locations = new_break_locs.GetSize(); 614 615 if (num_new_locations > 0) 616 { 617 // Break out the case of one location -> one location since that's the most common one, and there's no need 618 // to build up the structures needed for the merge in that case. 619 if (num_new_locations == 1 && num_old_locations == 1) 620 { 621 bool equivalent_locations = false; 622 SymbolContext old_sc, new_sc; 623 // The only way the old and new location can be equivalent is if they have the same amount of information: 624 BreakpointLocationSP old_loc_sp = old_break_locs.GetByIndex(0); 625 BreakpointLocationSP new_loc_sp = new_break_locs.GetByIndex(0); 626 627 if (old_loc_sp->GetAddress().CalculateSymbolContext(&old_sc) 628 == new_loc_sp->GetAddress().CalculateSymbolContext(&new_sc)) 629 { 630 equivalent_locations = SymbolContextsMightBeEquivalent(old_sc, new_sc); 631 } 632 633 if (equivalent_locations) 634 { 635 m_locations.SwapLocation (old_loc_sp, new_loc_sp); 636 } 637 else 638 { 639 locations_to_remove.Add(old_loc_sp); 640 locations_to_announce.Add(new_loc_sp); 641 } 642 } 643 else 644 { 645 //We don't want to have to keep computing the SymbolContexts for these addresses over and over, 646 // so lets get them up front: 647 648 typedef std::map<lldb::break_id_t, SymbolContext> IDToSCMap; 649 IDToSCMap old_sc_map; 650 for (size_t idx = 0; idx < num_old_locations; idx++) 651 { 652 SymbolContext sc; 653 BreakpointLocationSP bp_loc_sp = old_break_locs.GetByIndex(idx); 654 lldb::break_id_t loc_id = bp_loc_sp->GetID(); 655 bp_loc_sp->GetAddress().CalculateSymbolContext(&old_sc_map[loc_id]); 656 } 657 658 std::map<lldb::break_id_t, SymbolContext> new_sc_map; 659 for (size_t idx = 0; idx < num_new_locations; idx++) 660 { 661 SymbolContext sc; 662 BreakpointLocationSP bp_loc_sp = new_break_locs.GetByIndex(idx); 663 lldb::break_id_t loc_id = bp_loc_sp->GetID(); 664 bp_loc_sp->GetAddress().CalculateSymbolContext(&new_sc_map[loc_id]); 665 } 666 // Take an element from the old Symbol Contexts 667 while (old_sc_map.size() > 0) 668 { 669 lldb::break_id_t old_id = old_sc_map.begin()->first; 670 SymbolContext &old_sc = old_sc_map.begin()->second; 671 672 // Count the number of entries equivalent to this SC for the old list: 673 std::vector<lldb::break_id_t> old_id_vec; 674 old_id_vec.push_back(old_id); 675 676 IDToSCMap::iterator tmp_iter; 677 for (tmp_iter = ++old_sc_map.begin(); tmp_iter != old_sc_map.end(); tmp_iter++) 678 { 679 if (SymbolContextsMightBeEquivalent (old_sc, tmp_iter->second)) 680 old_id_vec.push_back (tmp_iter->first); 681 } 682 683 // Now find all the equivalent locations in the new list. 684 std::vector<lldb::break_id_t> new_id_vec; 685 for (tmp_iter = new_sc_map.begin(); tmp_iter != new_sc_map.end(); tmp_iter++) 686 { 687 if (SymbolContextsMightBeEquivalent (old_sc, tmp_iter->second)) 688 new_id_vec.push_back(tmp_iter->first); 689 } 690 691 // Alright, if we have the same number of potentially equivalent locations in the old 692 // and new modules, we'll just map them one to one in ascending ID order (assuming the 693 // resolver's order would match the equivalent ones. 694 // Otherwise, we'll dump all the old ones, and just take the new ones, erasing the elements 695 // from both maps as we go. 696 697 if (old_id_vec.size() == new_id_vec.size()) 698 { 699 sort(old_id_vec.begin(), old_id_vec.end()); 700 sort(new_id_vec.begin(), new_id_vec.end()); 701 size_t num_elements = old_id_vec.size(); 702 for (size_t idx = 0; idx < num_elements; idx++) 703 { 704 BreakpointLocationSP old_loc_sp = old_break_locs.FindByIDPair(GetID(), old_id_vec[idx]); 705 BreakpointLocationSP new_loc_sp = new_break_locs.FindByIDPair(GetID(), new_id_vec[idx]); 706 m_locations.SwapLocation(old_loc_sp, new_loc_sp); 707 old_sc_map.erase(old_id_vec[idx]); 708 new_sc_map.erase(new_id_vec[idx]); 709 } 710 } 711 else 712 { 713 for (lldb::break_id_t old_id : old_id_vec) 714 { 715 locations_to_remove.Add(old_break_locs.FindByIDPair(GetID(), old_id)); 716 old_sc_map.erase(old_id); 717 } 718 for (lldb::break_id_t new_id : new_id_vec) 719 { 720 locations_to_announce.Add(new_break_locs.FindByIDPair(GetID(), new_id)); 721 new_sc_map.erase(new_id); 722 } 723 } 724 } 725 } 726 } 727 728 // Now remove the remaining old locations, and cons up a removed locations event. 729 // Note, we don't put the new locations that were swapped with an old location on the locations_to_remove 730 // list, so we don't need to worry about telling the world about removing a location we didn't tell them 731 // about adding. 732 733 BreakpointEventData *locations_event; 734 if (!IsInternal()) 735 locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved, 736 shared_from_this()); 737 else 738 locations_event = nullptr; 739 740 for (BreakpointLocationSP loc_sp : locations_to_remove.BreakpointLocations()) 741 { 742 m_locations.RemoveLocation(loc_sp); 743 if (locations_event) 744 locations_event->GetBreakpointLocationCollection().Add(loc_sp); 745 } 746 SendBreakpointChangedEvent (locations_event); 747 748 // And announce the new ones. 749 750 if (!IsInternal()) 751 { 752 locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded, 753 shared_from_this()); 754 for (BreakpointLocationSP loc_sp : locations_to_announce.BreakpointLocations()) 755 locations_event->GetBreakpointLocationCollection().Add(loc_sp); 756 757 SendBreakpointChangedEvent (locations_event); 758 } 759 m_locations.Compact(); 760 } 761 } 762 763 void 764 Breakpoint::Dump (Stream *) 765 { 766 } 767 768 size_t 769 Breakpoint::GetNumResolvedLocations() const 770 { 771 // Return the number of breakpoints that are actually resolved and set 772 // down in the inferior process. 773 return m_locations.GetNumResolvedLocations(); 774 } 775 776 size_t 777 Breakpoint::GetNumLocations() const 778 { 779 return m_locations.GetSize(); 780 } 781 782 bool 783 Breakpoint::AddName (const char *new_name, Error &error) 784 { 785 if (!new_name) 786 return false; 787 if (!BreakpointID::StringIsBreakpointName(new_name, error)) 788 { 789 error.SetErrorStringWithFormat("input name \"%s\" not a breakpoint name.", new_name); 790 return false; 791 } 792 if (!error.Success()) 793 return false; 794 795 m_name_list.insert(new_name); 796 return true; 797 } 798 799 void 800 Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations) 801 { 802 assert (s != nullptr); 803 804 if (!m_kind_description.empty()) 805 { 806 if (level == eDescriptionLevelBrief) 807 { 808 s->PutCString (GetBreakpointKind()); 809 return; 810 } 811 else 812 s->Printf("Kind: %s\n", GetBreakpointKind ()); 813 } 814 815 const size_t num_locations = GetNumLocations (); 816 const size_t num_resolved_locations = GetNumResolvedLocations (); 817 818 // They just made the breakpoint, they don't need to be told HOW they made it... 819 // Also, we'll print the breakpoint number differently depending on whether there is 1 or more locations. 820 if (level != eDescriptionLevelInitial) 821 { 822 s->Printf("%i: ", GetID()); 823 GetResolverDescription (s); 824 GetFilterDescription (s); 825 } 826 827 switch (level) 828 { 829 case lldb::eDescriptionLevelBrief: 830 case lldb::eDescriptionLevelFull: 831 if (num_locations > 0) 832 { 833 s->Printf(", locations = %" PRIu64, (uint64_t)num_locations); 834 if (num_resolved_locations > 0) 835 s->Printf(", resolved = %" PRIu64 ", hit count = %d", (uint64_t)num_resolved_locations, GetHitCount()); 836 } 837 else 838 { 839 // Don't print the pending notification for exception resolvers since we don't generally 840 // know how to set them until the target is run. 841 if (m_resolver_sp->getResolverID() != BreakpointResolver::ExceptionResolver) 842 s->Printf(", locations = 0 (pending)"); 843 } 844 845 GetOptions()->GetDescription(s, level); 846 847 if (level == lldb::eDescriptionLevelFull) 848 { 849 if (!m_name_list.empty()) 850 { 851 s->EOL(); 852 s->Indent(); 853 s->Printf ("Names:"); 854 s->EOL(); 855 s->IndentMore(); 856 for (std::string name : m_name_list) 857 { 858 s->Indent(); 859 s->Printf("%s\n", name.c_str()); 860 } 861 s->IndentLess(); 862 } 863 s->IndentLess(); 864 s->EOL(); 865 } 866 break; 867 868 case lldb::eDescriptionLevelInitial: 869 s->Printf ("Breakpoint %i: ", GetID()); 870 if (num_locations == 0) 871 { 872 s->Printf ("no locations (pending)."); 873 } 874 else if (num_locations == 1 && !show_locations) 875 { 876 // There is only one location, so we'll just print that location information. 877 GetLocationAtIndex(0)->GetDescription(s, level); 878 } 879 else 880 { 881 s->Printf ("%" PRIu64 " locations.", static_cast<uint64_t>(num_locations)); 882 } 883 s->EOL(); 884 break; 885 886 case lldb::eDescriptionLevelVerbose: 887 // Verbose mode does a debug dump of the breakpoint 888 Dump (s); 889 s->EOL (); 890 //s->Indent(); 891 GetOptions()->GetDescription(s, level); 892 break; 893 894 default: 895 break; 896 } 897 898 // The brief description is just the location name (1.2 or whatever). That's pointless to 899 // show in the breakpoint's description, so suppress it. 900 if (show_locations && level != lldb::eDescriptionLevelBrief) 901 { 902 s->IndentMore(); 903 for (size_t i = 0; i < num_locations; ++i) 904 { 905 BreakpointLocation *loc = GetLocationAtIndex(i).get(); 906 loc->GetDescription(s, level); 907 s->EOL(); 908 } 909 s->IndentLess(); 910 } 911 } 912 913 void 914 Breakpoint::GetResolverDescription (Stream *s) 915 { 916 if (m_resolver_sp) 917 m_resolver_sp->GetDescription (s); 918 } 919 920 bool 921 Breakpoint::GetMatchingFileLine (const ConstString &filename, uint32_t line_number, BreakpointLocationCollection &loc_coll) 922 { 923 // TODO: To be correct, this method needs to fill the breakpoint location collection 924 // with the location IDs which match the filename and line_number. 925 // 926 927 if (m_resolver_sp) 928 { 929 BreakpointResolverFileLine *resolverFileLine = dyn_cast<BreakpointResolverFileLine>(m_resolver_sp.get()); 930 if (resolverFileLine && 931 resolverFileLine->m_file_spec.GetFilename() == filename && 932 resolverFileLine->m_line_number == line_number) 933 { 934 return true; 935 } 936 } 937 return false; 938 } 939 940 void 941 Breakpoint::GetFilterDescription (Stream *s) 942 { 943 m_filter_sp->GetDescription (s); 944 } 945 946 bool 947 Breakpoint::EvaluatePrecondition (StoppointCallbackContext &context) 948 { 949 if (!m_precondition_sp) 950 return true; 951 952 return m_precondition_sp->EvaluatePrecondition(context); 953 } 954 955 bool 956 Breakpoint::BreakpointPrecondition::EvaluatePrecondition(StoppointCallbackContext &context) 957 { 958 return true; 959 } 960 961 void 962 Breakpoint::BreakpointPrecondition::DescribePrecondition(Stream &stream, lldb::DescriptionLevel level) 963 { 964 } 965 966 Error 967 Breakpoint::BreakpointPrecondition::ConfigurePrecondition(Args &options) 968 { 969 Error error; 970 error.SetErrorString("Base breakpoint precondition has no options."); 971 return error; 972 } 973 974 void 975 Breakpoint::SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind) 976 { 977 if (!m_being_created 978 && !IsInternal() 979 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 980 { 981 BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind, shared_from_this()); 982 983 GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); 984 } 985 } 986 987 void 988 Breakpoint::SendBreakpointChangedEvent (BreakpointEventData *data) 989 { 990 if (data == nullptr) 991 return; 992 993 if (!m_being_created 994 && !IsInternal() 995 && GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) 996 GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data); 997 else 998 delete data; 999 } 1000 1001 Breakpoint::BreakpointEventData::BreakpointEventData (BreakpointEventType sub_type, 1002 const BreakpointSP &new_breakpoint_sp) : 1003 EventData (), 1004 m_breakpoint_event (sub_type), 1005 m_new_breakpoint_sp (new_breakpoint_sp) 1006 { 1007 } 1008 1009 Breakpoint::BreakpointEventData::~BreakpointEventData() = default; 1010 1011 const ConstString & 1012 Breakpoint::BreakpointEventData::GetFlavorString () 1013 { 1014 static ConstString g_flavor ("Breakpoint::BreakpointEventData"); 1015 return g_flavor; 1016 } 1017 1018 const ConstString & 1019 Breakpoint::BreakpointEventData::GetFlavor () const 1020 { 1021 return BreakpointEventData::GetFlavorString (); 1022 } 1023 1024 BreakpointSP & 1025 Breakpoint::BreakpointEventData::GetBreakpoint () 1026 { 1027 return m_new_breakpoint_sp; 1028 } 1029 1030 BreakpointEventType 1031 Breakpoint::BreakpointEventData::GetBreakpointEventType () const 1032 { 1033 return m_breakpoint_event; 1034 } 1035 1036 void 1037 Breakpoint::BreakpointEventData::Dump (Stream *s) const 1038 { 1039 } 1040 1041 const Breakpoint::BreakpointEventData * 1042 Breakpoint::BreakpointEventData::GetEventDataFromEvent (const Event *event) 1043 { 1044 if (event) 1045 { 1046 const EventData *event_data = event->GetData(); 1047 if (event_data && event_data->GetFlavor() == BreakpointEventData::GetFlavorString()) 1048 return static_cast <const BreakpointEventData *> (event->GetData()); 1049 } 1050 return nullptr; 1051 } 1052 1053 BreakpointEventType 1054 Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (const EventSP &event_sp) 1055 { 1056 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 1057 1058 if (data == nullptr) 1059 return eBreakpointEventTypeInvalidType; 1060 else 1061 return data->GetBreakpointEventType(); 1062 } 1063 1064 BreakpointSP 1065 Breakpoint::BreakpointEventData::GetBreakpointFromEvent (const EventSP &event_sp) 1066 { 1067 BreakpointSP bp_sp; 1068 1069 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 1070 if (data) 1071 bp_sp = data->m_new_breakpoint_sp; 1072 1073 return bp_sp; 1074 } 1075 1076 size_t 1077 Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (const EventSP &event_sp) 1078 { 1079 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 1080 if (data) 1081 return data->m_locations.GetSize(); 1082 1083 return 0; 1084 } 1085 1086 lldb::BreakpointLocationSP 1087 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t bp_loc_idx) 1088 { 1089 lldb::BreakpointLocationSP bp_loc_sp; 1090 1091 const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get()); 1092 if (data) 1093 { 1094 bp_loc_sp = data->m_locations.GetByIndex(bp_loc_idx); 1095 } 1096 1097 return bp_loc_sp; 1098 } 1099