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