//===-- Thread.cpp --------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Target/Thread.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Host/Host.h"
#include "lldb/Interpreter/Interfaces/ScriptedFrameInterface.h"
#include "lldb/Interpreter/Interfaces/ScriptedFrameProviderInterface.h"
#include "lldb/Interpreter/OptionValueFileSpecList.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/Property.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/ScriptedThreadPlan.h"
#include "lldb/Target/StackFrameRecognizer.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/SystemRuntime.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/ThreadPlanBase.h"
#include "lldb/Target/ThreadPlanCallFunction.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
#include "lldb/Target/ThreadPlanStack.h"
#include "lldb/Target/ThreadPlanStepInRange.h"
#include "lldb/Target/ThreadPlanStepInstruction.h"
#include "lldb/Target/ThreadPlanStepOut.h"
#include "lldb/Target/ThreadPlanStepOverBreakpoint.h"
#include "lldb/Target/ThreadPlanStepOverRange.h"
#include "lldb/Target/ThreadPlanStepThrough.h"
#include "lldb/Target/ThreadPlanStepUntil.h"
#include "lldb/Target/ThreadSpec.h"
#include "lldb/Target/UnwindLLDB.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/ScriptedMetadata.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectConstResult.h"
#include "lldb/lldb-enumerations.h"

#include "llvm/Support/MathExtras.h"

#include <memory>
#include <optional>

using namespace lldb;
using namespace lldb_private;

ThreadProperties &Thread::GetGlobalProperties() {
  // NOTE: intentional leak so we don't crash if global destructor chain gets
  // called as other threads still use the result of this function
  static ThreadProperties *g_settings_ptr = new ThreadProperties(true);
  return *g_settings_ptr;
}

#define LLDB_PROPERTIES_thread
#include "TargetProperties.inc"

enum {
#define LLDB_PROPERTIES_thread
#include "TargetPropertiesEnum.inc"
};

class ThreadOptionValueProperties
    : public Cloneable<ThreadOptionValueProperties, OptionValueProperties> {
public:
  ThreadOptionValueProperties(llvm::StringRef name) : Cloneable(name) {}

  const Property *
  GetPropertyAtIndex(size_t idx,
                     const ExecutionContext *exe_ctx) const override {
    // When getting the value for a key from the thread options, we will always
    // try and grab the setting from the current thread if there is one. Else
    // we just use the one from this instance.
    if (exe_ctx) {
      Thread *thread = exe_ctx->GetThreadPtr();
      if (thread) {
        ThreadOptionValueProperties *instance_properties =
            static_cast<ThreadOptionValueProperties *>(
                thread->GetValueProperties().get());
        if (this != instance_properties)
          return instance_properties->ProtectedGetPropertyAtIndex(idx);
      }
    }
    return ProtectedGetPropertyAtIndex(idx);
  }
};

ThreadProperties::ThreadProperties(bool is_global) : Properties() {
  if (is_global) {
    m_collection_sp = std::make_shared<ThreadOptionValueProperties>("thread");
    m_collection_sp->Initialize(g_thread_properties_def);
  } else
    m_collection_sp =
        OptionValueProperties::CreateLocalCopy(Thread::GetGlobalProperties());
}

ThreadProperties::~ThreadProperties() = default;

const RegularExpression *ThreadProperties::GetSymbolsToAvoidRegexp() {
  const uint32_t idx = ePropertyStepAvoidRegex;
  return GetPropertyAtIndexAs<const RegularExpression *>(idx);
}

FileSpecList ThreadProperties::GetLibrariesToAvoid() const {
  const uint32_t idx = ePropertyStepAvoidLibraries;
  return GetPropertyAtIndexAs<FileSpecList>(idx, {});
}

bool ThreadProperties::GetTraceEnabledState() const {
  const uint32_t idx = ePropertyEnableThreadTrace;
  return GetPropertyAtIndexAs<bool>(
      idx, g_thread_properties[idx].default_uint_value != 0);
}

bool ThreadProperties::GetStepInAvoidsNoDebug() const {
  const uint32_t idx = ePropertyStepInAvoidsNoDebug;
  return GetPropertyAtIndexAs<bool>(
      idx, g_thread_properties[idx].default_uint_value != 0);
}

bool ThreadProperties::GetStepOutAvoidsNoDebug() const {
  const uint32_t idx = ePropertyStepOutAvoidsNoDebug;
  return GetPropertyAtIndexAs<bool>(
      idx, g_thread_properties[idx].default_uint_value != 0);
}

uint64_t ThreadProperties::GetMaxBacktraceDepth() const {
  const uint32_t idx = ePropertyMaxBacktraceDepth;
  return GetPropertyAtIndexAs<uint64_t>(
      idx, g_thread_properties[idx].default_uint_value);
}

uint64_t ThreadProperties::GetSingleThreadPlanTimeout() const {
  const uint32_t idx = ePropertySingleThreadPlanTimeout;
  return GetPropertyAtIndexAs<uint64_t>(
      idx, g_thread_properties[idx].default_uint_value);
}

// Thread Event Data

llvm::StringRef Thread::ThreadEventData::GetFlavorString() {
  return "Thread::ThreadEventData";
}

Thread::ThreadEventData::ThreadEventData(const lldb::ThreadSP thread_sp)
    : m_thread_sp(thread_sp), m_stack_id() {}

Thread::ThreadEventData::ThreadEventData(const lldb::ThreadSP thread_sp,
                                         const StackID &stack_id)
    : m_thread_sp(thread_sp), m_stack_id(stack_id) {}

Thread::ThreadEventData::ThreadEventData() : m_thread_sp(), m_stack_id() {}

Thread::ThreadEventData::~ThreadEventData() = default;

void Thread::ThreadEventData::Dump(Stream *s) const {}

const Thread::ThreadEventData *
Thread::ThreadEventData::GetEventDataFromEvent(const Event *event_ptr) {
  if (event_ptr) {
    const EventData *event_data = event_ptr->GetData();
    if (event_data &&
        event_data->GetFlavor() == ThreadEventData::GetFlavorString())
      return static_cast<const ThreadEventData *>(event_ptr->GetData());
  }
  return nullptr;
}

ThreadSP Thread::ThreadEventData::GetThreadFromEvent(const Event *event_ptr) {
  ThreadSP thread_sp;
  const ThreadEventData *event_data = GetEventDataFromEvent(event_ptr);
  if (event_data)
    thread_sp = event_data->GetThread();
  return thread_sp;
}

StackID Thread::ThreadEventData::GetStackIDFromEvent(const Event *event_ptr) {
  StackID stack_id;
  const ThreadEventData *event_data = GetEventDataFromEvent(event_ptr);
  if (event_data)
    stack_id = event_data->GetStackID();
  return stack_id;
}

StackFrameSP
Thread::ThreadEventData::GetStackFrameFromEvent(const Event *event_ptr) {
  const ThreadEventData *event_data = GetEventDataFromEvent(event_ptr);
  StackFrameSP frame_sp;
  if (event_data) {
    ThreadSP thread_sp = event_data->GetThread();
    if (thread_sp) {
      frame_sp = thread_sp->GetStackFrameList()->GetFrameWithStackID(
          event_data->GetStackID());
    }
  }
  return frame_sp;
}

// Thread class

llvm::StringRef Thread::GetStaticBroadcasterClass() {
  static constexpr llvm::StringLiteral class_name("lldb.thread");
  return class_name;
}

Thread::Thread(Process &process, lldb::tid_t tid, bool use_invalid_index_id)
    : ThreadProperties(false), UserID(tid),
      Broadcaster(process.GetTarget().GetDebugger().GetBroadcasterManager(),
                  Thread::GetStaticBroadcasterClass().str()),
      m_process_wp(process.shared_from_this()), m_stop_info_sp(),
      m_stop_info_stop_id(0), m_stop_info_override_stop_id(0),
      m_should_run_before_public_stop(false),
      m_stopped_at_unexecuted_bp(LLDB_INVALID_ADDRESS),
      m_index_id(use_invalid_index_id ? LLDB_INVALID_INDEX32
                                      : process.GetNextThreadIndexID(tid)),
      m_reg_context_sp(), m_state(eStateUnloaded), m_state_mutex(),
      m_frame_mutex(), m_curr_frames_sp(), m_prev_frames_sp(),
      m_prev_framezero_pc(), m_resume_signal(LLDB_INVALID_SIGNAL_NUMBER),
      m_resume_state(eStateRunning), m_temporary_resume_state(eStateRunning),
      m_unwinder_up(), m_destroy_called(false),
      m_override_should_notify(eLazyBoolCalculate),
      m_extended_info_fetched(false), m_extended_info() {
  Log *log = GetLog(LLDBLog::Object);
  LLDB_LOGF(log, "%p Thread::Thread(tid = 0x%4.4" PRIx64 ")",
            static_cast<void *>(this), GetID());

  CheckInWithManager();
}

Thread::~Thread() {
  Log *log = GetLog(LLDBLog::Object);
  LLDB_LOGF(log, "%p Thread::~Thread(tid = 0x%4.4" PRIx64 ")",
            static_cast<void *>(this), GetID());
  /// If you hit this assert, it means your derived class forgot to call
  /// DestroyThread in its destructor.
  assert(m_destroy_called);
}

void Thread::DestroyThread() {
  m_destroy_called = true;
  m_stop_info_sp.reset();
  m_reg_context_sp.reset();
  m_unwinder_up.reset();
  std::lock_guard<std::recursive_mutex> guard(m_frame_mutex);
  m_curr_frames_sp.reset();
  m_prev_frames_sp.reset();
  m_unwinder_frames_sp.reset();
  m_frame_providers.clear();
  m_provider_chain_ids.clear();
  m_frame_lists_by_id.clear();
  {
    std::lock_guard<std::mutex> pguard(m_provider_frames_mutex);
    m_active_frame_providers_by_thread.clear();
  }
  m_prev_framezero_pc.reset();
}

void Thread::BroadcastSelectedFrameChange(StackID &new_frame_id) {
  if (EventTypeHasListeners(eBroadcastBitSelectedFrameChanged)) {
    auto data_sp =
        std::make_shared<ThreadEventData>(shared_from_this(), new_frame_id);
    BroadcastEvent(eBroadcastBitSelectedFrameChanged, data_sp);
  }
}

lldb::StackFrameSP
Thread::GetSelectedFrame(SelectMostRelevant select_most_relevant) {
  StackFrameListSP stack_frame_list_sp(GetStackFrameList());
  StackFrameSP frame_sp = stack_frame_list_sp->GetFrameAtIndex(
      stack_frame_list_sp->GetSelectedFrameIndex(select_most_relevant));
  FrameSelectedCallback(frame_sp.get());
  return frame_sp;
}

uint32_t Thread::SetSelectedFrame(lldb_private::StackFrame *frame,
                                  bool broadcast) {
  uint32_t ret_value = GetStackFrameList()->SetSelectedFrame(frame);
  if (broadcast)
    BroadcastSelectedFrameChange(frame->GetStackID());
  FrameSelectedCallback(frame);
  return ret_value;
}

bool Thread::SetSelectedFrameByIndex(uint32_t frame_idx, bool broadcast) {
  StackFrameSP frame_sp(GetStackFrameList()->GetFrameAtIndex(frame_idx));
  if (frame_sp) {
    GetStackFrameList()->SetSelectedFrame(frame_sp.get());
    if (broadcast)
      BroadcastSelectedFrameChange(frame_sp->GetStackID());
    FrameSelectedCallback(frame_sp.get());
    return true;
  } else
    return false;
}

