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