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