bool Thread::SetSelectedFrameByIndexNoisily(uint32_t frame_idx,
                                            Stream &output_stream) {
  const bool broadcast = true;
  bool success = SetSelectedFrameByIndex(frame_idx, broadcast);
  if (success) {
    StackFrameSP frame_sp = GetSelectedFrame(DoNoSelectMostRelevantFrame);
    if (frame_sp) {
      bool already_shown = false;
      SymbolContext frame_sc(
          frame_sp->GetSymbolContext(eSymbolContextLineEntry));
      const Debugger &debugger = GetProcess()->GetTarget().GetDebugger();
      if (debugger.GetUseExternalEditor() && frame_sc.line_entry.GetFile() &&
          frame_sc.line_entry.line != 0) {
        if (llvm::Error e = Host::OpenFileInExternalEditor(
                debugger.GetExternalEditor(), frame_sc.line_entry.GetFile(),
                frame_sc.line_entry.line)) {
          LLDB_LOG_ERROR(GetLog(LLDBLog::Host), std::move(e),
                         "OpenFileInExternalEditor failed: {0}");
        } else {
          already_shown = true;
        }
      }

      bool show_frame_info = true;
      bool show_source = !already_shown;
      FrameSelectedCallback(frame_sp.get());
      return frame_sp->GetStatus(output_stream, show_frame_info, show_source);
    }
    return false;
  } else
    return false;
}

void Thread::FrameSelectedCallback(StackFrame *frame) {
  if (!frame)
    return;

  if (frame->HasDebugInformation() &&
      (GetProcess()->GetWarningsOptimization() ||
       GetProcess()->GetWarningsUnsupportedLanguage())) {
    SymbolContext sc =
        frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextModule);
    GetProcess()->PrintWarningOptimization(sc);
    GetProcess()->PrintWarningUnsupportedLanguage(sc);
  }
}

lldb::StopInfoSP Thread::GetStopInfo() {
  if (m_destroy_called)
    return m_stop_info_sp;

  ThreadPlanSP completed_plan_sp(GetCompletedPlan());
  ProcessSP process_sp(GetProcess());
  const uint32_t stop_id = process_sp ? process_sp->GetStopID() : UINT32_MAX;

  // Here we select the stop info according to priorirty: - m_stop_info_sp (if
  // not trace) - preset value - completed plan stop info - new value with plan
  // from completed plan stack - m_stop_info_sp (trace stop reason is OK now) -
  // ask GetPrivateStopInfo to set stop info

  bool have_valid_stop_info = m_stop_info_sp &&
      m_stop_info_sp ->IsValid() &&
      m_stop_info_stop_id == stop_id;
  bool have_valid_completed_plan = completed_plan_sp && completed_plan_sp->PlanSucceeded();
  bool plan_failed = completed_plan_sp && !completed_plan_sp->PlanSucceeded();
  bool plan_overrides_trace =
    have_valid_stop_info && have_valid_completed_plan
    && (m_stop_info_sp->GetStopReason() == eStopReasonTrace);

  if (have_valid_stop_info && !plan_overrides_trace && !plan_failed) {
    return m_stop_info_sp;
  } else if (completed_plan_sp) {
    return StopInfo::CreateStopReasonWithPlan(
        completed_plan_sp, GetReturnValueObject(), GetExpressionVariable());
  } else {
    GetPrivateStopInfo();
    return m_stop_info_sp;
  }
}

void Thread::CalculatePublicStopInfo() {
  ResetStopInfo();
  SetStopInfo(GetStopInfo());
}

lldb::StopInfoSP Thread::GetPrivateStopInfo(bool calculate) {
  if (!calculate)
    return m_stop_info_sp;

  if (m_destroy_called)
    return m_stop_info_sp;

  ProcessSP process_sp(GetProcess());
  if (process_sp) {
    const uint32_t process_stop_id = process_sp->GetStopID();
    if (m_stop_info_stop_id != process_stop_id) {
      // We preserve the old stop info for a variety of reasons:
      // 1) Someone has already updated it by the time we get here
      // 2) We didn't get to execute the breakpoint instruction we stopped at
      // 3) This is a virtual step so we didn't actually run
      // 4) If this thread wasn't allowed to run the last time round.
      if (m_stop_info_sp) {
        if (m_stop_info_sp->IsValid() || IsStillAtLastBreakpointHit() ||
            GetCurrentPlan()->IsVirtualStep()
            || GetTemporaryResumeState() == eStateSuspended)
          SetStopInfo(m_stop_info_sp);
        else
          m_stop_info_sp.reset();
      }

      if (!m_stop_info_sp) {
        if (!CalculateStopInfo())
          SetStopInfo(StopInfoSP());
      }
    }

    // The stop info can be manually set by calling Thread::SetStopInfo() prior
    // to this function ever getting called, so we can't rely on
    // "m_stop_info_stop_id != process_stop_id" as the condition for the if
    // statement below, we must also check the stop info to see if we need to
    // override it. See the header documentation in
    // Architecture::OverrideStopInfo() for more information on the stop
    // info override callback.
    if (m_stop_info_override_stop_id != process_stop_id) {
      m_stop_info_override_stop_id = process_stop_id;
      if (m_stop_info_sp) {
        if (const Architecture *arch =
                process_sp->GetTarget().GetArchitecturePlugin())
          arch->OverrideStopInfo(*this);
      }
    }
  }

  // If we were resuming the process and it was interrupted,
  // return no stop reason.  This thread would like to resume.
  if (m_stop_info_sp && m_stop_info_sp->WasContinueInterrupted(*this))
    return {};

  return m_stop_info_sp;
}

lldb::StopReason Thread::GetStopReason() {
  lldb::StopInfoSP stop_info_sp(GetStopInfo());
  if (stop_info_sp)
    return stop_info_sp->GetStopReason();
  return eStopReasonNone;
}

bool Thread::StopInfoIsUpToDate() const {
  ProcessSP process_sp(GetProcess());
  if (process_sp)
    return m_stop_info_stop_id == process_sp->GetStopID();
  else
    return true; // Process is no longer around so stop info is always up to
                 // date...
}

void Thread::ResetStopInfo() {
  if (m_stop_info_sp) {
    m_stop_info_sp.reset();
  }
}

void Thread::SetStopInfo(const lldb::StopInfoSP &stop_info_sp) {
  m_stop_info_sp = stop_info_sp;
  if (m_stop_info_sp) {
    m_stop_info_sp->MakeStopInfoValid();
    // If we are overriding the ShouldReportStop, do that here:
    if (m_override_should_notify != eLazyBoolCalculate)
      m_stop_info_sp->OverrideShouldNotify(m_override_should_notify ==
                                           eLazyBoolYes);
  }

  ProcessSP process_sp(GetProcess());
  if (process_sp)
    m_stop_info_stop_id = process_sp->GetStopID();
  else
    m_stop_info_stop_id = UINT32_MAX;
  Log *log = GetLog(LLDBLog::Thread);
  LLDB_LOGF(log, "%p: tid = 0x%" PRIx64 ": stop info = %s (stop_id = %u)",
            static_cast<void *>(this), GetID(),
            stop_info_sp ? stop_info_sp->GetDescription() : "<NULL>",
            m_stop_info_stop_id);
}

void Thread::SetShouldReportStop(Vote vote) {
  if (vote == eVoteNoOpinion)
    return;
  else {
    m_override_should_notify = (vote == eVoteYes ? eLazyBoolYes : eLazyBoolNo);
    if (m_stop_info_sp)
      m_stop_info_sp->OverrideShouldNotify(m_override_should_notify ==
                                           eLazyBoolYes);
  }
}

void Thread::SetStopInfoToNothing() {
  // Note, we can't just NULL out the private reason, or the native thread
  // implementation will try to go calculate it again.  For now, just set it to
  // a Unix Signal with an invalid signal number.
  SetStopInfo(
      StopInfo::CreateStopReasonWithSignal(*this, LLDB_INVALID_SIGNAL_NUMBER));
}

bool Thread::ThreadStoppedForAReason() { return (bool)GetPrivateStopInfo(); }

bool Thread::CheckpointThreadState(ThreadStateCheckpoint &saved_state) {
  saved_state.register_backup_sp.reset();
  lldb::StackFrameSP frame_sp(GetStackFrameAtIndex(0));
  if (frame_sp) {
    lldb::RegisterCheckpointSP reg_checkpoint_sp(
        new RegisterCheckpoint(RegisterCheckpoint::Reason::eExpression));
    if (reg_checkpoint_sp) {
      lldb::RegisterContextSP reg_ctx_sp(frame_sp->GetRegisterContext());
      if (reg_ctx_sp && reg_ctx_sp->ReadAllRegisterValues(*reg_checkpoint_sp))
        saved_state.register_backup_sp = reg_checkpoint_sp;
    }
  }
  if (!saved_state.register_backup_sp)
    return false;

  saved_state.stop_info_sp = GetStopInfo();
  ProcessSP process_sp(GetProcess());
  if (process_sp)
    saved_state.orig_stop_id = process_sp->GetStopID();
  saved_state.current_inlined_depth = GetCurrentInlinedDepth();
  saved_state.m_completed_plan_checkpoint =
      GetPlans().CheckpointCompletedPlans();
  saved_state.stopped_at_unexecuted_bp = m_stopped_at_unexecuted_bp;

  return true;
}

bool Thread::RestoreRegisterStateFromCheckpoint(
    ThreadStateCheckpoint &saved_state) {
  if (saved_state.register_backup_sp) {
    lldb::StackFrameSP frame_sp(GetStackFrameAtIndex(0));
    if (frame_sp) {
      lldb::RegisterContextSP reg_ctx_sp(frame_sp->GetRegisterContext());
      if (reg_ctx_sp) {
        bool ret =
            reg_ctx_sp->WriteAllRegisterValues(*saved_state.register_backup_sp);

        // Clear out all stack frames as our world just changed.
        ClearStackFrames();
        reg_ctx_sp->InvalidateIfNeeded(true);
        if (m_unwinder_up)
          m_unwinder_up->Clear();
        return ret;
      }
    }
  }
  return false;
}

void Thread::RestoreThreadStateFromCheckpoint(
    ThreadStateCheckpoint &saved_state) {
  if (saved_state.stop_info_sp)
    saved_state.stop_info_sp->MakeStopInfoValid();
  SetStopInfo(saved_state.stop_info_sp);
  GetStackFrameList()->SetCurrentInlinedDepth(
      saved_state.current_inlined_depth);
  GetPlans().RestoreCompletedPlanCheckpoint(
      saved_state.m_completed_plan_checkpoint);
  m_stopped_at_unexecuted_bp = saved_state.stopped_at_unexecuted_bp;
}

StateType Thread::GetState() const {
  // If any other threads access this we will need a mutex for it
  std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
  return m_state;
}

void Thread::SetState(StateType state) {
  std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
  m_state = state;
}

std::string Thread::GetStopDescription() {
  StackFrameSP frame_sp = GetStackFrameAtIndex(0);

  if (!frame_sp)
    return GetStopDescriptionRaw();

  auto recognized_frame_sp = frame_sp->GetRecognizedFrame();

  if (!recognized_frame_sp)
    return GetStopDescriptionRaw();

  std::string recognized_stop_description =
      recognized_frame_sp->GetStopDescription();

  if (!recognized_stop_description.empty())
    return recognized_stop_description;

  return GetStopDescriptionRaw();
}

std::string Thread::GetStopDescriptionRaw() {
  StopInfoSP stop_info_sp = GetStopInfo();
  std::string raw_stop_description;
  if (stop_info_sp && stop_info_sp->IsValid()) {
    raw_stop_description = stop_info_sp->GetDescription();
    assert((!raw_stop_description.empty() ||
            stop_info_sp->GetStopReason() == eStopReasonNone) &&
           "StopInfo returned an empty description.");
  }
  return raw_stop_description;
}

