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