brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.2 KiB · c8ca6c8 Raw
439 lines · cpp
1//===-- SBThreadPlan.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/API/SBThread.h"10#include "lldb/Utility/Instrumentation.h"11 12#include "lldb/API/SBFileSpec.h"13#include "lldb/API/SBStream.h"14#include "lldb/API/SBStructuredData.h"15#include "lldb/API/SBSymbolContext.h"16#include "lldb/Breakpoint/BreakpointLocation.h"17#include "lldb/Core/Debugger.h"18#include "lldb/Core/StructuredDataImpl.h"19#include "lldb/Interpreter/CommandInterpreter.h"20#include "lldb/Symbol/CompileUnit.h"21#include "lldb/Symbol/SymbolContext.h"22#include "lldb/Target/Process.h"23#include "lldb/Target/Queue.h"24#include "lldb/Target/ScriptedThreadPlan.h"25#include "lldb/Target/StopInfo.h"26#include "lldb/Target/SystemRuntime.h"27#include "lldb/Target/Target.h"28#include "lldb/Target/Thread.h"29#include "lldb/Target/ThreadPlan.h"30#include "lldb/Target/ThreadPlanStepInRange.h"31#include "lldb/Target/ThreadPlanStepInstruction.h"32#include "lldb/Target/ThreadPlanStepOut.h"33#include "lldb/Target/ThreadPlanStepRange.h"34#include "lldb/Utility/State.h"35#include "lldb/Utility/Stream.h"36#include "lldb/Utility/StructuredData.h"37 38#include "lldb/API/SBAddress.h"39#include "lldb/API/SBDebugger.h"40#include "lldb/API/SBEvent.h"41#include "lldb/API/SBFrame.h"42#include "lldb/API/SBProcess.h"43#include "lldb/API/SBThreadPlan.h"44#include "lldb/API/SBValue.h"45 46#include <memory>47 48using namespace lldb;49using namespace lldb_private;50 51// Constructors52SBThreadPlan::SBThreadPlan() { LLDB_INSTRUMENT_VA(this); }53 54SBThreadPlan::SBThreadPlan(const ThreadPlanSP &lldb_object_sp)55    : m_opaque_wp(lldb_object_sp) {56  LLDB_INSTRUMENT_VA(this, lldb_object_sp);57}58 59SBThreadPlan::SBThreadPlan(const SBThreadPlan &rhs)60    : m_opaque_wp(rhs.m_opaque_wp) {61  LLDB_INSTRUMENT_VA(this, rhs);62}63 64SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name) {65  LLDB_INSTRUMENT_VA(this, sb_thread, class_name);66 67  Thread *thread = sb_thread.get();68  if (thread)69    m_opaque_wp = std::make_shared<ScriptedThreadPlan>(*thread, class_name,70                                                       StructuredDataImpl());71}72 73SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name,74                           lldb::SBStructuredData &args_data) {75  LLDB_INSTRUMENT_VA(this, sb_thread, class_name, args_data);76 77  Thread *thread = sb_thread.get();78  if (thread)79    m_opaque_wp = std::make_shared<ScriptedThreadPlan>(*thread, class_name,80                                                       *args_data.m_impl_up);81}82 83// Assignment operator84 85const lldb::SBThreadPlan &SBThreadPlan::operator=(const SBThreadPlan &rhs) {86  LLDB_INSTRUMENT_VA(this, rhs);87 88  if (this != &rhs)89    m_opaque_wp = rhs.m_opaque_wp;90  return *this;91}92// Destructor93SBThreadPlan::~SBThreadPlan() = default;94 95bool SBThreadPlan::IsValid() const {96  LLDB_INSTRUMENT_VA(this);97  return this->operator bool();98}99SBThreadPlan::operator bool() const {100  LLDB_INSTRUMENT_VA(this);101 102  return static_cast<bool>(GetSP());103}104 105void SBThreadPlan::Clear() {106  LLDB_INSTRUMENT_VA(this);107 108  m_opaque_wp.reset();109}110 111lldb::StopReason SBThreadPlan::GetStopReason() {112  LLDB_INSTRUMENT_VA(this);113 114  return eStopReasonNone;115}116 117size_t SBThreadPlan::GetStopReasonDataCount() {118  LLDB_INSTRUMENT_VA(this);119 120  return 0;121}122 123uint64_t SBThreadPlan::GetStopReasonDataAtIndex(uint32_t idx) {124  LLDB_INSTRUMENT_VA(this, idx);125 126  return 0;127}128 129SBThread SBThreadPlan::GetThread() const {130  LLDB_INSTRUMENT_VA(this);131 132  ThreadPlanSP thread_plan_sp(GetSP());133  if (thread_plan_sp) {134    return SBThread(thread_plan_sp->GetThread().shared_from_this());135  } else136    return SBThread();137}138 139bool SBThreadPlan::GetDescription(lldb::SBStream &description) const {140  LLDB_INSTRUMENT_VA(this, description);141 142  ThreadPlanSP thread_plan_sp(GetSP());143  if (thread_plan_sp) {144    thread_plan_sp->GetDescription(description.get(), eDescriptionLevelFull);145  } else {146    description.Printf("Empty SBThreadPlan");147  }148  return true;149}150 151void SBThreadPlan::SetThreadPlan(const ThreadPlanSP &lldb_object_wp) {152  m_opaque_wp = lldb_object_wp;153}154 155void SBThreadPlan::SetPlanComplete(bool success) {156  LLDB_INSTRUMENT_VA(this, success);157 158  ThreadPlanSP thread_plan_sp(GetSP());159  if (thread_plan_sp)160    thread_plan_sp->SetPlanComplete(success);161}162 163bool SBThreadPlan::IsPlanComplete() {164  LLDB_INSTRUMENT_VA(this);165 166  ThreadPlanSP thread_plan_sp(GetSP());167  if (thread_plan_sp)168    return thread_plan_sp->IsPlanComplete();169  return true;170}171 172bool SBThreadPlan::IsPlanStale() {173  LLDB_INSTRUMENT_VA(this);174 175  ThreadPlanSP thread_plan_sp(GetSP());176  if (thread_plan_sp)177    return thread_plan_sp->IsPlanStale();178  return true;179}180 181bool SBThreadPlan::IsValid() {182  LLDB_INSTRUMENT_VA(this);183 184  ThreadPlanSP thread_plan_sp(GetSP());185  if (thread_plan_sp)186    return thread_plan_sp->ValidatePlan(nullptr);187  return false;188}189 190bool SBThreadPlan::GetStopOthers() {191  LLDB_INSTRUMENT_VA(this);192 193  ThreadPlanSP thread_plan_sp(GetSP());194  if (thread_plan_sp)195    return thread_plan_sp->StopOthers();196  return false;197}198 199void SBThreadPlan::SetStopOthers(bool stop_others) {200  LLDB_INSTRUMENT_VA(this, stop_others);201 202  ThreadPlanSP thread_plan_sp(GetSP());203  if (thread_plan_sp)204    thread_plan_sp->SetStopOthers(stop_others);205}206 207// This section allows an SBThreadPlan to push another of the common types of208// plans...209//210// FIXME, you should only be able to queue thread plans from inside the methods211// of a Scripted Thread Plan.  Need a way to enforce that.212 213SBThreadPlan214SBThreadPlan::QueueThreadPlanForStepOverRange(SBAddress &sb_start_address,215                                              lldb::addr_t size) {216  LLDB_INSTRUMENT_VA(this, sb_start_address, size);217 218  SBError error;219  return QueueThreadPlanForStepOverRange(sb_start_address, size, error);220}221 222SBThreadPlan SBThreadPlan::QueueThreadPlanForStepOverRange(223    SBAddress &sb_start_address, lldb::addr_t size, SBError &error) {224  LLDB_INSTRUMENT_VA(this, sb_start_address, size, error);225 226  ThreadPlanSP thread_plan_sp(GetSP());227  if (thread_plan_sp) {228    Address *start_address = sb_start_address.get();229    if (!start_address) {230      return SBThreadPlan();231    }232 233    AddressRange range(*start_address, size);234    SymbolContext sc;235    start_address->CalculateSymbolContext(&sc);236    Status plan_status;237 238    SBThreadPlan plan = SBThreadPlan(239        thread_plan_sp->GetThread().QueueThreadPlanForStepOverRange(240            false, range, sc, eAllThreads, plan_status));241 242    if (plan_status.Fail())243      error.SetErrorString(plan_status.AsCString());244    else245      plan.GetSP()->SetPrivate(true);246 247    return plan;248  }249  return SBThreadPlan();250}251 252SBThreadPlan253SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address,254                                            lldb::addr_t size) {255  LLDB_INSTRUMENT_VA(this, sb_start_address, size);256 257  SBError error;258  return QueueThreadPlanForStepInRange(sb_start_address, size, error);259}260 261SBThreadPlan262SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address,263                                            lldb::addr_t size, SBError &error) {264  LLDB_INSTRUMENT_VA(this, sb_start_address, size, error);265 266  ThreadPlanSP thread_plan_sp(GetSP());267  if (thread_plan_sp) {268    Address *start_address = sb_start_address.get();269    if (!start_address) {270      return SBThreadPlan();271    }272 273    AddressRange range(*start_address, size);274    SymbolContext sc;275    start_address->CalculateSymbolContext(&sc);276 277    Status plan_status;278    SBThreadPlan plan =279        SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepInRange(280            false, range, sc, nullptr, eAllThreads, plan_status));281 282    if (plan_status.Fail())283      error.SetErrorString(plan_status.AsCString());284    else285      plan.GetSP()->SetPrivate(true);286 287    return plan;288  }289  return SBThreadPlan();290}291 292SBThreadPlan293SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,294                                        bool first_insn) {295  LLDB_INSTRUMENT_VA(this, frame_idx_to_step_to, first_insn);296 297  SBError error;298  return QueueThreadPlanForStepOut(frame_idx_to_step_to, first_insn, error);299}300 301SBThreadPlan302SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,303                                        bool first_insn, SBError &error) {304  LLDB_INSTRUMENT_VA(this, frame_idx_to_step_to, first_insn, error);305 306  ThreadPlanSP thread_plan_sp(GetSP());307  if (thread_plan_sp) {308    SymbolContext sc;309    sc = thread_plan_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(310        lldb::eSymbolContextEverything);311 312    Status plan_status;313    SBThreadPlan plan =314        SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepOut(315            false, &sc, first_insn, false, eVoteYes, eVoteNoOpinion,316            frame_idx_to_step_to, plan_status));317 318    if (plan_status.Fail())319      error.SetErrorString(plan_status.AsCString());320    else321      plan.GetSP()->SetPrivate(true);322 323    return plan;324  }325  return SBThreadPlan();326}327 328SBThreadPlan329SBThreadPlan::QueueThreadPlanForStepSingleInstruction(bool step_over,330                                                      SBError &error) {331  LLDB_INSTRUMENT_VA(this, step_over, error);332 333  ThreadPlanSP thread_plan_sp(GetSP());334  if (thread_plan_sp) {335    Status plan_status;336    SBThreadPlan plan(337        thread_plan_sp->GetThread().QueueThreadPlanForStepSingleInstruction(338            step_over, false, false, plan_status));339 340    if (plan_status.Fail())341      error.SetErrorString(plan_status.AsCString());342    else343      plan.GetSP()->SetPrivate(true);344 345    return plan;346  }347 348  return SBThreadPlan();349}350 351SBThreadPlan352SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address) {353  LLDB_INSTRUMENT_VA(this, sb_address);354 355  SBError error;356  return QueueThreadPlanForRunToAddress(sb_address, error);357}358 359SBThreadPlan SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address,360                                                          SBError &error) {361  LLDB_INSTRUMENT_VA(this, sb_address, error);362 363  ThreadPlanSP thread_plan_sp(GetSP());364  if (thread_plan_sp) {365    Address *address = sb_address.get();366    if (!address)367      return SBThreadPlan();368 369    Status plan_status;370    SBThreadPlan plan =371        SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForRunToAddress(372            false, *address, false, plan_status));373 374    if (plan_status.Fail())375      error.SetErrorString(plan_status.AsCString());376    else377      plan.GetSP()->SetPrivate(true);378 379    return plan;380  }381  return SBThreadPlan();382}383 384SBThreadPlan385SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name) {386  LLDB_INSTRUMENT_VA(this, script_class_name);387 388  SBError error;389  return QueueThreadPlanForStepScripted(script_class_name, error);390}391 392SBThreadPlan393SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,394                                             SBError &error) {395  LLDB_INSTRUMENT_VA(this, script_class_name, error);396 397  ThreadPlanSP thread_plan_sp(GetSP());398  if (thread_plan_sp) {399    Status plan_status;400    StructuredData::ObjectSP empty_args;401    SBThreadPlan plan =402        SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepScripted(403            false, script_class_name, empty_args, false, plan_status));404 405    if (plan_status.Fail())406      error.SetErrorString(plan_status.AsCString());407    else408      plan.GetSP()->SetPrivate(true);409 410    return plan;411  }412  return SBThreadPlan();413}414 415SBThreadPlan416SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,417                                             lldb::SBStructuredData &args_data,418                                             SBError &error) {419  LLDB_INSTRUMENT_VA(this, script_class_name, args_data, error);420 421  ThreadPlanSP thread_plan_sp(GetSP());422  if (thread_plan_sp) {423    Status plan_status;424    StructuredData::ObjectSP args_obj = args_data.m_impl_up->GetObjectSP();425    SBThreadPlan plan =426        SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepScripted(427            false, script_class_name, args_obj, false, plan_status));428 429    if (plan_status.Fail())430      error.SetErrorString(plan_status.AsCString());431    else432      plan.GetSP()->SetPrivate(true);433 434    return plan;435  } else {436    return SBThreadPlan();437  }438}439