void Thread::WillStop() {
  ThreadPlan *current_plan = GetCurrentPlan();

  // FIXME: I may decide to disallow threads with no plans.  In which
  // case this should go to an assert.

  if (!current_plan)
    return;

  current_plan->WillStop();
}

bool Thread::SetupToStepOverBreakpointIfNeeded(RunDirection direction) {
  if (GetResumeState() != eStateSuspended) {
    // First check whether this thread is going to "actually" resume at all.
    // For instance, if we're stepping from one level to the next of an
    // virtual inlined call stack, we just change the inlined call stack index
    // without actually running this thread.  In that case, for this thread we
    // shouldn't push a step over breakpoint plan or do that work.
    if (GetCurrentPlan()->IsVirtualStep())
      return false;

    // If we're at a breakpoint push the step-over breakpoint plan.  Do this
    // before telling the current plan it will resume, since we might change
    // what the current plan is.

    lldb::RegisterContextSP reg_ctx_sp(GetRegisterContext());
    ProcessSP process_sp(GetProcess());
    if (reg_ctx_sp && process_sp && direction == eRunForward) {
      const addr_t thread_pc = reg_ctx_sp->GetPC();
      BreakpointSiteSP bp_site_sp =
          process_sp->GetBreakpointSiteList().FindByAddress(thread_pc);
      // If we're at a BreakpointSite which we have either
      //   1. already triggered/hit, or
      //   2. the Breakpoint was added while stopped, or the pc was moved
      //      to this BreakpointSite
      // Step past the breakpoint before resuming.
      // If we stopped at a breakpoint instruction/BreakpointSite location
      // without hitting it, and we're still at that same address on
      // resuming, then we want to hit the BreakpointSite when we resume.
      if (bp_site_sp && m_stopped_at_unexecuted_bp != thread_pc) {
        // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the
        // target may not require anything special to step over a breakpoint.

        ThreadPlan *cur_plan = GetCurrentPlan();

        bool push_step_over_bp_plan = false;
        if (cur_plan->GetKind() == ThreadPlan::eKindStepOverBreakpoint) {
          ThreadPlanStepOverBreakpoint *bp_plan =
              (ThreadPlanStepOverBreakpoint *)cur_plan;
          if (bp_plan->GetBreakpointLoadAddress() != thread_pc)
            push_step_over_bp_plan = true;
        } else
          push_step_over_bp_plan = true;

        if (push_step_over_bp_plan) {
          ThreadPlanSP step_bp_plan_sp(new ThreadPlanStepOverBreakpoint(*this));
          if (step_bp_plan_sp) {
            step_bp_plan_sp->SetPrivate(true);

            if (GetCurrentPlan()->RunState() != eStateStepping) {
              ThreadPlanStepOverBreakpoint *step_bp_plan =
                  static_cast<ThreadPlanStepOverBreakpoint *>(
                      step_bp_plan_sp.get());
              step_bp_plan->SetAutoContinue(true);
            }
            QueueThreadPlan(step_bp_plan_sp, false);
            return true;
          }
        }
      }
    }
  }
  return false;
}

bool Thread::ShouldResume(StateType resume_state) {
  // At this point clear the completed plan stack.
  GetPlans().WillResume();
  m_override_should_notify = eLazyBoolCalculate;

  StateType prev_resume_state = GetTemporaryResumeState();

  SetTemporaryResumeState(resume_state);

  lldb::ThreadSP backing_thread_sp(GetBackingThread());
  if (backing_thread_sp)
    backing_thread_sp->SetTemporaryResumeState(resume_state);

  // Make sure m_stop_info_sp is valid.  Don't do this for threads we suspended
  // in the previous run.
  if (prev_resume_state != eStateSuspended)
    GetPrivateStopInfo();

  // This is a little dubious, but we are trying to limit how often we actually
  // fetch stop info from the target, 'cause that slows down single stepping.
  // So assume that if we got to the point where we're about to resume, and we
  // haven't yet had to fetch the stop reason, then it doesn't need to know
  // about the fact that we are resuming...
  const uint32_t process_stop_id = GetProcess()->GetStopID();
  if (m_stop_info_stop_id == process_stop_id &&
      (m_stop_info_sp && m_stop_info_sp->IsValid())) {
    if (StopInfoSP stop_info_sp = GetPrivateStopInfo())
      stop_info_sp->WillResume(resume_state);
  }

  // Tell all the plans that we are about to resume in case they need to clear
  // any state. We distinguish between the plan on the top of the stack and the
  // lower plans in case a plan needs to do any special business before it
  // runs.

  bool need_to_resume = false;
  ThreadPlan *plan_ptr = GetCurrentPlan();
  if (plan_ptr) {
    need_to_resume = plan_ptr->WillResume(resume_state, true);

    while ((plan_ptr = GetPreviousPlan(plan_ptr)) != nullptr) {
      plan_ptr->WillResume(resume_state, false);
    }

    // If the WillResume for the plan says we are faking a resume, then it will
    // have set an appropriate stop info. In that case, don't reset it here.

    if (need_to_resume && resume_state != eStateSuspended) {
      m_stop_info_sp.reset();
    }
  }

  if (need_to_resume) {
    ClearStackFrames();

    // Only reset m_stopped_at_unexecuted_bp if the thread is actually being
    // resumed. Otherwise, the state of a suspended thread may not be restored
    // correctly at the next stop. For example, this could happen if the thread
    // is suspended by ThreadPlanStepOverBreakpoint in another thread, which
    // temporarily disables the breakpoint that the suspended thread has reached
    // but not yet executed.
    if (resume_state != eStateSuspended)
      m_stopped_at_unexecuted_bp = LLDB_INVALID_ADDRESS;

    // Let Thread subclasses do any special work they need to prior to resuming
    WillResume(resume_state);
  }

  return need_to_resume;
}

void Thread::DidResume() {
  SetResumeSignal(LLDB_INVALID_SIGNAL_NUMBER);
  // This will get recomputed each time when we stop.
  SetShouldRunBeforePublicStop(false);
}

void Thread::DidStop() { SetState(eStateStopped); }

bool Thread::ShouldStop(Event *event_ptr) {
  ThreadPlan *current_plan = GetCurrentPlan();

  bool should_stop = true;

  Log *log = GetLog(LLDBLog::Step);

  if (GetResumeState() == eStateSuspended) {
    LLDB_LOGF(log,
              "Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
              ", should_stop = 0 (ignore since thread was suspended)",
              __FUNCTION__, GetID(), GetProtocolID());
    return false;
  }

  if (GetTemporaryResumeState() == eStateSuspended) {
    LLDB_LOGF(log,
              "Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
              ", should_stop = 0 (ignore since thread was suspended)",
              __FUNCTION__, GetID(), GetProtocolID());
    return false;
  }

  // Based on the current thread plan and process stop info, check if this
  // thread caused the process to stop. NOTE: this must take place before the
  // plan is moved from the current plan stack to the completed plan stack.
  if (!ThreadStoppedForAReason()) {
    LLDB_LOGF(log,
              "Thread::%s for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
              ", pc = 0x%16.16" PRIx64
              ", should_stop = 0 (ignore since no stop reason)",
              __FUNCTION__, GetID(), GetProtocolID(),
              GetRegisterContext() ? GetRegisterContext()->GetPC()
                                   : LLDB_INVALID_ADDRESS);
    return false;
  }

  // Clear the "must run me before stop" if it was set:
  SetShouldRunBeforePublicStop(false);

  if (log) {
    LLDB_LOGF(log,
              "Thread::%s(%p) for tid = 0x%4.4" PRIx64 " 0x%4.4" PRIx64
              ", pc = 0x%16.16" PRIx64,
              __FUNCTION__, static_cast<void *>(this), GetID(), GetProtocolID(),
              GetRegisterContext() ? GetRegisterContext()->GetPC()
                                   : LLDB_INVALID_ADDRESS);
    LLDB_LOGF(log, "^^^^^^^^ Thread::ShouldStop Begin ^^^^^^^^");
    StreamString s;
    s.IndentMore();
    GetProcess()->DumpThreadPlansForTID(
        s, GetID(), eDescriptionLevelVerbose, true /* internal */,
        false /* condense_trivial */, true /* skip_unreported */);
    LLDB_LOGF(log, "Plan stack initial state:\n%s", s.GetData());
  }

  // The top most plan always gets to do the trace log...
  current_plan->DoTraceLog();

  // First query the stop info's ShouldStopSynchronous.  This handles
  // "synchronous" stop reasons, for example the breakpoint command on internal
  // breakpoints.  If a synchronous stop reason says we should not stop, then
  // we don't have to do any more work on this stop.
  StopInfoSP private_stop_info(GetPrivateStopInfo());
  if (private_stop_info &&
      !private_stop_info->ShouldStopSynchronous(event_ptr)) {
    LLDB_LOGF(log, "StopInfo::ShouldStop async callback says we should not "
                   "stop, returning ShouldStop of false.");
    return false;
  }

  // If we've already been restarted, don't query the plans since the state
  // they would examine is not current.
  if (Process::ProcessEventData::GetRestartedFromEvent(event_ptr))
    return false;

  // Before the plans see the state of the world, calculate the current inlined
  // depth.
  GetStackFrameList()->CalculateCurrentInlinedDepth();

  // If the base plan doesn't understand why we stopped, then we have to find a
  // plan that does. If that plan is still working, then we don't need to do
  // any more work.  If the plan that explains the stop is done, then we should
  // pop all the plans below it, and pop it, and then let the plans above it
  // decide whether they still need to do more work.

  bool done_processing_current_plan = false;
  if (!current_plan->PlanExplainsStop(event_ptr)) {
    if (current_plan->TracerExplainsStop()) {
      done_processing_current_plan = true;
      should_stop = false;
    } else {
      // Leaf plan that does not explain the stop should be popped.
      // The plan should be push itself later again before resuming to stay
      // as leaf.
      if (current_plan->IsLeafPlan())
        PopPlan();

      // If the current plan doesn't explain the stop, then find one that does
      // and let it handle the situation.
      ThreadPlan *plan_ptr = current_plan;
      while ((plan_ptr = GetPreviousPlan(plan_ptr)) != nullptr) {
        if (plan_ptr->PlanExplainsStop(event_ptr)) {
          LLDB_LOGF(log, "Plan %s explains stop.", plan_ptr->GetName());

          should_stop = plan_ptr->ShouldStop(event_ptr);

          // plan_ptr explains the stop, next check whether plan_ptr is done,
          // if so, then we should take it and all the plans below it off the
          // stack.

          if (plan_ptr->MischiefManaged()) {
            // We're going to pop the plans up to and including the plan that
            // explains the stop.
            ThreadPlan *prev_plan_ptr = GetPreviousPlan(plan_ptr);

            do {
              if (should_stop)
                current_plan->WillStop();
              PopPlan();
            } while ((current_plan = GetCurrentPlan()) != prev_plan_ptr);
            // Now, if the responsible plan was not "Okay to discard" then
            // we're done, otherwise we forward this to the next plan in the
            // stack below.
            done_processing_current_plan =
                (plan_ptr->IsControllingPlan() && !plan_ptr->OkayToDiscard());
          } else {
            bool should_force_run = plan_ptr->ShouldRunBeforePublicStop();
            if (should_force_run) {
              SetShouldRunBeforePublicStop(true);
              should_stop = false;
            }
            done_processing_current_plan = true;
          }
          break;
        }
      }
    }
  }

  if (!done_processing_current_plan) {
    bool override_stop = false;

    // We're starting from the base plan, so just let it decide;
    if (current_plan->IsBasePlan()) {
      should_stop = current_plan->ShouldStop(event_ptr);
      LLDB_LOGF(log, "Base plan says should stop: %i.", should_stop);
    } else {
      // Otherwise, don't let the base plan override what the other plans say
      // to do, since presumably if there were other plans they would know what
      // to do...
      while (true) {
        if (current_plan->IsBasePlan())
          break;

        should_stop = current_plan->ShouldStop(event_ptr);
        LLDB_LOGF(log, "Plan %s should stop: %d.", current_plan->GetName(),
                  should_stop);
        if (current_plan->MischiefManaged()) {
          if (should_stop)
            current_plan->WillStop();

          if (current_plan->ShouldAutoContinue(event_ptr)) {
            override_stop = true;
            LLDB_LOGF(log, "Plan %s auto-continue: true.",
                      current_plan->GetName());
          }

          // If a Controlling Plan wants to stop, we let it. Otherwise, see if
          // the plan's parent wants to stop.

          PopPlan();
          if (should_stop && current_plan->IsControllingPlan() &&
              !current_plan->OkayToDiscard()) {
            break;
          }

          current_plan = GetCurrentPlan();
          if (current_plan == nullptr) {
            break;
          }
        } else {
          break;
        }
      }
    }

    if (override_stop)
      should_stop = false;
  }

  // One other potential problem is that we set up a controlling plan, then stop
  // in before it is complete - for instance by hitting a breakpoint during a
  // step-over - then do some step/finish/etc operations that wind up past the
  // end point condition of the initial plan.  We don't want to strand the
  // original plan on the stack, This code clears stale plans off the stack.

  if (should_stop) {
    ThreadPlan *plan_ptr = GetCurrentPlan();

    // Discard the stale plans and all plans below them in the stack, plus move
    // the completed plans to the completed plan stack
    while (!plan_ptr->IsBasePlan()) {
      bool stale = plan_ptr->IsPlanStale();
      ThreadPlan *examined_plan = plan_ptr;
      plan_ptr = GetPreviousPlan(examined_plan);

      if (stale) {
        LLDB_LOGF(
            log,
            "Plan %s being discarded in cleanup, it says it is already done.",
            examined_plan->GetName());
        while (GetCurrentPlan() != examined_plan) {
          DiscardPlan();
        }
        if (examined_plan->IsPlanComplete()) {
          // plan is complete but does not explain the stop (example: step to a
          // line with breakpoint), let us move the plan to
          // completed_plan_stack anyway
          PopPlan();
        } else
          DiscardPlan();
      }
    }
  }

  if (log) {
    StreamString s;
    s.IndentMore();
    GetProcess()->DumpThreadPlansForTID(
        s, GetID(), eDescriptionLevelVerbose, true /* internal */,
        false /* condense_trivial */, true /* skip_unreported */);
    LLDB_LOGF(log, "Plan stack final state:\n%s", s.GetData());
    LLDB_LOGF(log, "vvvvvvvv Thread::ShouldStop End (returning %i) vvvvvvvv",
              should_stop);
  }
  return should_stop;
}

