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