brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.0 KiB · 25285be Raw
823 lines · cpp
1//===-- BreakpointLocation.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-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Breakpoint/BreakpointLocation.h"10#include "lldb/Breakpoint/BreakpointID.h"11#include "lldb/Breakpoint/BreakpointResolver.h"12#include "lldb/Breakpoint/BreakpointResolverScripted.h"13#include "lldb/Breakpoint/StoppointCallbackContext.h"14#include "lldb/Core/Debugger.h"15#include "lldb/Core/Module.h"16#include "lldb/Expression/DiagnosticManager.h"17#include "lldb/Expression/ExpressionVariable.h"18#include "lldb/Expression/UserExpression.h"19#include "lldb/Symbol/CompileUnit.h"20#include "lldb/Symbol/Symbol.h"21#include "lldb/Symbol/TypeSystem.h"22#include "lldb/Target/Process.h"23#include "lldb/Target/Target.h"24#include "lldb/Target/Thread.h"25#include "lldb/Target/ThreadSpec.h"26#include "lldb/Utility/LLDBLog.h"27#include "lldb/Utility/Log.h"28#include "lldb/Utility/StreamString.h"29#include "lldb/ValueObject/ValueObject.h"30 31using namespace lldb;32using namespace lldb_private;33 34BreakpointLocation::BreakpointLocation(break_id_t loc_id, Breakpoint &owner,35                                       const Address &addr, lldb::tid_t tid,36                                       bool check_for_resolver)37    : m_should_resolve_indirect_functions(false), m_is_reexported(false),38      m_is_indirect(false), m_address(addr), m_owner(owner),39      m_condition_hash(0), m_loc_id(loc_id), m_hit_counter() {40  if (check_for_resolver) {41    Symbol *symbol = m_address.CalculateSymbolContextSymbol();42    if (symbol && symbol->IsIndirect()) {43      SetShouldResolveIndirectFunctions(true);44    }45  }46 47  SetThreadIDInternal(tid);48}49 50BreakpointLocation::BreakpointLocation(break_id_t loc_id, Breakpoint &owner)51    : m_should_resolve_indirect_functions(false), m_is_reexported(false),52      m_is_indirect(false), m_address(LLDB_INVALID_ADDRESS), m_owner(owner),53      m_condition_hash(0), m_loc_id(loc_id), m_hit_counter() {54  SetThreadIDInternal(LLDB_INVALID_THREAD_ID);55}56 57BreakpointLocation::~BreakpointLocation() {58  llvm::consumeError(ClearBreakpointSite());59}60 61lldb::addr_t BreakpointLocation::GetLoadAddress() const {62  return m_address.GetOpcodeLoadAddress(&m_owner.GetTarget());63}64 65const BreakpointOptions &BreakpointLocation::GetOptionsSpecifyingKind(66    BreakpointOptions::OptionKind kind) const {67  if (m_options_up && m_options_up->IsOptionSet(kind))68    return *m_options_up;69  return m_owner.GetOptions();70}71 72Address &BreakpointLocation::GetAddress() { return m_address; }73 74Breakpoint &BreakpointLocation::GetBreakpoint() { return m_owner; }75 76Target &BreakpointLocation::GetTarget() { return m_owner.GetTarget(); }77 78bool BreakpointLocation::IsEnabled() const {79  if (!m_owner.IsEnabled())80    return false;81  if (m_options_up != nullptr)82    return m_options_up->IsEnabled();83  return true;84}85 86llvm::Error BreakpointLocation::SetEnabled(bool enabled) {87  GetLocationOptions().SetEnabled(enabled);88  llvm::Error error = enabled ? ResolveBreakpointSite() : ClearBreakpointSite();89  SendBreakpointLocationChangedEvent(enabled ? eBreakpointEventTypeEnabled90                                             : eBreakpointEventTypeDisabled);91  return error;92}93 94bool BreakpointLocation::IsAutoContinue() const {95  if (m_options_up &&96      m_options_up->IsOptionSet(BreakpointOptions::eAutoContinue))97    return m_options_up->IsAutoContinue();98  return m_owner.IsAutoContinue();99}100 101void BreakpointLocation::SetAutoContinue(bool auto_continue) {102  GetLocationOptions().SetAutoContinue(auto_continue);103  SendBreakpointLocationChangedEvent(eBreakpointEventTypeAutoContinueChanged);104}105 106void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) {107  SetThreadIDInternal(thread_id);108  SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);109}110 111lldb::tid_t BreakpointLocation::GetThreadID() {112  const ThreadSpec *thread_spec =113      GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)114          .GetThreadSpecNoCreate();115  if (thread_spec)116    return thread_spec->GetTID();117  return LLDB_INVALID_THREAD_ID;118}119 120void BreakpointLocation::SetThreadIndex(uint32_t index) {121  if (index != 0)122    GetLocationOptions().GetThreadSpec()->SetIndex(index);123  else {124    // If we're resetting this to an invalid thread id, then don't make an125    // options pointer just to do that.126    if (m_options_up != nullptr)127      m_options_up->GetThreadSpec()->SetIndex(index);128  }129  SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);130}131 132uint32_t BreakpointLocation::GetThreadIndex() const {133  const ThreadSpec *thread_spec =134      GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)135          .GetThreadSpecNoCreate();136  if (thread_spec)137    return thread_spec->GetIndex();138  return 0;139}140 141void BreakpointLocation::SetThreadName(const char *thread_name) {142  if (thread_name != nullptr)143    GetLocationOptions().GetThreadSpec()->SetName(thread_name);144  else {145    // If we're resetting this to an invalid thread id, then don't make an146    // options pointer just to do that.147    if (m_options_up != nullptr)148      m_options_up->GetThreadSpec()->SetName(thread_name);149  }150  SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);151}152 153const char *BreakpointLocation::GetThreadName() const {154  const ThreadSpec *thread_spec =155      GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)156          .GetThreadSpecNoCreate();157  if (thread_spec)158    return thread_spec->GetName();159  return nullptr;160}161 162void BreakpointLocation::SetQueueName(const char *queue_name) {163  if (queue_name != nullptr)164    GetLocationOptions().GetThreadSpec()->SetQueueName(queue_name);165  else {166    // If we're resetting this to an invalid thread id, then don't make an167    // options pointer just to do that.168    if (m_options_up != nullptr)169      m_options_up->GetThreadSpec()->SetQueueName(queue_name);170  }171  SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);172}173 174const char *BreakpointLocation::GetQueueName() const {175  const ThreadSpec *thread_spec =176      GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)177          .GetThreadSpecNoCreate();178  if (thread_spec)179    return thread_spec->GetQueueName();180  return nullptr;181}182 183bool BreakpointLocation::InvokeCallback(StoppointCallbackContext *context) {184  if (m_options_up != nullptr && m_options_up->HasCallback())185    return m_options_up->InvokeCallback(context, m_owner.GetID(), GetID());186  return m_owner.InvokeCallback(context, GetID());187}188 189bool BreakpointLocation::IsCallbackSynchronous() {190  if (m_options_up != nullptr && m_options_up->HasCallback())191    return m_options_up->IsCallbackSynchronous();192  return m_owner.GetOptions().IsCallbackSynchronous();193}194 195void BreakpointLocation::SetCallback(BreakpointHitCallback callback,196                                     void *baton, bool is_synchronous) {197  // The default "Baton" class will keep a copy of "baton" and won't free or198  // delete it when it goes out of scope.199  GetLocationOptions().SetCallback(200      callback, std::make_shared<UntypedBaton>(baton), is_synchronous);201  SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);202}203 204void BreakpointLocation::SetCallback(BreakpointHitCallback callback,205                                     const BatonSP &baton_sp,206                                     bool is_synchronous) {207  GetLocationOptions().SetCallback(callback, baton_sp, is_synchronous);208  SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);209}210 211void BreakpointLocation::ClearCallback() {212  GetLocationOptions().ClearCallback();213}214 215void BreakpointLocation::SetCondition(StopCondition condition) {216  GetLocationOptions().SetCondition(std::move(condition));217  SendBreakpointLocationChangedEvent(eBreakpointEventTypeConditionChanged);218}219 220const StopCondition &BreakpointLocation::GetCondition() const {221  return GetOptionsSpecifyingKind(BreakpointOptions::eCondition).GetCondition();222}223 224bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,225                                           Status &error) {226  Log *log = GetLog(LLDBLog::Breakpoints);227 228  std::lock_guard<std::mutex> guard(m_condition_mutex);229 230  StopCondition condition = GetCondition();231 232  if (!condition) {233    m_user_expression_sp.reset();234    return false;235  }236 237  error.Clear();238 239  DiagnosticManager diagnostics;240 241  if (condition.GetHash() != m_condition_hash || !m_user_expression_sp ||242      !m_user_expression_sp->IsParseCacheable() ||243      !m_user_expression_sp->MatchesContext(exe_ctx)) {244    LanguageType language = condition.GetLanguage();245    if (language == lldb::eLanguageTypeUnknown) {246      // See if we can figure out the language from the frame, otherwise use the247      // default language:248      if (CompileUnit *comp_unit =249              m_address.CalculateSymbolContextCompileUnit())250        language = comp_unit->GetLanguage();251    }252 253    m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(254        condition.GetText(), llvm::StringRef(), SourceLanguage{language},255        Expression::eResultTypeAny, EvaluateExpressionOptions(), nullptr,256        error));257    if (error.Fail()) {258      LLDB_LOGF(log, "Error getting condition expression: %s.",259                error.AsCString());260      m_user_expression_sp.reset();261      return true;262    }263 264    if (!m_user_expression_sp->Parse(diagnostics, exe_ctx,265                                     eExecutionPolicyOnlyWhenNeeded, true,266                                     false)) {267      error = Status::FromError(268          diagnostics.GetAsError(lldb::eExpressionParseError,269                                 "Couldn't parse conditional expression:"));270 271      m_user_expression_sp.reset();272      return true;273    }274 275    m_condition_hash = condition.GetHash();276  }277 278  // We need to make sure the user sees any parse errors in their condition, so279  // we'll hook the constructor errors up to the debugger's Async I/O.280 281  ValueObjectSP result_value_sp;282 283  EvaluateExpressionOptions options;284  options.SetUnwindOnError(true);285  options.SetIgnoreBreakpoints(true);286  options.SetTryAllThreads(true);287  options.SetSuppressPersistentResult(288      true); // Don't generate a user variable for condition expressions.289 290  Status expr_error;291 292  diagnostics.Clear();293 294  ExpressionVariableSP result_variable_sp;295 296  ExpressionResults result_code = m_user_expression_sp->Execute(297      diagnostics, exe_ctx, options, m_user_expression_sp, result_variable_sp);298 299  bool ret;300 301  if (result_code == eExpressionCompleted) {302    if (!result_variable_sp) {303      error = Status::FromErrorString("Expression did not return a result");304      return false;305    }306 307    result_value_sp = result_variable_sp->GetValueObject();308 309    if (result_value_sp) {310      ret = result_value_sp->IsLogicalTrue(error);311      if (log) {312        if (error.Success()) {313          LLDB_LOGF(log, "Condition successfully evaluated, result is %s.\n",314                    ret ? "true" : "false");315        } else {316          error = Status::FromErrorString(317              "Failed to get an integer result from the expression");318          ret = false;319        }320      }321    } else {322      ret = false;323      error = Status::FromErrorString(324          "Failed to get any result from the expression");325    }326  } else {327    ret = false;328    error = Status::FromError(diagnostics.GetAsError(329        lldb::eExpressionParseError, "Couldn't execute expression:"));330  }331 332  return ret;333}334 335uint32_t BreakpointLocation::GetIgnoreCount() const {336  return GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)337      .GetIgnoreCount();338}339 340void BreakpointLocation::SetIgnoreCount(uint32_t n) {341  GetLocationOptions().SetIgnoreCount(n);342  SendBreakpointLocationChangedEvent(eBreakpointEventTypeIgnoreChanged);343}344 345void BreakpointLocation::DecrementIgnoreCount() {346  if (m_options_up != nullptr) {347    uint32_t loc_ignore = m_options_up->GetIgnoreCount();348    if (loc_ignore != 0)349      m_options_up->SetIgnoreCount(loc_ignore - 1);350  }351}352 353bool BreakpointLocation::IgnoreCountShouldStop() {354  uint32_t owner_ignore = GetBreakpoint().GetIgnoreCount();355  uint32_t loc_ignore = 0;356  if (m_options_up != nullptr)357    loc_ignore = m_options_up->GetIgnoreCount();358 359  if (loc_ignore != 0 || owner_ignore != 0) {360    m_owner.DecrementIgnoreCount();361    DecrementIgnoreCount(); // Have to decrement our owners' ignore count,362                            // since it won't get a chance to.363    return false;364  }365  return true;366}367 368BreakpointOptions &BreakpointLocation::GetLocationOptions() {369  // If we make the copy we don't copy the callbacks because that is370  // potentially expensive and we don't want to do that for the simple case371  // where someone is just disabling the location.372  if (m_options_up == nullptr)373    m_options_up = std::make_unique<BreakpointOptions>(false);374 375  return *m_options_up;376}377 378bool BreakpointLocation::ValidForThisThread(Thread &thread) {379  return thread.MatchesSpec(380      GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)381          .GetThreadSpecNoCreate());382}383 384BreakpointLocationSP385BreakpointLocation::WasHit(StoppointCallbackContext *context) {386  // Only the BreakpointResolverScripted provides WasHit.387  BreakpointResolverSP resolver_sp = GetBreakpoint().GetResolver();388  BreakpointResolverScripted *scripted =389      llvm::dyn_cast<BreakpointResolverScripted>(resolver_sp.get());390  if (!scripted)391    return shared_from_this();392 393  StackFrameSP frame_sp = context->exe_ctx_ref.GetFrameSP();394  if (!frame_sp)395    return shared_from_this();396 397  BreakpointLocationSP return_loc_sp =398      scripted->WasHit(frame_sp, shared_from_this());399  // If this is a facade location, then we won't have bumped its hit count400  // while processing the original location hit.  Do so here.  We don't need401  // to bump the breakpoint's hit count, however, since hitting the real402  // location would have already done that.403  // Also we have to check the enabled state here, since we would never have404  // gotten here with a real location...405  if (return_loc_sp && return_loc_sp->IsFacade()) {406    if (return_loc_sp->IsEnabled())407      return_loc_sp->m_hit_counter.Increment();408    else409      return {};410  }411  return return_loc_sp;412}413 414// RETURNS - true if we should stop at this breakpoint, false if we415// should continue.  Note, we don't check the thread spec for the breakpoint416// here, since if the breakpoint is not for this thread, then the event won't417// even get reported, so the check is redundant.418 419bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context,420                                    lldb::BreakpointLocationSP &facade_loc_sp) {421  bool should_stop = true;422  Log *log = GetLog(LLDBLog::Breakpoints);423 424  // Do this first, if a location is disabled, it shouldn't increment its hit425  // count.426  if (!IsEnabled())427    return false;428 429  // Next check WasHit:430  BreakpointLocationSP loc_hit_sp = WasHit(context);431 432  if (!loc_hit_sp) {433    // We bump the hit counts in StopInfoBreakpoint::ShouldStopSynchronous,434    // before we call into each location's ShouldStop.  So we need to undo435    // that here.436    UndoBumpHitCount();437    return false;438  }439 440  // If the location hit was not us, it was a facade location, in which case441  // we should use the facade location's callbacks, etc.  Those will all be442  // run in the asynchronous phase, so for now we just have to record the fact443  // that we should treat this as a facade hit.  This is strictly an out444  // parameter, so clear it if this isn't a facade hit.445  if (loc_hit_sp.get() != this)446    facade_loc_sp = loc_hit_sp;447  else448    facade_loc_sp.reset();449 450  // We only run synchronous callbacks in ShouldStop:451  context->is_synchronous = true;452  should_stop = InvokeCallback(context);453 454  if (log) {455    StreamString s;456    GetDescription(&s, lldb::eDescriptionLevelVerbose);457    LLDB_LOGF(log, "Hit breakpoint location: %s, %s.\n", s.GetData(),458              should_stop ? "stopping" : "continuing");459    if (facade_loc_sp) {460      s.Clear();461      facade_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);462      LLDB_LOGF(log, "Attributing to facade location: %s.\n", s.GetData());463    }464  }465 466  return should_stop;467}468 469void BreakpointLocation::BumpHitCount() {470  if (IsEnabled()) {471    // Step our hit count, and also step the hit count of the owner.472    m_hit_counter.Increment();473    m_owner.m_hit_counter.Increment();474  }475}476 477void BreakpointLocation::UndoBumpHitCount() {478  if (IsEnabled()) {479    // Step our hit count, and also step the hit count of the owner.480    m_hit_counter.Decrement();481    m_owner.m_hit_counter.Decrement();482  }483}484 485bool BreakpointLocation::IsResolved() const {486 487  bool has_site = m_bp_site_sp.get() != nullptr;488  // Facade locations are currently always considered resolved.489  return has_site || IsFacade();490}491 492lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const {493  return m_bp_site_sp;494}495 496llvm::Error BreakpointLocation::ResolveBreakpointSite() {497  // This might be a facade location, which doesn't have an address.498  // In that case, don't attempt to make a site.499  if (m_bp_site_sp || IsFacade())500    return llvm::Error::success();501 502  Process *process = m_owner.GetTarget().GetProcessSP().get();503  if (process == nullptr)504    return llvm::createStringError("no process");505 506  lldb::break_id_t new_id =507      process->CreateBreakpointSite(shared_from_this(), m_owner.IsHardware());508 509  if (new_id == LLDB_INVALID_BREAK_ID)510    return llvm::createStringError(511        llvm::formatv("Failed to add breakpoint site at {0:x}",512                      m_address.GetOpcodeLoadAddress(&m_owner.GetTarget())));513 514  if (!IsResolved())515    return llvm::createStringError(516        "breakpoint site created but location is still unresolved");517 518  return llvm::Error::success();519}520 521bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) {522  m_bp_site_sp = bp_site_sp;523  SendBreakpointLocationChangedEvent(eBreakpointEventTypeLocationsResolved);524  return true;525}526 527llvm::Error BreakpointLocation::ClearBreakpointSite() {528  if (!m_bp_site_sp) {529    // This might be a Facade Location, which don't have sites or addresses530    if (IsFacade())531      return llvm::Error::success();532    return llvm::createStringError("no breakpoint site to clear");533  }534 535  // If the process exists, get it to remove the owner, it will remove the536  // physical implementation of the breakpoint as well if there are no more537  // owners.  Otherwise just remove this owner.538  if (ProcessSP process_sp = m_owner.GetTarget().GetProcessSP())539    process_sp->RemoveConstituentFromBreakpointSite(GetBreakpoint().GetID(),540                                                    GetID(), m_bp_site_sp);541  else542    m_bp_site_sp->RemoveConstituent(GetBreakpoint().GetID(), GetID());543 544  m_bp_site_sp.reset();545  return llvm::Error::success();546}547 548void BreakpointLocation::GetDescription(Stream *s,549                                        lldb::DescriptionLevel level) {550  SymbolContext sc;551 552  // If this is a scripted breakpoint, give it a chance to describe its553  // locations:554  std::optional<std::string> scripted_opt;555  BreakpointResolverSP resolver_sp = GetBreakpoint().GetResolver();556  BreakpointResolverScripted *scripted =557      llvm::dyn_cast<BreakpointResolverScripted>(resolver_sp.get());558  if (scripted)559    scripted_opt = scripted->GetLocationDescription(shared_from_this(), level);560 561  bool is_scripted_desc = scripted_opt.has_value();562 563  // If the description level is "initial" then the breakpoint is printing out564  // our initial state, and we should let it decide how it wants to print our565  // label.566  if (level != eDescriptionLevelInitial) {567    s->Indent();568    BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());569  }570 571  if (level == lldb::eDescriptionLevelBrief)572    return;573 574  if (level != eDescriptionLevelInitial)575    s->PutCString(": ");576 577  if (level == lldb::eDescriptionLevelVerbose)578    s->IndentMore();579 580  if (is_scripted_desc) {581    s->PutCString(scripted_opt->c_str());582  } else if (m_address.IsSectionOffset()) {583    m_address.CalculateSymbolContext(&sc);584 585    if (level == lldb::eDescriptionLevelFull ||586        level == eDescriptionLevelInitial) {587      if (IsReExported())588        s->PutCString("re-exported target = ");589      else590        s->PutCString("where = ");591 592      // If there's a preferred line entry for printing, use that.593      bool show_function_info = true;594      if (auto preferred = GetPreferredLineEntry()) {595        sc.line_entry = *preferred;596        // FIXME: We're going to get the function name wrong when the preferred597        // line entry is not the lowest one.  For now, just leave the function598        // out in this case, but we really should also figure out how to easily599        // fake the function name here.600        show_function_info = false;601      }602      sc.DumpStopContext(s, m_owner.GetTarget().GetProcessSP().get(), m_address,603                         false, true, false, show_function_info,604                         show_function_info, show_function_info);605    } else {606      if (sc.module_sp) {607        s->EOL();608        s->Indent("module = ");609        sc.module_sp->GetFileSpec().Dump(s->AsRawOstream());610      }611 612      if (sc.comp_unit != nullptr) {613        s->EOL();614        s->Indent("compile unit = ");615        sc.comp_unit->GetPrimaryFile().GetFilename().Dump(s);616 617        if (sc.function != nullptr) {618          s->EOL();619          s->Indent("function = ");620          s->PutCString(sc.function->GetName().AsCString("<unknown>"));621          if (ConstString mangled_name =622                  sc.function->GetMangled().GetMangledName()) {623            s->EOL();624            s->Indent("mangled function = ");625            s->PutCString(mangled_name.AsCString());626          }627        }628 629        if (sc.line_entry.line > 0) {630          s->EOL();631          s->Indent("location = ");632          if (auto preferred = GetPreferredLineEntry())633            preferred->DumpStopContext(s, true);634          else635            sc.line_entry.DumpStopContext(s, true);636        }637 638      } else {639        // If we don't have a comp unit, see if we have a symbol we can print.640        if (sc.symbol) {641          s->EOL();642          if (IsReExported())643            s->Indent("re-exported target = ");644          else645            s->Indent("symbol = ");646          s->PutCString(sc.symbol->GetName().AsCString("<unknown>"));647        }648      }649    }650  }651 652  if (level == lldb::eDescriptionLevelVerbose) {653    s->EOL();654    s->Indent();655  }656 657  if (!is_scripted_desc) {658    if (m_address.IsSectionOffset() &&659        (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))660      s->Printf(", ");661    s->Printf("address = ");662 663    ExecutionContextScope *exe_scope = nullptr;664    Target *target = &m_owner.GetTarget();665    if (target)666      exe_scope = target->GetProcessSP().get();667    if (exe_scope == nullptr)668      exe_scope = target;669 670    if (level == eDescriptionLevelInitial)671      m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,672                     Address::DumpStyleFileAddress);673    else674      m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,675                     Address::DumpStyleModuleWithFileAddress);676 677    if (IsIndirect() && m_bp_site_sp) {678      Address resolved_address;679      resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);680      Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();681      if (resolved_symbol) {682        if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)683          s->Printf(", ");684        else if (level == lldb::eDescriptionLevelVerbose) {685          s->EOL();686          s->Indent();687        }688        s->Printf("indirect target = %s",689                  resolved_symbol->GetName().GetCString());690      }691    }692  }693 694  // FIXME: scripted breakpoint are currently always resolved.  Does this seem695  // right? If they don't add any scripted locations, we shouldn't consider them696  // resolved.697  bool is_resolved = is_scripted_desc || IsResolved();698  // A scripted breakpoint might be resolved but not have a site.  Be sure to699  // check for that.700  bool is_hardware = !is_scripted_desc && IsResolved() && m_bp_site_sp &&701                     m_bp_site_sp->IsHardware();702 703  if (level == lldb::eDescriptionLevelVerbose) {704    s->EOL();705    s->Indent();706    s->Printf("resolved = %s\n", is_resolved ? "true" : "false");707    s->Indent();708    s->Printf("hardware = %s\n", is_hardware ? "true" : "false");709    s->Indent();710    s->Printf("hit count = %-4u\n", GetHitCount());711 712    if (m_options_up) {713      s->Indent();714      m_options_up->GetDescription(s, level);715      s->EOL();716    }717    s->IndentLess();718  } else if (level != eDescriptionLevelInitial) {719    s->Printf(", %sresolved, %shit count = %u ", (is_resolved ? "" : "un"),720              (is_hardware ? "hardware, " : ""), GetHitCount());721    if (m_options_up) {722      m_options_up->GetDescription(s, level);723    }724  }725}726 727void BreakpointLocation::Dump(Stream *s) const {728  if (s == nullptr)729    return;730 731  bool is_resolved = IsResolved();732  bool is_hardware = is_resolved && m_bp_site_sp->IsHardware();733 734  lldb::tid_t tid = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)735                        .GetThreadSpecNoCreate()736                        ->GetTID();737  s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64738            "  load addr = 0x%8.8" PRIx64 "  state = %s  type = %s breakpoint  "739            "hit_count = %-4u  ignore_count = %-4u",740            GetID(), tid,741            (uint64_t)m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()),742            (m_options_up ? m_options_up->IsEnabled() : m_owner.IsEnabled())743                ? "enabled "744                : "disabled",745            is_hardware ? "hardware" : "software", GetHitCount(),746            GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)747                .GetIgnoreCount());748}749 750void BreakpointLocation::SendBreakpointLocationChangedEvent(751    lldb::BreakpointEventType eventKind) {752  if (!m_owner.IsInternal()) {753    auto data_sp = std::make_shared<Breakpoint::BreakpointEventData>(754        eventKind, m_owner.shared_from_this());755    data_sp->GetBreakpointLocationCollection().Add(shared_from_this());756    m_owner.GetTarget().NotifyBreakpointChanged(m_owner, data_sp);757  }758}759 760std::optional<uint32_t> BreakpointLocation::GetSuggestedStackFrameIndex() {761  auto preferred_opt = GetPreferredLineEntry();762  if (!preferred_opt)763    return {};764  LineEntry preferred = *preferred_opt;765  SymbolContext sc;766  if (!m_address.CalculateSymbolContext(&sc))767    return {};768  // Don't return anything special if frame 0 is the preferred line entry.769  // We not really telling the stack frame list to do anything special in that770  // case.771  if (!LineEntry::Compare(sc.line_entry, preferred))772    return {};773 774  if (!sc.block)775    return {};776 777  // Blocks have their line info in Declaration form, so make one here:778  Declaration preferred_decl(preferred.GetFile(), preferred.line,779                             preferred.column);780 781  uint32_t depth = 0;782  Block *inlined_block = sc.block->GetContainingInlinedBlock();783  while (inlined_block) {784    // If we've moved to a block that this isn't the start of, that's not785    // our inlining info or call site, so we can stop here.786    Address start_address;787    if (!inlined_block->GetStartAddress(start_address) ||788        start_address != m_address)789      return {};790 791    const InlineFunctionInfo *info = inlined_block->GetInlinedFunctionInfo();792    if (info) {793      if (preferred_decl == info->GetDeclaration())794        return depth;795      if (preferred_decl == info->GetCallSite())796        return depth + 1;797    }798    inlined_block = inlined_block->GetInlinedParent();799    depth++;800  }801  return {};802}803 804void BreakpointLocation::SwapLocation(BreakpointLocationSP swap_from) {805  m_address = swap_from->m_address;806  m_should_resolve_indirect_functions =807      swap_from->m_should_resolve_indirect_functions;808  m_is_reexported = swap_from->m_is_reexported;809  m_is_indirect = swap_from->m_is_indirect;810  m_user_expression_sp.reset();811}812 813void BreakpointLocation::SetThreadIDInternal(lldb::tid_t thread_id) {814  if (thread_id != LLDB_INVALID_THREAD_ID) {815    GetLocationOptions().SetThreadID(thread_id);816  } else {817    // If we're resetting this to an invalid thread id, then don't make an818    // options pointer just to do that.819    if (m_options_up != nullptr)820      m_options_up->SetThreadID(thread_id);821  }822}823