Vote Thread::ShouldReportStop(Event *event_ptr) {
  StateType thread_state = GetResumeState();
  StateType temp_thread_state = GetTemporaryResumeState();

  Log *log = GetLog(LLDBLog::Step);

  if (thread_state == eStateSuspended || thread_state == eStateInvalid) {
    LLDB_LOGF(log,
              "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
              ": returning vote %i (state was suspended or invalid)",
              GetID(), eVoteNoOpinion);
    return eVoteNoOpinion;
  }

  if (temp_thread_state == eStateSuspended ||
      temp_thread_state == eStateInvalid) {
    LLDB_LOGF(log,
              "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
              ": returning vote %i (temporary state was suspended or invalid)",
              GetID(), eVoteNoOpinion);
    return eVoteNoOpinion;
  }

  if (!ThreadStoppedForAReason()) {
    LLDB_LOGF(log,
              "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
              ": returning vote %i (thread didn't stop for a reason.)",
              GetID(), eVoteNoOpinion);
    return eVoteNoOpinion;
  }

  if (GetPlans().AnyCompletedPlans()) {
    // Pass skip_private = false to GetCompletedPlan, since we want to ask
    // the last plan, regardless of whether it is private or not.
    LLDB_LOGF(log,
              "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
              ": returning vote for complete stack's back plan",
              GetID());
    return GetPlans().GetCompletedPlan(false)->ShouldReportStop(event_ptr);
  } else {
    Vote thread_vote = eVoteNoOpinion;
    ThreadPlan *plan_ptr = GetCurrentPlan();
    while (true) {
      if (plan_ptr->PlanExplainsStop(event_ptr)) {
        thread_vote = plan_ptr->ShouldReportStop(event_ptr);
        break;
      }
      if (plan_ptr->IsBasePlan())
        break;
      else
        plan_ptr = GetPreviousPlan(plan_ptr);
    }
    LLDB_LOGF(log,
              "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64
              ": returning vote %i for current plan",
              GetID(), thread_vote);

    return thread_vote;
  }
}

Vote Thread::ShouldReportRun(Event *event_ptr) {
  StateType thread_state = GetResumeState();

  if (thread_state == eStateSuspended || thread_state == eStateInvalid) {
    return eVoteNoOpinion;
  }

  Log *log = GetLog(LLDBLog::Step);
  if (GetPlans().AnyCompletedPlans()) {
    // Pass skip_private = false to GetCompletedPlan, since we want to ask
    // the last plan, regardless of whether it is private or not.
    ThreadPlanSP plan = GetPlans().GetCompletedPlan(/*skip_private=*/false);

    LLDB_LOGF(log,
              "Current Plan for thread %d(%p) (0x%4.4" PRIx64
              ", %s): %s being asked whether we should report run.",
              GetIndexID(), static_cast<void *>(this), GetID(),
              StateAsCString(GetTemporaryResumeState()), plan->GetName());

    return plan->ShouldReportRun(event_ptr);
  } else {
    LLDB_LOGF(log,
              "Current Plan for thread %d(%p) (0x%4.4" PRIx64
              ", %s): %s being asked whether we should report run.",
              GetIndexID(), static_cast<void *>(this), GetID(),
              StateAsCString(GetTemporaryResumeState()),
              GetCurrentPlan()->GetName());

    return GetCurrentPlan()->ShouldReportRun(event_ptr);
  }
}

bool Thread::MatchesSpec(const ThreadSpec *spec) {
  return (spec == nullptr) ? true : spec->ThreadPassesBasicTests(*this);
}

ThreadPlanStack &Thread::GetPlans() const {
  ThreadPlanStack *plans = GetProcess()->FindThreadPlans(GetID());
  if (plans)
    return *plans;

  // History threads don't have a thread plan, but they do ask get asked to
  // describe themselves, which usually involves pulling out the stop reason.
  // That in turn will check for a completed plan on the ThreadPlanStack.
  // Instead of special-casing at that point, we return a Stack with a
  // ThreadPlanNull as its base plan.  That will give the right answers to the
  // queries GetDescription makes, and only assert if you try to run the thread.
  if (!m_null_plan_stack_up)
    m_null_plan_stack_up = std::make_unique<ThreadPlanStack>(*this, true);
  return *m_null_plan_stack_up;
}

void Thread::PushPlan(ThreadPlanSP thread_plan_sp) {
  assert(thread_plan_sp && "Don't push an empty thread plan.");

  Log *log = GetLog(LLDBLog::Step);
  if (log) {
    StreamString s;
    thread_plan_sp->GetDescription(&s, lldb::eDescriptionLevelFull);
    LLDB_LOGF(log, "Thread::PushPlan(0x%p): \"%s\", tid = 0x%4.4" PRIx64 ".",
              static_cast<void *>(this), s.GetData(),
              thread_plan_sp->GetThread().GetID());
  }

  GetPlans().PushPlan(std::move(thread_plan_sp));
}

void Thread::PopPlan() {
  Log *log = GetLog(LLDBLog::Step);
  ThreadPlanSP popped_plan_sp = GetPlans().PopPlan();
  LLDB_LOGF(log, "Popping plan: \"%s\", tid = 0x%4.4" PRIx64 ".",
            popped_plan_sp->GetName(), popped_plan_sp->GetThread().GetID());
}

void Thread::DiscardPlan() {
  Log *log = GetLog(LLDBLog::Step);
  ThreadPlanSP discarded_plan_sp = GetPlans().DiscardPlan();

  LLDB_LOGF(log, "Discarding plan: \"%s\", tid = 0x%4.4" PRIx64 ".",
            discarded_plan_sp->GetName(),
            discarded_plan_sp->GetThread().GetID());
}

void Thread::AutoCompleteThreadPlans(CompletionRequest &request) const {
  const ThreadPlanStack &plans = GetPlans();
  if (!plans.AnyPlans())
    return;

  // Iterate from the second plan (index: 1) to skip the base plan.
  ThreadPlanSP p;
  uint32_t i = 1;
  while ((p = plans.GetPlanByIndex(i, false))) {
    StreamString strm;
    p->GetDescription(&strm, eDescriptionLevelInitial);
    request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
    i++;
  }
}

ThreadPlan *Thread::GetCurrentPlan() const {
  return GetPlans().GetCurrentPlan().get();
}

ThreadPlanSP Thread::GetCompletedPlan() const {
  return GetPlans().GetCompletedPlan();
}

ValueObjectSP Thread::GetReturnValueObject() const {
  return GetPlans().GetReturnValueObject();
}

ExpressionVariableSP Thread::GetExpressionVariable() const {
  return GetPlans().GetExpressionVariable();
}

bool Thread::IsThreadPlanDone(ThreadPlan *plan) const {
  return GetPlans().IsPlanDone(plan);
}

bool Thread::WasThreadPlanDiscarded(ThreadPlan *plan) const {
  return GetPlans().WasPlanDiscarded(plan);
}

bool Thread::CompletedPlanOverridesBreakpoint() const {
  return GetPlans().AnyCompletedPlans();
}

ThreadPlan *Thread::GetPreviousPlan(ThreadPlan *current_plan) const{
  return GetPlans().GetPreviousPlan(current_plan);
}

Status Thread::QueueThreadPlan(ThreadPlanSP &thread_plan_sp,
                               bool abort_other_plans) {
  Status status;
  StreamString s;
  if (!thread_plan_sp->ValidatePlan(&s)) {
    DiscardThreadPlansUpToPlan(thread_plan_sp);
    thread_plan_sp.reset();
    return Status(s.GetString().str());
  }

  if (abort_other_plans)
    DiscardThreadPlans(true);

  PushPlan(thread_plan_sp);

  // This seems a little funny, but I don't want to have to split up the
  // constructor and the DidPush in the scripted plan, that seems annoying.
  // That means the constructor has to be in DidPush. So I have to validate the
  // plan AFTER pushing it, and then take it off again...
  if (!thread_plan_sp->ValidatePlan(&s)) {
    DiscardThreadPlansUpToPlan(thread_plan_sp);
    thread_plan_sp.reset();
    return Status(s.GetString().str());
  }

  return status;
}

bool Thread::DiscardUserThreadPlansUpToIndex(uint32_t plan_index) {
  // Count the user thread plans from the back end to get the number of the one
  // we want to discard:

  ThreadPlan *up_to_plan_ptr = GetPlans().GetPlanByIndex(plan_index).get();
  if (up_to_plan_ptr == nullptr)
    return false;

  DiscardThreadPlansUpToPlan(up_to_plan_ptr);
  return true;
}

