brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.5 KiB · f05e1fa Raw
294 lines · cpp
1//===-- ThreadPlan.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/Target/ThreadPlan.h"10#include "lldb/Core/Debugger.h"11#include "lldb/Target/Process.h"12#include "lldb/Target/RegisterContext.h"13#include "lldb/Target/Target.h"14#include "lldb/Target/Thread.h"15#include "lldb/Utility/LLDBLog.h"16#include "lldb/Utility/Log.h"17#include "lldb/Utility/State.h"18 19using namespace lldb;20using namespace lldb_private;21 22// ThreadPlan constructor23ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread,24                       Vote report_stop_vote, Vote report_run_vote)25    : m_process(*thread.GetProcess().get()), m_tid(thread.GetID()),26      m_report_stop_vote(report_stop_vote), m_report_run_vote(report_run_vote),27      m_takes_iteration_count(false), m_could_not_resolve_hw_bp(false),28      m_thread(&thread), m_kind(kind), m_name(name), m_plan_complete_mutex(),29      m_cached_plan_explains_stop(eLazyBoolCalculate), m_plan_complete(false),30      m_plan_private(false), m_okay_to_discard(true),31      m_is_controlling_plan(false), m_plan_succeeded(true) {32  SetID(GetNextID());33}34 35// Destructor36ThreadPlan::~ThreadPlan() = default;37 38Target &ThreadPlan::GetTarget() { return m_process.GetTarget(); }39 40const Target &ThreadPlan::GetTarget() const { return m_process.GetTarget(); }41 42Thread &ThreadPlan::GetThread() {43  if (m_thread)44    return *m_thread;45 46  ThreadSP thread_sp = m_process.GetThreadList().FindThreadByID(m_tid);47  m_thread = thread_sp.get();48  return *m_thread;49}50 51bool ThreadPlan::PlanExplainsStop(Event *event_ptr) {52  if (m_cached_plan_explains_stop == eLazyBoolCalculate) {53    bool actual_value = DoPlanExplainsStop(event_ptr);54    CachePlanExplainsStop(actual_value);55    return actual_value;56  } else {57    return m_cached_plan_explains_stop == eLazyBoolYes;58  }59}60 61bool ThreadPlan::IsPlanComplete() {62  std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);63  return m_plan_complete;64}65 66void ThreadPlan::SetPlanComplete(bool success) {67  std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);68  m_plan_complete = true;69  m_plan_succeeded = success;70}71 72bool ThreadPlan::MischiefManaged() {73  std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);74  // Mark the plan is complete, but don't override the success flag.75  m_plan_complete = true;76  return true;77}78 79Vote ThreadPlan::ShouldReportStop(Event *event_ptr) {80  Log *log = GetLog(LLDBLog::Step);81 82  if (m_report_stop_vote == eVoteNoOpinion) {83    ThreadPlan *prev_plan = GetPreviousPlan();84    if (prev_plan) {85      Vote prev_vote = prev_plan->ShouldReportStop(event_ptr);86      LLDB_LOG(log, "returning previous thread plan vote: {0}", prev_vote);87      return prev_vote;88    }89  }90  LLDB_LOG(log, "Returning vote: {0}", m_report_stop_vote);91  return m_report_stop_vote;92}93 94Vote ThreadPlan::ShouldReportRun(Event *event_ptr) {95  if (m_report_run_vote == eVoteNoOpinion) {96    ThreadPlan *prev_plan = GetPreviousPlan();97    if (prev_plan)98      return prev_plan->ShouldReportRun(event_ptr);99  }100  return m_report_run_vote;101}102 103void ThreadPlan::ClearThreadCache() { m_thread = nullptr; }104 105bool ThreadPlan::StopOthers() {106  ThreadPlan *prev_plan;107  prev_plan = GetPreviousPlan();108  return (prev_plan == nullptr) ? false : prev_plan->StopOthers();109}110 111void ThreadPlan::SetStopOthers(bool new_value) {112  // SetStopOthers doesn't work up the hierarchy.  You have to set the explicit113  // ThreadPlan you want to affect.114}115 116bool ThreadPlan::WillResume(StateType resume_state, bool current_plan) {117  m_cached_plan_explains_stop = eLazyBoolCalculate;118 119  if (current_plan) {120    Log *log = GetLog(LLDBLog::Step);121 122    if (log) {123      RegisterContext *reg_ctx = GetThread().GetRegisterContext().get();124      assert(reg_ctx);125      addr_t pc = reg_ctx->GetPC();126      addr_t sp = reg_ctx->GetSP();127      addr_t fp = reg_ctx->GetFP();128      LLDB_LOGF(129          log,130          "%s Thread #%u (0x%p): tid = 0x%4.4" PRIx64 ", pc = 0x%8.8" PRIx64131          ", sp = 0x%8.8" PRIx64 ", fp = 0x%8.8" PRIx64 ", "132          "plan = '%s', state = %s, stop others = %d",133          __FUNCTION__, GetThread().GetIndexID(),134          static_cast<void *>(&GetThread()), m_tid, static_cast<uint64_t>(pc),135          static_cast<uint64_t>(sp), static_cast<uint64_t>(fp), m_name.c_str(),136          StateAsCString(resume_state), StopOthers());137    }138  }139  bool success = DoWillResume(resume_state, current_plan);140  ClearThreadCache(); // We don't cache the thread pointer over resumes.  This141                      // Thread might go away, and another Thread represent142                      // the same underlying object on a later stop.143  return success;144}145 146lldb::user_id_t ThreadPlan::GetNextID() {147  static uint32_t g_nextPlanID = 0;148  return ++g_nextPlanID;149}150 151void ThreadPlan::DidPush() {}152 153void ThreadPlan::DidPop() {}154 155bool ThreadPlan::OkayToDiscard() {156  return IsControllingPlan() ? m_okay_to_discard : true;157}158 159lldb::StateType ThreadPlan::RunState() {160  if (m_tracer_sp && m_tracer_sp->TracingEnabled())161    return eStateStepping;162  else163    return GetPlanRunState();164}165 166bool ThreadPlan::IsUsuallyUnexplainedStopReason(lldb::StopReason reason) {167  switch (reason) {168  case eStopReasonWatchpoint:169  case eStopReasonSignal:170  case eStopReasonException:171  case eStopReasonExec:172  case eStopReasonThreadExiting:173  case eStopReasonInstrumentation:174  case eStopReasonFork:175  case eStopReasonVFork:176  case eStopReasonVForkDone:177  case eStopReasonInterrupt:178    return true;179  default:180    return false;181  }182}183 184// ThreadPlanNull185 186ThreadPlanNull::ThreadPlanNull(Thread &thread)187    : ThreadPlan(ThreadPlan::eKindNull, "Null Thread Plan", thread,188                 eVoteNoOpinion, eVoteNoOpinion) {}189 190ThreadPlanNull::~ThreadPlanNull() = default;191 192void ThreadPlanNull::GetDescription(Stream *s, lldb::DescriptionLevel level) {193  s->PutCString("Null thread plan - thread has been destroyed.");194}195 196bool ThreadPlanNull::ValidatePlan(Stream *error) {197#ifdef LLDB_CONFIGURATION_DEBUG198  fprintf(stderr,199          "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64200          ", ptid = 0x%" PRIx64 ")",201          LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());202#else203  Log *log = GetLog(LLDBLog::Thread);204  if (log)205    log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64206               ", ptid = 0x%" PRIx64 ")",207               LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());208#endif209  return true;210}211 212bool ThreadPlanNull::ShouldStop(Event *event_ptr) {213#ifdef LLDB_CONFIGURATION_DEBUG214  fprintf(stderr,215          "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64216          ", ptid = 0x%" PRIx64 ")",217          LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());218#else219  Log *log = GetLog(LLDBLog::Thread);220  if (log)221    log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64222               ", ptid = 0x%" PRIx64 ")",223               LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());224#endif225  return true;226}227 228bool ThreadPlanNull::WillStop() {229#ifdef LLDB_CONFIGURATION_DEBUG230  fprintf(stderr,231          "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64232          ", ptid = 0x%" PRIx64 ")",233          LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());234#else235  Log *log = GetLog(LLDBLog::Thread);236  if (log)237    log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64238               ", ptid = 0x%" PRIx64 ")",239               LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());240#endif241  return true;242}243 244bool ThreadPlanNull::DoPlanExplainsStop(Event *event_ptr) {245#ifdef LLDB_CONFIGURATION_DEBUG246  fprintf(stderr,247          "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64248          ", ptid = 0x%" PRIx64 ")",249          LLVM_PRETTY_FUNCTION, GetThread().GetID(), GetThread().GetProtocolID());250#else251  Log *log = GetLog(LLDBLog::Thread);252  if (log)253    log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64254               ", ptid = 0x%" PRIx64 ")",255               LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());256#endif257  return true;258}259 260// The null plan is never done.261bool ThreadPlanNull::MischiefManaged() {262// The null plan is never done.263#ifdef LLDB_CONFIGURATION_DEBUG264  fprintf(stderr,265          "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64266          ", ptid = 0x%" PRIx64 ")",267          LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());268#else269  Log *log = GetLog(LLDBLog::Thread);270  if (log)271    log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64272               ", ptid = 0x%" PRIx64 ")",273               LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());274#endif275  return false;276}277 278lldb::StateType ThreadPlanNull::GetPlanRunState() {279// Not sure what to return here.  This is a dead thread.280#ifdef LLDB_CONFIGURATION_DEBUG281  fprintf(stderr,282          "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64283          ", ptid = 0x%" PRIx64 ")",284          LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());285#else286  Log *log = GetLog(LLDBLog::Thread);287  if (log)288    log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64289               ", ptid = 0x%" PRIx64 ")",290               LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());291#endif292  return eStateRunning;293}294