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