void Thread::DiscardThreadPlansUpToPlan(lldb::ThreadPlanSP &up_to_plan_sp) {
  DiscardThreadPlansUpToPlan(up_to_plan_sp.get());
}

void Thread::DiscardThreadPlansUpToPlan(ThreadPlan *up_to_plan_ptr) {
  Log *log = GetLog(LLDBLog::Step);
  LLDB_LOGF(log,
            "Discarding thread plans for thread tid = 0x%4.4" PRIx64
            ", up to %p",
            GetID(), static_cast<void *>(up_to_plan_ptr));
  GetPlans().DiscardPlansUpToPlan(up_to_plan_ptr);
}

void Thread::DiscardThreadPlans(bool force) {
  Log *log = GetLog(LLDBLog::Step);
  LLDB_LOGF(log,
            "Discarding thread plans for thread (tid = 0x%4.4" PRIx64
            ", force %d)",
            GetID(), force);

  if (force) {
    GetPlans().DiscardAllPlans();
    return;
  }
  GetPlans().DiscardConsultingControllingPlans();
}

Status Thread::UnwindInnermostExpression() {
  Status error;
  ThreadPlan *innermost_expr_plan = GetPlans().GetInnermostExpression();
  if (!innermost_expr_plan) {
    error = Status::FromErrorString(
        "No expressions currently active on this thread");
    return error;
  }
  DiscardThreadPlansUpToPlan(innermost_expr_plan);
  return error;
}

ThreadPlanSP Thread::QueueBasePlan(bool abort_other_plans) {
  ThreadPlanSP thread_plan_sp(new ThreadPlanBase(*this));
  QueueThreadPlan(thread_plan_sp, abort_other_plans);
  return thread_plan_sp;
}

ThreadPlanSP Thread::QueueThreadPlanForStepSingleInstruction(
    bool step_over, bool abort_other_plans, bool stop_other_threads,
    Status &status) {
  ThreadPlanSP thread_plan_sp(new ThreadPlanStepInstruction(
      *this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion));
  status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
  return thread_plan_sp;
}

ThreadPlanSP Thread::QueueThreadPlanForStepOverRange(
    bool abort_other_plans, const AddressRange &range,
    const SymbolContext &addr_context, lldb::RunMode stop_other_threads,
    Status &status, LazyBool step_out_avoids_code_withoug_debug_info) {
  ThreadPlanSP thread_plan_sp;
  thread_plan_sp = std::make_shared<ThreadPlanStepOverRange>(
      *this, range, addr_context, stop_other_threads,
      step_out_avoids_code_withoug_debug_info);

  status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
  return thread_plan_sp;
}

// Call the QueueThreadPlanForStepOverRange method which takes an address
// range.
ThreadPlanSP Thread::QueueThreadPlanForStepOverRange(
    bool abort_other_plans, const LineEntry &line_entry,
    const SymbolContext &addr_context, lldb::RunMode stop_other_threads,
    Status &status, LazyBool step_out_avoids_code_withoug_debug_info) {
  const bool include_inlined_functions = true;
  auto address_range =
      line_entry.GetSameLineContiguousAddressRange(include_inlined_functions);
  return QueueThreadPlanForStepOverRange(
      abort_other_plans, address_range, addr_context, stop_other_threads,
      status, step_out_avoids_code_withoug_debug_info);
}

ThreadPlanSP Thread::QueueThreadPlanForStepInRange(
    bool abort_other_plans, const AddressRange &range,
    const SymbolContext &addr_context, const char *step_in_target,
    lldb::RunMode stop_other_threads, Status &status,
    LazyBool step_in_avoids_code_without_debug_info,
    LazyBool step_out_avoids_code_without_debug_info) {
  ThreadPlanSP thread_plan_sp(new ThreadPlanStepInRange(
      *this, range, addr_context, step_in_target, stop_other_threads,
      step_in_avoids_code_without_debug_info,
      step_out_avoids_code_without_debug_info));
  status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
  return thread_plan_sp;
}

// Call the QueueThreadPlanForStepInRange method which takes an address range.
ThreadPlanSP Thread::QueueThreadPlanForStepInRange(
    bool abort_other_plans, const LineEntry &line_entry,
    const SymbolContext &addr_context, const char *step_in_target,
    lldb::RunMode stop_other_threads, Status &status,
    LazyBool step_in_avoids_code_without_debug_info,
    LazyBool step_out_avoids_code_without_debug_info) {
  const bool include_inlined_functions = false;
  return QueueThreadPlanForStepInRange(
      abort_other_plans,
      line_entry.GetSameLineContiguousAddressRange(include_inlined_functions),
      addr_context, step_in_target, stop_other_threads, status,
      step_in_avoids_code_without_debug_info,
      step_out_avoids_code_without_debug_info);
}

ThreadPlanSP Thread::QueueThreadPlanForStepOut(
    bool abort_other_plans, SymbolContext *addr_context, bool first_insn,
    bool stop_other_threads, Vote report_stop_vote, Vote report_run_vote,
    uint32_t frame_idx, Status &status,
    LazyBool step_out_avoids_code_without_debug_info) {
  ThreadPlanSP thread_plan_sp(new ThreadPlanStepOut(
      *this, addr_context, first_insn, stop_other_threads, report_stop_vote,
      report_run_vote, frame_idx, step_out_avoids_code_without_debug_info));

  status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
  return thread_plan_sp;
}

ThreadPlanSP Thread::QueueThreadPlanForStepOutNoShouldStop(
    bool abort_other_plans, SymbolContext *addr_context, bool first_insn,
    bool stop_other_threads, Vote report_stop_vote, Vote report_run_vote,
    uint32_t frame_idx, Status &status, bool continue_to_next_branch) {
  const bool calculate_return_value =
      false; // No need to calculate the return value here.
  ThreadPlanSP thread_plan_sp(new ThreadPlanStepOut(
      *this, stop_other_threads, report_stop_vote, report_run_vote, frame_idx,
      continue_to_next_branch, calculate_return_value));

  ThreadPlanStepOut *new_plan =
      static_cast<ThreadPlanStepOut *>(thread_plan_sp.get());
  new_plan->ClearShouldStopHereCallbacks();

  status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
  return thread_plan_sp;
}

ThreadPlanSP Thread::QueueThreadPlanForStepThrough(StackID &return_stack_id,
                                                   bool abort_other_plans,
                                                   bool stop_other_threads,
                                                   Status &status) {
  ThreadPlanSP thread_plan_sp(
      new ThreadPlanStepThrough(*this, return_stack_id, stop_other_threads));
  if (!thread_plan_sp || !thread_plan_sp->ValidatePlan(nullptr))
    return ThreadPlanSP();

  status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
  return thread_plan_sp;
}

ThreadPlanSP Thread::QueueThreadPlanForRunToAddress(bool abort_other_plans,
                                                    Address &target_addr,
                                                    bool stop_other_threads,
                                                    Status &status) {
  ThreadPlanSP thread_plan_sp(
      new ThreadPlanRunToAddress(*this, target_addr, stop_other_threads));

  status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
  return thread_plan_sp;
}

ThreadPlanSP Thread::QueueThreadPlanForStepUntil(
    bool abort_other_plans, llvm::ArrayRef<addr_t> address_list,
    bool stop_other_threads, uint32_t frame_idx, Status &status) {
  ThreadPlanSP thread_plan_sp = std::make_shared<ThreadPlanStepUntil>(
      *this, address_list, stop_other_threads, frame_idx);

  status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
  return thread_plan_sp;
}

lldb::ThreadPlanSP Thread::QueueThreadPlanForStepScripted(
    bool abort_other_plans, const char *class_name,
    StructuredData::ObjectSP extra_args_sp, bool stop_other_threads,
    Status &status) {

  ThreadPlanSP thread_plan_sp(new ScriptedThreadPlan(
      *this, class_name, StructuredDataImpl(extra_args_sp)));
  thread_plan_sp->SetStopOthers(stop_other_threads);
  status = QueueThreadPlan(thread_plan_sp, abort_other_plans);
  return thread_plan_sp;
}

uint32_t Thread::GetIndexID() const { return m_index_id; }

TargetSP Thread::CalculateTarget() {
  TargetSP target_sp;
  ProcessSP process_sp(GetProcess());
  if (process_sp)
    target_sp = process_sp->CalculateTarget();
  return target_sp;
}

ProcessSP Thread::CalculateProcess() { return GetProcess(); }

ThreadSP Thread::CalculateThread() { return shared_from_this(); }

StackFrameSP Thread::CalculateStackFrame() { return StackFrameSP(); }

void Thread::CalculateExecutionContext(ExecutionContext &exe_ctx) {
  exe_ctx.SetContext(shared_from_this());
}

void Thread::PushProviderFrameList(StackFrameListSP frames) {
  std::lock_guard<std::mutex> guard(m_provider_frames_mutex);
  HostThread current(Host::GetCurrentThread());
  auto &stack = m_active_frame_providers_by_thread[current];
  LLDB_LOG(GetLog(LLDBLog::Thread),
           "Thread::PushProviderFrameList: tid = 0x{0:x}, depth = {1} -> {2}",
           GetID(), stack.size(), stack.size() + 1);
  stack.push_back(std::move(frames));
}

void Thread::PopProviderFrameList() {
  std::lock_guard<std::mutex> guard(m_provider_frames_mutex);
  HostThread current(Host::GetCurrentThread());
  auto it = m_active_frame_providers_by_thread.find(current);
  size_t pre_pop_depth =
      (it != m_active_frame_providers_by_thread.end()) ? it->second.size() : 0;
  LLDB_LOG(GetLog(LLDBLog::Thread),
           "Thread::PopProviderFrameList: tid = 0x{0:x}, depth = {1} -> {2}",
           GetID(), pre_pop_depth, pre_pop_depth ? pre_pop_depth - 1 : 0);
  assert(it != m_active_frame_providers_by_thread.end() && !it->second.empty());
  if (it == m_active_frame_providers_by_thread.end() || it->second.empty())
    return;
  it->second.pop_back();
  if (it->second.empty())
    m_active_frame_providers_by_thread.erase(it);
}

bool Thread::IsAnyProviderActive() {
  std::lock_guard<std::mutex> guard(m_provider_frames_mutex);
  return !m_active_frame_providers_by_thread.empty();
}

