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