StackFrameListSP Thread::GetStackFrameList() {
  std::lock_guard<std::recursive_mutex> guard(m_frame_mutex);

  // Determine if we must return the parent frames instead of the
  // provider-augmented frames on this call.
  //
  // Frame providers are a public illusion layered on top of the private
  // reality (the unwinder stack, or a scripted process playing that
  // role). The private state thread (PST) manages the stop of that private
  // reality, so the correct view for its logic IS the private reality
  // -- the public illusion is only applied once the process has settled
  // and clients query the stopped state.
  //
  // When RunThreadPlan spawns an override PST, the original PST changes
  // role: it becomes the public event listener for the override, but it is
  // still working to manage the private side of the process.  So it also should
  // see the private reality and not the public illusion. Feeding it the public
  // illusion instead of the private reality is incorrect and can lead to
  // deadlocks as a side effect, since provider code may try to acquire locks
  // already held further up the call stack.
  //
  // We return parent frames in two situations:
  //
  //  1. Re-entrancy: a provider is already active on some host thread.
  //     - Same thread: the provider's get_frame_at_index() calls
  //       HandleCommand("bt") or accesses input_frames, which re-enters
  //       GetStackFrameList() -> infinite recursion.
  //     - Private state thread: the provider called EvaluateExpression()
  //       which resumed the process via RunThreadPlan; the private state
  //       thread must process the resulting stop event, but if it tries to
  //       build the synthetic frame list it will re-enter the provider ->
  //       deadlock.
  //     - Any other thread: would run the provider concurrently with the
  //       thread that is already mid-construction.
  //
  //  2. Current thread is a private state thread that should see the
  //     private reality (PrivateStateThreadGuard::IsPrivateStateThread).
  //
  // For case 1, if a provider is active we return its input (parent)
  // frames. For case (2), we return/create the unwinder frame list
  // without caching it in m_curr_frames_sp so that non-private-state
  // callers still get the public illusion once the process settles.
  ProcessSP process_sp = GetProcess();
  {
    std::lock_guard<std::mutex> pguard(m_provider_frames_mutex);
    if (!m_active_frame_providers_by_thread.empty()) {
      // Case 1a: current host thread is inside a provider call.
      HostThread current(Host::GetCurrentThread());
      auto it = m_active_frame_providers_by_thread.find(current);
      if (it != m_active_frame_providers_by_thread.end() && !it->second.empty())
        return it->second.back();

      // Case 1b: private state thread while a provider is active elsewhere.
      if (process_sp && process_sp->CurrentThreadIsPrivateStateThread())
        return m_active_frame_providers_by_thread.begin()->second.back();
    }
  }

  if (m_curr_frames_sp)
    return m_curr_frames_sp;

  // For case 2, PST must see the private reality, not the public illusion.
  // PrivateStateThreadGuard is a thread_local flag set by RunThreadPlan
  // (for the original PST) and RunPrivateStateThread (for override PSTs).
  // We cannot use CurrentThreadIsPrivateStateThread() here because
  // RunThreadPlan reassigns m_current_private_state_thread_sp to the
  // override, so the original PST is no longer recognized.
  if (PrivateStateThreadGuard::IsPrivateStateThread()) {
    if (!m_unwinder_frames_sp)
      m_unwinder_frames_sp = std::make_shared<StackFrameList>(
          *this, m_prev_frames_sp, true, /*provider_id=*/0);
    return m_unwinder_frames_sp;
  }

  // First, try to load frame providers if we don't have any yet.
  if (m_frame_providers.empty()) {
    if (process_sp) {
      Target &target = process_sp->GetTarget();
      const auto &descriptors = target.GetScriptedFrameProviderDescriptors();

      // Collect all descriptors that apply to this thread.
      std::vector<const ScriptedFrameProviderDescriptor *> thread_descriptors;
      for (const auto &entry : descriptors) {
        const ScriptedFrameProviderDescriptor &descriptor = entry.second;
        if (descriptor.IsValid() && descriptor.AppliesToThread(*this))
          thread_descriptors.push_back(&descriptor);
      }

      // Stable sort by priority so equal-priority providers keep
      // their registration (insertion) order.
      llvm::stable_sort(
          thread_descriptors, [](const ScriptedFrameProviderDescriptor *a,
                                 const ScriptedFrameProviderDescriptor *b) {
            // nullopt (no priority) sorts last (UINT32_MAX).
            uint32_t priority_a = a->GetPriority().value_or(UINT32_MAX);
            uint32_t priority_b = b->GetPriority().value_or(UINT32_MAX);
            return priority_a < priority_b;
          });

      // Load ALL matching providers in priority order.
      for (const auto *descriptor : thread_descriptors) {
        if (llvm::Error error = LoadScriptedFrameProvider(*descriptor)) {
          LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), std::move(error),
                         "Failed to load scripted frame provider: {0}");
          continue; // Try next provider if this one fails.
        }
      }
    }
  }

  // Create the frame list based on whether we have providers.
  if (!m_provider_chain_ids.empty()) {
    // We have providers - use the last one in the chain.
    // The last provider has already been chained with all previous providers.
    auto [last_desc, last_id] = m_provider_chain_ids.back();
    auto it = m_frame_providers.find(last_id);
    if (it != m_frame_providers.end()) {
      SyntheticFrameProviderSP last_provider = it->second;
      StackFrameListSP input_frames = last_provider->GetInputFrames();
      m_curr_frames_sp = std::make_shared<SyntheticStackFrameList>(
          *this, input_frames, m_prev_frames_sp, true, last_provider, last_id);
    } else {
      LLDB_LOG(GetLog(LLDBLog::Thread),
               "Missing frame provider (id = {0}) in Thread #{1:x}}", last_id,
               GetID());
    }
  }

  if (!m_curr_frames_sp) {
    // No provider - use normal unwinder frames with stable ID = 0.
    m_unwinder_frames_sp = std::make_shared<StackFrameList>(
        *this, m_prev_frames_sp, true, /*provider_id=*/0);
    m_curr_frames_sp = m_unwinder_frames_sp;
  } else {
    // Register this frame list by its identifier for later lookup.
    m_frame_lists_by_id.insert(
        {m_curr_frames_sp->GetIdentifier(), m_curr_frames_sp});
  }

  return m_curr_frames_sp;
}

lldb::StackFrameListSP
Thread::GetFrameListByIdentifier(lldb::frame_list_id_t id) {
  std::lock_guard<std::recursive_mutex> guard(m_frame_mutex);

  // ID 0 is reserved for the unwinder frame list. Always return the unwinder
  // frame list for ID 0.
  if (id == 0) {
    return m_unwinder_frames_sp;
  }

  auto it = m_frame_lists_by_id.find(id);
  if (it != m_frame_lists_by_id.end()) {
    auto sp = it->second.lock();
    LLDB_LOG(GetLog(LLDBLog::Thread),
             "GetFrameListByIdentifier({0}): found={1}, locked={2}", id, true,
             sp != nullptr);
    return sp;
  }
  LLDB_LOG(GetLog(LLDBLog::Thread), "GetFrameListByIdentifier({0}): found={1}",
           id, false);
  return nullptr;
}

llvm::Error Thread::LoadScriptedFrameProvider(
    const ScriptedFrameProviderDescriptor &descriptor) {
  std::lock_guard<std::recursive_mutex> guard(m_frame_mutex);

  StackFrameListSP input_frames;
  if (m_frame_providers.empty()) {
    // First provider gets real unwinder frames with stable ID = 0.
    m_unwinder_frames_sp =
        std::make_shared<StackFrameList>(*this, m_prev_frames_sp, true,
                                         /*provider_id=*/0);
    input_frames = m_unwinder_frames_sp;
  } else {
    // Subsequent providers wrap the previous provider.
    auto [last_desc, last_id] = m_provider_chain_ids.back();
    auto it = m_frame_providers.find(last_id);
    if (it == m_frame_providers.end())
      return llvm::createStringError("previous frame provider not found");
    SyntheticFrameProviderSP last_provider = it->second;
    StackFrameListSP last_provider_frames = last_provider->GetInputFrames();
    input_frames = std::make_shared<SyntheticStackFrameList>(
        *this, last_provider_frames, m_prev_frames_sp, true, last_provider,
        last_id);
    // Register this intermediate frame list so 'bt --provider <id>' can
    // show each provider's output independently.
    m_frame_lists_by_id.insert({last_id, input_frames});
    LLDB_LOG(GetLog(LLDBLog::Thread),
             "Registered intermediate frame list for provider id={0}, "
             "use_count={1}",
             last_id, input_frames.use_count());
  }

  // Protect provider construction (__init__) from re-entrancy. If the
  // provider calls back into the frame machinery (e.g. HandleCommand("bt"))
  // during __init__, GetStackFrameList() will find this thread in the
  // active-provider map and return input_frames instead of trying to
  // build a new synthetic list — preventing infinite recursion.
  PushProviderFrameList(input_frames);
  auto provider_or_err =
      SyntheticFrameProvider::CreateInstance(input_frames, descriptor);
  PopProviderFrameList();
  if (!provider_or_err)
    return provider_or_err.takeError();

  lldb::frame_list_id_t provider_id = descriptor.GetID();

  m_frame_providers.insert({provider_id, *provider_or_err});

  // Add to the provider chain.
  m_provider_chain_ids.push_back({descriptor, provider_id});

  return llvm::Error::success();
}

llvm::Expected<ScriptedFrameProviderDescriptor>
Thread::GetScriptedFrameProviderDescriptorForID(
    lldb::frame_list_id_t id) const {
  if (id == LLDB_UNWINDER_FRAME_LIST_ID)
    return ScriptedFrameProviderDescriptor();

  auto it = llvm::find_if(
      m_provider_chain_ids,
      [id](const std::pair<ScriptedFrameProviderDescriptor,
                           lldb::frame_list_id_t> &provider_id_pair) {
        return provider_id_pair.second == id;
      });

  if (it == m_provider_chain_ids.end())
    return llvm::createStringError(
        "Couldn't find ScriptedFrameProviderDescriptor for id = %u.", id);

  return it->first;
}

void Thread::ClearScriptedFrameProvider() {
  std::lock_guard<std::recursive_mutex> guard(m_frame_mutex);
  m_frame_providers.clear();
  m_provider_chain_ids.clear();
  m_frame_lists_by_id.clear();
  m_unwinder_frames_sp.reset();
  m_curr_frames_sp.reset();
  m_prev_frames_sp.reset();
}

std::optional<addr_t> Thread::GetPreviousFrameZeroPC() {
  return m_prev_framezero_pc;
}

void Thread::ClearStackFrames() {
  std::lock_guard<std::recursive_mutex> guard(m_frame_mutex);

  // If any host thread is inside a frame provider call (e.g. the provider
  // called EvaluateExpression which resumes the process), don't tear down the
  // frame state. The synthetic frame list is still being constructed and the
  // thread will stop right back where it was after the expression finishes.
  // This must be a global check (not per-host-thread) because the frame state
  // is shared and clearing it would destroy in-progress provider work.
  if (IsAnyProviderActive())
    return;

  GetUnwinder().Clear();
  m_prev_framezero_pc.reset();
  if (RegisterContextSP reg_ctx_sp = GetRegisterContext())
    m_prev_framezero_pc = reg_ctx_sp->GetPC();

  // Only store away the old "reference" StackFrameList if we got all its
  // frames:
  // FIXME: At some point we can try to splice in the frames we have fetched
  // into the new frame as we make it, but let's not try that now.
  if (m_curr_frames_sp && m_curr_frames_sp->WereAllFramesFetched())
    m_prev_frames_sp.swap(m_curr_frames_sp);
  m_curr_frames_sp.reset();
  m_unwinder_frames_sp.reset();

  // Clear the provider instances and reset the ID counter, but keep the
  // chain configuration (m_provider_chain_ids) so providers are re-loaded
  // with consistent IDs on the next GetStackFrameList() call.
  m_frame_providers.clear();
  m_frame_lists_by_id.clear();
  m_extended_info.reset();
  m_extended_info_fetched = false;
}

lldb::StackFrameSP Thread::GetFrameWithConcreteFrameIndex(uint32_t unwind_idx) {
  return GetStackFrameList()->GetFrameWithConcreteFrameIndex(unwind_idx);
}

Status Thread::ReturnFromFrameWithIndex(uint32_t frame_idx,
                                        lldb::ValueObjectSP return_value_sp,
                                        bool broadcast) {
  StackFrameSP frame_sp = GetStackFrameAtIndex(frame_idx);
  Status return_error;

  if (!frame_sp) {
    return_error = Status::FromErrorStringWithFormat(
        "Could not find frame with index %d in thread 0x%" PRIx64 ".",
        frame_idx, GetID());
  }

  return ReturnFromFrame(frame_sp, return_value_sp, broadcast);
}

Status Thread::ReturnFromFrame(lldb::StackFrameSP frame_sp,
                               lldb::ValueObjectSP return_value_sp,
                               bool broadcast) {
  Status return_error;

  if (!frame_sp) {
    return_error = Status::FromErrorString("Can't return to a null frame.");
    return return_error;
  }

  Thread *thread = frame_sp->GetThread().get();
  uint32_t older_frame_idx = frame_sp->GetFrameIndex() + 1;
  StackFrameSP older_frame_sp = thread->GetStackFrameAtIndex(older_frame_idx);
  if (!older_frame_sp) {
    return_error = Status::FromErrorString("No older frame to return to.");
    return return_error;
  }

  if (return_value_sp) {
    lldb::ABISP abi = thread->GetProcess()->GetABI();
    if (!abi) {
      return_error =
          Status::FromErrorString("Could not find ABI to set return value.");
      return return_error;
    }
    SymbolContext sc = frame_sp->GetSymbolContext(eSymbolContextFunction);

    // FIXME: ValueObject::Cast doesn't currently work correctly, at least not
    // for scalars.
    // Turn that back on when that works.
    if (/* DISABLES CODE */ (false) && sc.function != nullptr) {
      Type *function_type = sc.function->GetType();
      if (function_type) {
        CompilerType return_type =
            sc.function->GetCompilerType().GetFunctionReturnType();
        if (return_type) {
          StreamString s;
          return_type.DumpTypeDescription(&s);
          ValueObjectSP cast_value_sp = return_value_sp->Cast(return_type);
          if (cast_value_sp) {
            cast_value_sp->SetFormat(eFormatHex);
            return_value_sp = cast_value_sp;
          }
        }
      }
    }

    return_error = abi->SetReturnValueObject(older_frame_sp, return_value_sp);
    if (!return_error.Success())
      return return_error;
  }

  // Now write the return registers for the chosen frame: Note, we can't use
  // ReadAllRegisterValues->WriteAllRegisterValues, since the read & write cook
  // their data

  StackFrameSP youngest_frame_sp = thread->GetStackFrameAtIndex(0);
  if (youngest_frame_sp) {
    lldb::RegisterContextSP reg_ctx_sp(youngest_frame_sp->GetRegisterContext());
    if (reg_ctx_sp) {
      bool copy_success = reg_ctx_sp->CopyFromRegisterContext(
          older_frame_sp->GetRegisterContext());
      if (copy_success) {
        thread->DiscardThreadPlans(true);
        thread->ClearStackFrames();
        if (broadcast && EventTypeHasListeners(eBroadcastBitStackChanged)) {
          auto data_sp = std::make_shared<ThreadEventData>(shared_from_this());
          BroadcastEvent(eBroadcastBitStackChanged, data_sp);
        }
      } else {
        return_error =
            Status::FromErrorString("Could not reset register values.");
      }
    } else {
      return_error = Status::FromErrorString("Frame has no register context.");
    }
  } else {
    return_error = Status::FromErrorString("Returned past top frame.");
  }
  return return_error;
}

static void DumpAddressList(Stream &s, const std::vector<Address> &list,
                            ExecutionContextScope *exe_scope) {
  for (size_t n = 0; n < list.size(); n++) {
    s << "\t";
    list[n].Dump(&s, exe_scope, Address::DumpStyleResolvedDescription,
                 Address::DumpStyleSectionNameOffset);
    s << "\n";
  }
}

Status Thread::JumpToLine(const FileSpec &file, uint32_t line,
                          bool can_leave_function, std::string *warnings) {
  ExecutionContext exe_ctx(GetStackFrameAtIndex(0));
  Target *target = exe_ctx.GetTargetPtr();
  TargetSP target_sp = exe_ctx.GetTargetSP();
  RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
  StackFrame *frame = exe_ctx.GetFramePtr();
  const SymbolContext &sc = frame->GetSymbolContext(eSymbolContextFunction);

  // Find candidate locations.
  std::vector<Address> candidates, within_function, outside_function;
  target->GetImages().FindAddressesForLine(target_sp, file, line, sc.function,
                                           within_function, outside_function);

  // If possible, we try and stay within the current function. Within a
  // function, we accept multiple locations (optimized code may do this,
  // there's no solution here so we do the best we can). However if we're
  // trying to leave the function, we don't know how to pick the right
  // location, so if there's more than one then we bail.
  if (!within_function.empty())
    candidates = within_function;
  else if (outside_function.size() == 1 && can_leave_function)
    candidates = outside_function;

  // Check if we got anything.
  if (candidates.empty()) {
    if (outside_function.empty()) {
      return Status::FromErrorStringWithFormatv(
          "Cannot locate an address for {0}:{1}.", file.GetFilename(), line);
    } else if (outside_function.size() == 1) {
      return Status::FromErrorStringWithFormatv(
          "{0}:{1} is outside the current function.", file.GetFilename(), line);
    } else {
      StreamString sstr;
      DumpAddressList(sstr, outside_function, target);
      return Status::FromErrorStringWithFormatv(
          "{0}:{1} has multiple candidate locations:\n{2}", file.GetFilename(),
          line, sstr.GetData());
    }
  }

  // Accept the first location, warn about any others.
  Address dest = candidates[0];
  if (warnings && candidates.size() > 1) {
    StreamString sstr;
    sstr.Format(
        "{0}:{1} appears multiple times in this function, selecting the "
        "first location:\n",
        file.GetFilename(), line);
    DumpAddressList(sstr, candidates, target);
    *warnings = std::string(sstr.GetString().trim('\n'));
  }

  if (!reg_ctx->SetPC(dest))
    return Status::FromErrorString("Cannot change PC to target address.");

  return Status();
}

bool Thread::DumpUsingFormat(Stream &strm, uint32_t frame_idx,
                             const FormatEntity::Entry *format) {
  ExecutionContext exe_ctx(shared_from_this());
  Process *process = exe_ctx.GetProcessPtr();
  if (!process || !format)
    return false;

  StackFrameSP frame_sp;
  SymbolContext frame_sc;
  if (frame_idx != LLDB_INVALID_FRAME_ID) {
    frame_sp = GetStackFrameAtIndex(frame_idx);
    if (frame_sp) {
      exe_ctx.SetFrameSP(frame_sp);
      frame_sc = frame_sp->GetSymbolContext(eSymbolContextEverything);
    }
  }

  return FormatEntity::Formatter(frame_sp ? &frame_sc : nullptr, &exe_ctx,
                                 nullptr, false, false)
      .Format(*format, strm);
}

void Thread::DumpUsingSettingsFormat(Stream &strm, uint32_t frame_idx,
                                     bool stop_format) {
  ExecutionContext exe_ctx(shared_from_this());

  const FormatEntity::Entry *thread_format;
  FormatEntity::Entry format_entry;
  if (stop_format) {
    format_entry = exe_ctx.GetTargetRef().GetDebugger().GetThreadStopFormat();
    thread_format = &format_entry;
  } else {
    format_entry = exe_ctx.GetTargetRef().GetDebugger().GetThreadFormat();
    thread_format = &format_entry;
  }

  assert(thread_format);

  DumpUsingFormat(strm, frame_idx, thread_format);
}

void Thread::SettingsInitialize() {}

void Thread::SettingsTerminate() {}

lldb::addr_t Thread::GetThreadPointer() {
  if (m_reg_context_sp)
    return m_reg_context_sp->GetThreadPointer();
  return LLDB_INVALID_ADDRESS;
}

addr_t Thread::GetThreadLocalData(const ModuleSP module,
                                  lldb::addr_t tls_file_addr) {
  // The default implementation is to ask the dynamic loader for it. This can
  // be overridden for specific platforms.
  DynamicLoader *loader = GetProcess()->GetDynamicLoader();
  if (loader)
    return loader->GetThreadLocalData(module, shared_from_this(),
                                      tls_file_addr);
  else
    return LLDB_INVALID_ADDRESS;
}

bool Thread::SafeToCallFunctions() {
  Process *process = GetProcess().get();
  if (process) {
    DynamicLoader *loader = GetProcess()->GetDynamicLoader();
    if (loader && loader->IsFullyInitialized() == false)
      return false;

    SystemRuntime *runtime = process->GetSystemRuntime();
    if (runtime) {
      return runtime->SafeToCallFunctionsOnThisThread(shared_from_this());
    }
  }
  return true;
}

lldb::StackFrameSP
Thread::GetStackFrameSPForStackFramePtr(StackFrame *stack_frame_ptr) {
  return GetStackFrameList()->GetStackFrameSPForStackFramePtr(stack_frame_ptr);
}

std::string Thread::StopReasonAsString(lldb::StopReason reason) {
  switch (reason) {
  case eStopReasonInvalid:
    return "invalid";
  case eStopReasonNone:
    return "none";
  case eStopReasonTrace:
    return "trace";
  case eStopReasonBreakpoint:
    return "breakpoint";
  case eStopReasonWatchpoint:
    return "watchpoint";
  case eStopReasonSignal:
    return "signal";
  case eStopReasonException:
    return "exception";
  case eStopReasonExec:
    return "exec";
  case eStopReasonFork:
    return "fork";
  case eStopReasonVFork:
    return "vfork";
  case eStopReasonVForkDone:
    return "vfork done";
  case eStopReasonPlanComplete:
    return "plan complete";
  case eStopReasonThreadExiting:
    return "thread exiting";
  case eStopReasonInstrumentation:
    return "instrumentation break";
  case eStopReasonProcessorTrace:
    return "processor trace";
  case eStopReasonInterrupt:
    return "async interrupt";
  case eStopReasonHistoryBoundary:
    return "history boundary";
  }

  return "StopReason = " + std::to_string(reason);
}

std::string Thread::RunModeAsString(lldb::RunMode mode) {
  switch (mode) {
  case eOnlyThisThread:
    return "only this thread";
  case eAllThreads:
    return "all threads";
  case eOnlyDuringStepping:
    return "only during stepping";
  }

  return "RunMode = " + std::to_string(mode);
}

size_t Thread::GetStatus(Stream &strm, uint32_t start_frame,
                         uint32_t num_frames, uint32_t num_frames_with_source,
                         bool stop_format, bool show_hidden, bool only_stacks) {

  ExecutionContext exe_ctx(shared_from_this());
  Target *target = exe_ctx.GetTargetPtr();
  if (!only_stacks) {
    Process *process = exe_ctx.GetProcessPtr();
    strm.Indent();
    bool is_selected = false;
    if (process) {
      if (process->GetThreadList().GetSelectedThread().get() == this)
        is_selected = true;
    }
    strm.Printf("%c ", is_selected ? '*' : ' ');
    if (target && target->GetDebugger().GetUseExternalEditor()) {
      StackFrameSP frame_sp = GetStackFrameAtIndex(start_frame);
      if (frame_sp) {
        SymbolContext frame_sc(
            frame_sp->GetSymbolContext(eSymbolContextLineEntry));
        if (frame_sc.line_entry.line != 0 && frame_sc.line_entry.GetFile()) {
          if (llvm::Error e = Host::OpenFileInExternalEditor(
                  target->GetDebugger().GetExternalEditor(),
                  frame_sc.line_entry.GetFile(), frame_sc.line_entry.line)) {
            LLDB_LOG_ERROR(GetLog(LLDBLog::Host), std::move(e),
                           "OpenFileInExternalEditor failed: {0}");
          }
        }
      }
    }

    DumpUsingSettingsFormat(strm, start_frame, stop_format);
  }

  size_t num_frames_shown = 0;
  if (num_frames > 0) {
    strm.IndentMore();

    const bool show_frame_info = true;
    const bool show_frame_unique = only_stacks;
    bool show_selected_frame = false;
    if (num_frames == 1 || only_stacks ||
        (GetID() != GetProcess()->GetThreadList().GetSelectedThread()->GetID()))
      strm.IndentMore();
    else
      show_selected_frame = true;

    bool show_hidden_marker =
        target && target->GetDebugger().GetMarkHiddenFrames();
    num_frames_shown = GetStackFrameList()->GetStatus(
        strm, start_frame, num_frames, show_frame_info, num_frames_with_source,
        show_frame_unique, show_hidden, show_hidden_marker,
        show_selected_frame);
    if (num_frames == 1)
      strm.IndentLess();
    strm.IndentLess();
  }
  return num_frames_shown;
}

bool Thread::GetDescription(Stream &strm, lldb::DescriptionLevel level,
                            bool print_json_thread, bool print_json_stopinfo) {
  const bool stop_format = false;
  DumpUsingSettingsFormat(strm, 0, stop_format);
  strm.Printf("\n");

  StructuredData::ObjectSP thread_info = GetExtendedInfo();

  if (print_json_thread || print_json_stopinfo) {
    if (thread_info && print_json_thread) {
      thread_info->Dump(strm);
      strm.Printf("\n");
    }

    if (print_json_stopinfo && m_stop_info_sp) {
      StructuredData::ObjectSP stop_info = m_stop_info_sp->GetExtendedInfo();
      if (stop_info) {
        stop_info->Dump(strm);
        strm.Printf("\n");
      }
    }

    return true;
  }

  if (thread_info) {
    StructuredData::ObjectSP activity =
        thread_info->GetObjectForDotSeparatedPath("activity");
    StructuredData::ObjectSP breadcrumb =
        thread_info->GetObjectForDotSeparatedPath("breadcrumb");
    StructuredData::ObjectSP messages =
        thread_info->GetObjectForDotSeparatedPath("trace_messages");

    bool printed_activity = false;
    if (activity && activity->GetType() == eStructuredDataTypeDictionary) {
      StructuredData::Dictionary *activity_dict = activity->GetAsDictionary();
      StructuredData::ObjectSP id = activity_dict->GetValueForKey("id");
      StructuredData::ObjectSP name = activity_dict->GetValueForKey("name");
      if (name && name->GetType() == eStructuredDataTypeString && id &&
          id->GetType() == eStructuredDataTypeInteger) {
        strm.Format("  Activity '{0}', {1:x}\n",
                    name->GetAsString()->GetValue(),
                    id->GetUnsignedIntegerValue());
      }
      printed_activity = true;
    }
    bool printed_breadcrumb = false;
    if (breadcrumb && breadcrumb->GetType() == eStructuredDataTypeDictionary) {
      if (printed_activity)
        strm.Printf("\n");
      StructuredData::Dictionary *breadcrumb_dict =
          breadcrumb->GetAsDictionary();
      StructuredData::ObjectSP breadcrumb_text =
          breadcrumb_dict->GetValueForKey("name");
      if (breadcrumb_text &&
          breadcrumb_text->GetType() == eStructuredDataTypeString) {
        strm.Format("  Current Breadcrumb: {0}\n",
                    breadcrumb_text->GetAsString()->GetValue());
      }
      printed_breadcrumb = true;
    }
    if (messages && messages->GetType() == eStructuredDataTypeArray) {
      if (printed_breadcrumb)
        strm.Printf("\n");
      StructuredData::Array *messages_array = messages->GetAsArray();
      const size_t msg_count = messages_array->GetSize();
      if (msg_count > 0) {
        strm.Printf("  %zu trace messages:\n", msg_count);
        for (size_t i = 0; i < msg_count; i++) {
          StructuredData::ObjectSP message = messages_array->GetItemAtIndex(i);
          if (message && message->GetType() == eStructuredDataTypeDictionary) {
            StructuredData::Dictionary *message_dict =
                message->GetAsDictionary();
            StructuredData::ObjectSP message_text =
                message_dict->GetValueForKey("message");
            if (message_text &&
                message_text->GetType() == eStructuredDataTypeString) {
              strm.Format("    {0}\n", message_text->GetAsString()->GetValue());
            }
          }
        }
      }
    }
  }

  return true;
}

size_t Thread::GetStackFrameStatus(Stream &strm, uint32_t first_frame,
                                   uint32_t num_frames, bool show_frame_info,
                                   uint32_t num_frames_with_source,
                                   bool show_hidden) {
  ExecutionContext exe_ctx(shared_from_this());
  Target *target = exe_ctx.GetTargetPtr();
  bool show_hidden_marker =
      target && target->GetDebugger().GetMarkHiddenFrames();
  return GetStackFrameList()->GetStatus(
      strm, first_frame, num_frames, show_frame_info, num_frames_with_source,
      /*show_unique*/ false, show_hidden, show_hidden_marker);
}

Unwind &Thread::GetUnwinder() {
  if (!m_unwinder_up)
    m_unwinder_up = std::make_unique<UnwindLLDB>(*this);
  return *m_unwinder_up;
}

void Thread::Flush() {
  ClearStackFrames();
  m_reg_context_sp.reset();
  m_stopped_at_unexecuted_bp = LLDB_INVALID_ADDRESS;
}

bool Thread::IsStillAtLastBreakpointHit() {
  // If we are currently stopped at a breakpoint, always return that stopinfo
  // and don't reset it. This allows threads to maintain their breakpoint
  // stopinfo, such as when thread-stepping in multithreaded programs.
  if (m_stop_info_sp) {
    StopReason stop_reason = m_stop_info_sp->GetStopReason();
    if (stop_reason == lldb::eStopReasonBreakpoint) {
      uint64_t value = m_stop_info_sp->GetValue();
      lldb::RegisterContextSP reg_ctx_sp(GetRegisterContext());
      if (reg_ctx_sp) {
        lldb::addr_t pc = reg_ctx_sp->GetPC();
        BreakpointSiteSP bp_site_sp =
            GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
        if (bp_site_sp && static_cast<break_id_t>(value) == bp_site_sp->GetID())
          return true;
      }
    }
  }
  return false;
}

Status Thread::StepIn(bool source_step,
                      LazyBool step_in_avoids_code_without_debug_info,
                      LazyBool step_out_avoids_code_without_debug_info)

{
  Status error;
  Process *process = GetProcess().get();
  if (StateIsStoppedState(process->GetState(), true)) {
    StackFrameSP frame_sp = GetStackFrameAtIndex(0);
    ThreadPlanSP new_plan_sp;
    const lldb::RunMode run_mode = eOnlyThisThread;
    const bool abort_other_plans = false;

    if (source_step && frame_sp && frame_sp->HasDebugInformation()) {
      SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
      new_plan_sp = QueueThreadPlanForStepInRange(
          abort_other_plans, sc.line_entry, sc, nullptr, run_mode, error,
          step_in_avoids_code_without_debug_info,
          step_out_avoids_code_without_debug_info);
    } else {
      new_plan_sp = QueueThreadPlanForStepSingleInstruction(
          false, abort_other_plans, run_mode, error);
    }

    new_plan_sp->SetIsControllingPlan(true);
    new_plan_sp->SetOkayToDiscard(false);

    // Why do we need to set the current thread by ID here???
    process->GetThreadList().SetSelectedThreadByID(GetID());
    error = process->Resume();
  } else {
    error = Status::FromErrorString("process not stopped");
  }
  return error;
}

Status Thread::StepOver(bool source_step,
                        LazyBool step_out_avoids_code_without_debug_info) {
  Status error;
  Process *process = GetProcess().get();
  if (StateIsStoppedState(process->GetState(), true)) {
    StackFrameSP frame_sp = GetStackFrameAtIndex(0);
    ThreadPlanSP new_plan_sp;

    const lldb::RunMode run_mode = eOnlyThisThread;
    const bool abort_other_plans = false;

    if (source_step && frame_sp && frame_sp->HasDebugInformation()) {
      SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
      new_plan_sp = QueueThreadPlanForStepOverRange(
          abort_other_plans, sc.line_entry, sc, run_mode, error,
          step_out_avoids_code_without_debug_info);
    } else {
      new_plan_sp = QueueThreadPlanForStepSingleInstruction(
          true, abort_other_plans, run_mode, error);
    }

    new_plan_sp->SetIsControllingPlan(true);
    new_plan_sp->SetOkayToDiscard(false);

    // Why do we need to set the current thread by ID here???
    process->GetThreadList().SetSelectedThreadByID(GetID());
    error = process->Resume();
  } else {
    error = Status::FromErrorString("process not stopped");
  }
  return error;
}

Status Thread::StepOut(uint32_t frame_idx) {
  Status error;
  Process *process = GetProcess().get();
  if (StateIsStoppedState(process->GetState(), true)) {
    const bool first_instruction = false;
    const bool stop_other_threads = false;
    const bool abort_other_plans = false;

    ThreadPlanSP new_plan_sp(QueueThreadPlanForStepOut(
        abort_other_plans, nullptr, first_instruction, stop_other_threads,
        eVoteYes, eVoteNoOpinion, frame_idx, error));

    new_plan_sp->SetIsControllingPlan(true);
    new_plan_sp->SetOkayToDiscard(false);

    // Why do we need to set the current thread by ID here???
    process->GetThreadList().SetSelectedThreadByID(GetID());
    error = process->Resume();
  } else {
    error = Status::FromErrorString("process not stopped");
  }
  return error;
}

ValueObjectSP Thread::GetCurrentException() {
  if (auto frame_sp = GetStackFrameAtIndex(0))
    if (auto recognized_frame = frame_sp->GetRecognizedFrame())
      if (auto e = recognized_frame->GetExceptionObject())
        return e;

  // NOTE: Even though this behavior is generalized, only ObjC is actually
  // supported at the moment.
  for (LanguageRuntime *runtime : GetProcess()->GetLanguageRuntimes()) {
    if (auto e = runtime->GetExceptionObjectForThread(shared_from_this()))
      return e;
  }

  return ValueObjectSP();
}

ThreadSP Thread::GetCurrentExceptionBacktrace() {
  ValueObjectSP exception = GetCurrentException();
  if (!exception)
    return ThreadSP();

  // NOTE: Even though this behavior is generalized, only ObjC is actually
  // supported at the moment.
  for (LanguageRuntime *runtime : GetProcess()->GetLanguageRuntimes()) {
    if (auto bt = runtime->GetBacktraceThreadFromException(exception))
      return bt;
  }

  return ThreadSP();
}

lldb::ValueObjectSP Thread::GetSiginfoValue() {
  ProcessSP process_sp = GetProcess();
  assert(process_sp);
  Target &target = process_sp->GetTarget();
  PlatformSP platform_sp = target.GetPlatform();
  assert(platform_sp);
  ArchSpec arch = target.GetArchitecture();

  CompilerType type = platform_sp->GetSiginfoType(arch.GetTriple());
  if (!type.IsValid())
    return ValueObjectConstResult::Create(
        &target, Status::FromErrorString("no siginfo_t for the platform"));

  auto type_size_or_err = type.GetByteSize(nullptr);
  if (!type_size_or_err)
    return ValueObjectConstResult::Create(
        &target, Status::FromError(type_size_or_err.takeError()));

  llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> data =
      GetSiginfo(*type_size_or_err);
  if (!data)
    return ValueObjectConstResult::Create(&target,
                                          Status::FromError(data.takeError()));

  DataExtractor data_extractor{data.get()->getBufferStart(), data.get()->getBufferSize(),
    process_sp->GetByteOrder(), arch.GetAddressByteSize()};
  return ValueObjectConstResult::Create(&target, type, ConstString("__lldb_siginfo"), data_extractor);
}
