//===-- Thread.h ------------------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_TARGET_THREAD_H
#define LLDB_TARGET_THREAD_H

#include <memory>
#include <mutex>
#include <string>
#include <vector>

#include "lldb/Core/UserSettingsController.h"
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/RegisterCheckpoint.h"
#include "lldb/Target/StackFrameList.h"
#include "lldb/Utility/Broadcaster.h"
#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/UserID.h"
#include "lldb/lldb-private.h"

#define LLDB_THREAD_MAX_STOP_EXC_DATA 8

namespace lldb_private {

class ThreadPlanStack;

class ThreadProperties : public Properties {
public:
  ThreadProperties(bool is_global);

  ~ThreadProperties() override;

  /// The regular expression returned determines symbols that this
  /// thread won't stop in during "step-in" operations.
  ///
  /// \return
  ///    A pointer to a regular expression to compare against symbols,
  ///    or nullptr if all symbols are allowed.
  ///
  const RegularExpression *GetSymbolsToAvoidRegexp();

  FileSpecList GetLibrariesToAvoid() const;

  bool GetTraceEnabledState() const;

  bool GetStepInAvoidsNoDebug() const;

  bool GetStepOutAvoidsNoDebug() const;

  uint64_t GetMaxBacktraceDepth() const;
};

typedef std::shared_ptr<ThreadProperties> ThreadPropertiesSP;

class Thread : public std::enable_shared_from_this<Thread>,
               public ThreadProperties,
               public UserID,
               public ExecutionContextScope,
               public Broadcaster {
public:
  /// Broadcaster event bits definitions.
  enum {
    eBroadcastBitStackChanged = (1 << 0),
    eBroadcastBitThreadSuspended = (1 << 1),
    eBroadcastBitThreadResumed = (1 << 2),
    eBroadcastBitSelectedFrameChanged = (1 << 3),
    eBroadcastBitThreadSelected = (1 << 4)
  };

  static ConstString &GetStaticBroadcasterClass();

  ConstString &GetBroadcasterClass() const override {
    return GetStaticBroadcasterClass();
  }

  class ThreadEventData : public EventData {
  public:
    ThreadEventData(const lldb::ThreadSP thread_sp);

    ThreadEventData(const lldb::ThreadSP thread_sp, const StackID &stack_id);

    ThreadEventData();

    ~ThreadEventData() override;

    static ConstString GetFlavorString();

    ConstString GetFlavor() const override {
      return ThreadEventData::GetFlavorString();
    }

    void Dump(Stream *s) const override;

    static const ThreadEventData *GetEventDataFromEvent(const Event *event_ptr);

    static lldb::ThreadSP GetThreadFromEvent(const Event *event_ptr);

    static StackID GetStackIDFromEvent(const Event *event_ptr);

    static lldb::StackFrameSP GetStackFrameFromEvent(const Event *event_ptr);

    lldb::ThreadSP GetThread() const { return m_thread_sp; }

    StackID GetStackID() const { return m_stack_id; }

  private:
    lldb::ThreadSP m_thread_sp;
    StackID m_stack_id;

    ThreadEventData(const ThreadEventData &) = delete;
    const ThreadEventData &operator=(const ThreadEventData &) = delete;
  };

  struct ThreadStateCheckpoint {
    uint32_t orig_stop_id; // Dunno if I need this yet but it is an interesting
                           // bit of data.
    lldb::StopInfoSP stop_info_sp; // You have to restore the stop info or you
                                   // might continue with the wrong signals.
    size_t m_completed_plan_checkpoint;
    lldb::RegisterCheckpointSP
        register_backup_sp; // You need to restore the registers, of course...
    uint32_t current_inlined_depth;
    lldb::addr_t current_inlined_pc;
  };

  /// Constructor
  ///
  /// \param [in] use_invalid_index_id
  ///     Optional parameter, defaults to false.  The only subclass that
  ///     is likely to set use_invalid_index_id == true is the HistoryThread
  ///     class.  In that case, the Thread we are constructing represents
  ///     a thread from earlier in the program execution.  We may have the
  ///     tid of the original thread that they represent but we don't want
  ///     to reuse the IndexID of that thread, or create a new one.  If a
  ///     client wants to know the original thread's IndexID, they should use
  ///     Thread::GetExtendedBacktraceOriginatingIndexID().
  Thread(Process &process, lldb::tid_t tid, bool use_invalid_index_id = false);

  ~Thread() override;

  static void SettingsInitialize();

  static void SettingsTerminate();

  static const ThreadPropertiesSP &GetGlobalProperties();

  lldb::ProcessSP GetProcess() const { return m_process_wp.lock(); }

  int GetResumeSignal() const { return m_resume_signal; }

  void SetResumeSignal(int signal) { m_resume_signal = signal; }

  lldb::StateType GetState() const;

  void SetState(lldb::StateType state);

  /// Sets the USER resume state for this thread.  If you set a thread to
  /// suspended with
  /// this API, it won't take part in any of the arbitration for ShouldResume,
  /// and will stay
  /// suspended even when other threads do get to run.
  ///
  /// N.B. This is not the state that is used internally by thread plans to
  /// implement
  /// staying on one thread while stepping over a breakpoint, etc.  The is the
  /// TemporaryResume state, and if you are implementing some bit of strategy in
  /// the stepping
  /// machinery you should be using that state and not the user resume state.
  ///
  /// If you are just preparing all threads to run, you should not override the
  /// threads that are
  /// marked as suspended by the debugger.  In that case, pass override_suspend
  /// = false.  If you want
  /// to force the thread to run (e.g. the "thread continue" command, or are
  /// resetting the state
  /// (e.g. in SBThread::Resume()), then pass true to override_suspend.
  void SetResumeState(lldb::StateType state, bool override_suspend = false) {
    if (m_resume_state == lldb::eStateSuspended && !override_suspend)
      return;
    m_resume_state = state;
  }

  /// Gets the USER resume state for this thread.  This is not the same as what
  /// this thread is going to do for any particular step, however if this thread
  /// returns eStateSuspended, then the process control logic will never allow
  /// this
  /// thread to run.
  ///
  /// \return
  ///    The User resume state for this thread.
  lldb::StateType GetResumeState() const { return m_resume_state; }

  // This function is called on all the threads before "ShouldResume" and
  // "WillResume" in case a thread needs to change its state before the
  // ThreadList polls all the threads to figure out which ones actually will
  // get to run and how.
  void SetupForResume();

  // Do not override this function, it is for thread plan logic only
  bool ShouldResume(lldb::StateType resume_state);

  // Override this to do platform specific tasks before resume.
  virtual void WillResume(lldb::StateType resume_state) {}

  // This clears generic thread state after a resume.  If you subclass this, be
  // sure to call it.
  virtual void DidResume();

  // This notifies the thread when a private stop occurs.
  virtual void DidStop();

  virtual void RefreshStateAfterStop() = 0;

  void SelectMostRelevantFrame();

  std::string GetStopDescription();

  std::string GetStopDescriptionRaw();

  void WillStop();

  bool ShouldStop(Event *event_ptr);

  Vote ShouldReportStop(Event *event_ptr);

  Vote ShouldReportRun(Event *event_ptr);

  void Flush();

  // Return whether this thread matches the specification in ThreadSpec.  This
  // is a virtual method because at some point we may extend the thread spec
  // with a platform specific dictionary of attributes, which then only the
  // platform specific Thread implementation would know how to match.  For now,
  // this just calls through to the ThreadSpec's ThreadPassesBasicTests method.
  virtual bool MatchesSpec(const ThreadSpec *spec);

  lldb::StopInfoSP GetStopInfo();

  lldb::StopReason GetStopReason();

  bool StopInfoIsUpToDate() const;

  // This sets the stop reason to a "blank" stop reason, so you can call
  // functions on the thread without having the called function run with
  // whatever stop reason you stopped with.
  void SetStopInfoToNothing();

  bool ThreadStoppedForAReason();

  static std::string RunModeAsString(lldb::RunMode mode);

  static std::string StopReasonAsString(lldb::StopReason reason);

  virtual const char *GetInfo() { return nullptr; }

  /// Retrieve a dictionary of information about this thread
  ///
  /// On Mac OS X systems there may be voucher information.
  /// The top level dictionary returned will have an "activity" key and the
  /// value of the activity is a dictionary.  Keys in that dictionary will
  /// be "name" and "id", among others.
  /// There may also be "trace_messages" (an array) with each entry in that
  /// array
  /// being a dictionary (keys include "message" with the text of the trace
  /// message).
  StructuredData::ObjectSP GetExtendedInfo() {
    if (!m_extended_info_fetched) {
      m_extended_info = FetchThreadExtendedInfo();
      m_extended_info_fetched = true;
    }
    return m_extended_info;
  }

  virtual const char *GetName() { return nullptr; }

  virtual void SetName(const char *name) {}

  /// Whether this thread can be associated with a libdispatch queue
  ///
  /// The Thread may know if it is associated with a libdispatch queue,
  /// it may know definitively that it is NOT associated with a libdispatch
  /// queue, or it may be unknown whether it is associated with a libdispatch
  /// queue.
  ///
  /// \return
  ///     eLazyBoolNo if this thread is definitely not associated with a
  ///     libdispatch queue (e.g. on a non-Darwin system where GCD aka
  ///     libdispatch is not available).
  ///
  ///     eLazyBoolYes this thread is associated with a libdispatch queue.
  ///
  ///     eLazyBoolCalculate this thread may be associated with a libdispatch
  ///     queue but the thread doesn't know one way or the other.
  virtual lldb_private::LazyBool GetAssociatedWithLibdispatchQueue() {
    return eLazyBoolNo;
  }

  virtual void SetAssociatedWithLibdispatchQueue(
      lldb_private::LazyBool associated_with_libdispatch_queue) {}

  /// Retrieve the Queue ID for the queue currently using this Thread
  ///
  /// If this Thread is doing work on behalf of a libdispatch/GCD queue,
  /// retrieve the QueueID.
  ///
  /// This is a unique identifier for the libdispatch/GCD queue in a
  /// process.  Often starting at 1 for the initial system-created
  /// queues and incrementing, a QueueID will not be reused for a
  /// different queue during the lifetime of a process.
  ///
  /// \return
  ///     A QueueID if the Thread subclass implements this, else
  ///     LLDB_INVALID_QUEUE_ID.
  virtual lldb::queue_id_t GetQueueID() { return LLDB_INVALID_QUEUE_ID; }

  virtual void SetQueueID(lldb::queue_id_t new_val) {}

  /// Retrieve the Queue name for the queue currently using this Thread
  ///
  /// If this Thread is doing work on behalf of a libdispatch/GCD queue,
  /// retrieve the Queue name.
  ///
  /// \return
  ///     The Queue name, if the Thread subclass implements this, else
  ///     nullptr.
  virtual const char *GetQueueName() { return nullptr; }

  virtual void SetQueueName(const char *name) {}

  /// Retrieve the Queue kind for the queue currently using this Thread
  ///
  /// If this Thread is doing work on behalf of a libdispatch/GCD queue,
  /// retrieve the Queue kind - either eQueueKindSerial or
  /// eQueueKindConcurrent, indicating that this queue processes work
  /// items serially or concurrently.
  ///
  /// \return
  ///     The Queue kind, if the Thread subclass implements this, else
  ///     eQueueKindUnknown.
  virtual lldb::QueueKind GetQueueKind() { return lldb::eQueueKindUnknown; }

  virtual void SetQueueKind(lldb::QueueKind kind) {}

  /// Retrieve the Queue for this thread, if any.
  ///
  /// \return
  ///     A QueueSP for the queue that is currently associated with this
  ///     thread.
  ///     An empty shared pointer indicates that this thread is not
  ///     associated with a queue, or libdispatch queues are not
  ///     supported on this target.
  virtual lldb::QueueSP GetQueue() { return lldb::QueueSP(); }

  /// Retrieve the address of the libdispatch_queue_t struct for queue
  /// currently using this Thread
  ///
  /// If this Thread is doing work on behalf of a libdispatch/GCD queue,
  /// retrieve the address of the libdispatch_queue_t structure describing
  /// the queue.
  ///
  /// This address may be reused for different queues later in the Process
  /// lifetime and should not be used to identify a queue uniquely.  Use
  /// the GetQueueID() call for that.
  ///
  /// \return
  ///     The Queue's libdispatch_queue_t address if the Thread subclass
  ///     implements this, else LLDB_INVALID_ADDRESS.
  virtual lldb::addr_t GetQueueLibdispatchQueueAddress() {
    return LLDB_INVALID_ADDRESS;
  }

  virtual void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) {}

  /// Whether this Thread already has all the Queue information cached or not
  ///
  /// A Thread may be associated with a libdispatch work Queue at a given
  /// public stop event.  If so, the thread can satisify requests like
  /// GetQueueLibdispatchQueueAddress, GetQueueKind, GetQueueName, and
  /// GetQueueID
  /// either from information from the remote debug stub when it is initially
  /// created, or it can query the SystemRuntime for that information.
  ///
  /// This method allows the SystemRuntime to discover if a thread has this
  /// information already, instead of calling the thread to get the information
  /// and having the thread call the SystemRuntime again.
  virtual bool ThreadHasQueueInformation() const { return false; }

  virtual uint32_t GetStackFrameCount() {
    return GetStackFrameList()->GetNumFrames();
  }

  virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx) {
    return GetStackFrameList()->GetFrameAtIndex(idx);
  }

  virtual lldb::StackFrameSP
  GetFrameWithConcreteFrameIndex(uint32_t unwind_idx);

  bool DecrementCurrentInlinedDepth() {
    return GetStackFrameList()->DecrementCurrentInlinedDepth();
  }

  uint32_t GetCurrentInlinedDepth() {
    return GetStackFrameList()->GetCurrentInlinedDepth();
  }

  Status ReturnFromFrameWithIndex(uint32_t frame_idx,
                                  lldb::ValueObjectSP return_value_sp,
                                  bool broadcast = false);

  Status ReturnFromFrame(lldb::StackFrameSP frame_sp,
                         lldb::ValueObjectSP return_value_sp,
                         bool broadcast = false);

  Status JumpToLine(const FileSpec &file, uint32_t line,
                    bool can_leave_function, std::string *warnings = nullptr);

  virtual lldb::StackFrameSP GetFrameWithStackID(const StackID &stack_id) {
    if (stack_id.IsValid())
      return GetStackFrameList()->GetFrameWithStackID(stack_id);
    return lldb::StackFrameSP();
  }

  uint32_t GetSelectedFrameIndex() {
    return GetStackFrameList()->GetSelectedFrameIndex();
  }

  lldb::StackFrameSP GetSelectedFrame();

  uint32_t SetSelectedFrame(lldb_private::StackFrame *frame,
                            bool broadcast = false);

  bool SetSelectedFrameByIndex(uint32_t frame_idx, bool broadcast = false);

  bool SetSelectedFrameByIndexNoisily(uint32_t frame_idx,
                                      Stream &output_stream);

  void SetDefaultFileAndLineToSelectedFrame() {
    GetStackFrameList()->SetDefaultFileAndLineToSelectedFrame();
  }

  virtual lldb::RegisterContextSP GetRegisterContext() = 0;

  virtual lldb::RegisterContextSP
  CreateRegisterContextForFrame(StackFrame *frame) = 0;

  virtual void ClearStackFrames();

  virtual bool SetBackingThread(const lldb::ThreadSP &thread_sp) {
    return false;
  }

  virtual lldb::ThreadSP GetBackingThread() const { return lldb::ThreadSP(); }

  virtual void ClearBackingThread() {
    // Subclasses can use this function if a thread is actually backed by
    // another thread. This is currently used for the OperatingSystem plug-ins
    // where they might have a thread that is in memory, yet its registers are
    // available through the lldb_private::Thread subclass for the current
    // lldb_private::Process class. Since each time the process stops the
    // backing threads for memory threads can change, we need a way to clear
    // the backing thread for all memory threads each time we stop.
  }

  /// Dump \a count instructions of the thread's \a Trace starting at the \a
  /// start_position position in reverse order.
  ///
  /// The instructions are indexed in reverse order, which means that the \a
  /// start_position 0 represents the last instruction of the trace
  /// chronologically.
  ///
  /// \param[in] s
  ///   The stream object where the instructions are printed.
  ///
  /// \param[in] count
  ///     The number of instructions to print.
  ///
  /// \param[in] start_position
  ///     The position of the first instruction to print.
  void DumpTraceInstructions(Stream &s, size_t count,
                             size_t start_position = 0) const;

  // If stop_format is true, this will be the form used when we print stop
  // info. If false, it will be the form we use for thread list and co.
  void DumpUsingSettingsFormat(Stream &strm, uint32_t frame_idx,
                               bool stop_format);

  bool GetDescription(Stream &s, lldb::DescriptionLevel level,
                      bool print_json_thread, bool print_json_stopinfo);

  /// Default implementation for stepping into.
  ///
  /// This function is designed to be used by commands where the
  /// process is publicly stopped.
  ///
  /// \param[in] source_step
  ///     If true and the frame has debug info, then do a source level
  ///     step in, else do a single instruction step in.
  ///
  /// \param[in] step_in_avoids_code_without_debug_info
  ///     If \a true, then avoid stepping into code that doesn't have
  ///     debug info, else step into any code regardless of whether it
  ///     has debug info.
  ///
  /// \param[in] step_out_avoids_code_without_debug_info
  ///     If \a true, then if you step out to code with no debug info, keep
  ///     stepping out till you get to code with debug info.
  ///
  /// \return
  ///     An error that describes anything that went wrong
  virtual Status
  StepIn(bool source_step,
         LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate,
         LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);

  /// Default implementation for stepping over.
  ///
  /// This function is designed to be used by commands where the
  /// process is publicly stopped.
  ///
  /// \param[in] source_step
  ///     If true and the frame has debug info, then do a source level
  ///     step over, else do a single instruction step over.
  ///
  /// \return
  ///     An error that describes anything that went wrong
  virtual Status StepOver(
      bool source_step,
      LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);

  /// Default implementation for stepping out.
  ///
  /// This function is designed to be used by commands where the
  /// process is publicly stopped.
  ///
  /// \return
  ///     An error that describes anything that went wrong
  virtual Status StepOut();

  /// Retrieves the per-thread data area.
  /// Most OSs maintain a per-thread pointer (e.g. the FS register on
  /// x64), which we return the value of here.
  ///
  /// \return
  ///     LLDB_INVALID_ADDRESS if not supported, otherwise the thread
  ///     pointer value.
  virtual lldb::addr_t GetThreadPointer();

  /// Retrieves the per-module TLS block for a thread.
  ///
  /// \param[in] module
  ///     The module to query TLS data for.
  ///
  /// \param[in] tls_file_addr
  ///     The thread local address in module
  /// \return
  ///     If the thread has TLS data allocated for the
  ///     module, the address of the TLS block. Otherwise
  ///     LLDB_INVALID_ADDRESS is returned.
  virtual lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
                                          lldb::addr_t tls_file_addr);

  /// Check whether this thread is safe to run functions
  ///
  /// The SystemRuntime may know of certain thread states (functions in
  /// process of execution, for instance) which can make it unsafe for
  /// functions to be called.
  ///
  /// \return
  ///     True if it is safe to call functions on this thread.
  ///     False if function calls should be avoided on this thread.
  virtual bool SafeToCallFunctions();

  // Thread Plan Providers:
  // This section provides the basic thread plans that the Process control
  // machinery uses to run the target.  ThreadPlan.h provides more details on
  // how this mechanism works. The thread provides accessors to a set of plans
  // that perform basic operations. The idea is that particular Platform
  // plugins can override these methods to provide the implementation of these
  // basic operations appropriate to their environment.
  //
  // NB: All the QueueThreadPlanXXX providers return Shared Pointers to
  // Thread plans.  This is useful so that you can modify the plans after
  // creation in ways specific to that plan type.  Also, it is often necessary
  // for ThreadPlans that utilize other ThreadPlans to implement their task to
  // keep a shared pointer to the sub-plan. But besides that, the shared
  // pointers should only be held onto by entities who live no longer than the
  // thread containing the ThreadPlan.
  // FIXME: If this becomes a problem, we can make a version that just returns a
  // pointer,
  // which it is clearly unsafe to hold onto, and a shared pointer version, and
  // only allow ThreadPlan and Co. to use the latter.  That is made more
  // annoying to do because there's no elegant way to friend a method to all
  // sub-classes of a given class.
  //

  /// Queues the base plan for a thread.
  /// The version returned by Process does some things that are useful,
  /// like handle breakpoints and signals, so if you return a plugin specific
  /// one you probably want to call through to the Process one for anything
  /// your plugin doesn't explicitly handle.
  ///
  /// \param[in] abort_other_plans
  ///    \b true if we discard the currently queued plans and replace them with
  ///    this one.
  ///    Otherwise this plan will go on the end of the plan stack.
  ///
  /// \return
  ///     A shared pointer to the newly queued thread plan, or nullptr if the
  ///     plan could not be queued.
  lldb::ThreadPlanSP QueueBasePlan(bool abort_other_plans);

  /// Queues the plan used to step one instruction from the current PC of \a
  /// thread.
  ///
  /// \param[in] step_over
  ///    \b true if we step over calls to functions, false if we step in.
  ///
  /// \param[in] abort_other_plans
  ///    \b true if we discard the currently queued plans and replace them with
  ///    this one.
  ///    Otherwise this plan will go on the end of the plan stack.
  ///
  /// \param[in] stop_other_threads
  ///    \b true if we will stop other threads while we single step this one.
  ///
  /// \param[out] status
  ///     A status with an error if queuing failed.
  ///
  /// \return
  ///     A shared pointer to the newly queued thread plan, or nullptr if the
  ///     plan could not be queued.
  virtual lldb::ThreadPlanSP QueueThreadPlanForStepSingleInstruction(
      bool step_over, bool abort_other_plans, bool stop_other_threads,
      Status &status);

  /// Queues the plan used to step through an address range, stepping  over
  /// function calls.
  ///
  /// \param[in] abort_other_plans
  ///    \b true if we discard the currently queued plans and replace them with
  ///    this one.
  ///    Otherwise this plan will go on the end of the plan stack.
  ///
  /// \param[in] type
  ///    Type of step to do, only eStepTypeInto and eStepTypeOver are supported
  ///    by this plan.
  ///
  /// \param[in] range
  ///    The address range to step through.
  ///
  /// \param[in] addr_context
  ///    When dealing with stepping through inlined functions the current PC is
  ///    not enough information to know
  ///    what "step" means.  For instance a series of nested inline functions
  ///    might start at the same address.
  //     The \a addr_context provides the current symbol context the step
  ///    is supposed to be out of.
  //   FIXME: Currently unused.
  ///
  /// \param[in] stop_other_threads
  ///    \b true if we will stop other threads while we single step this one.
  ///
  /// \param[out] status
  ///     A status with an error if queuing failed.
  ///
  /// \param[in] step_out_avoids_code_without_debug_info
  ///    If eLazyBoolYes, if the step over steps out it will continue to step
  ///    out till it comes to a frame with debug info.
  ///    If eLazyBoolCalculate, we will consult the default set in the thread.
  ///
  /// \return
  ///     A shared pointer to the newly queued thread plan, or nullptr if the
  ///     plan could not be queued.
  virtual lldb::ThreadPlanSP QueueThreadPlanForStepOverRange(
      bool abort_other_plans, const AddressRange &range,
      const SymbolContext &addr_context, lldb::RunMode stop_other_threads,
      Status &status,
      LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);

  // Helper function that takes a LineEntry to step, insted of an AddressRange.
  // This may combine multiple LineEntries of the same source line number to
  // step over a longer address range in a single operation.
  virtual lldb::ThreadPlanSP 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_without_debug_info = eLazyBoolCalculate);

  /// Queues the plan used to step through an address range, stepping into
  /// functions.
  ///
  /// \param[in] abort_other_plans
  ///    \b true if we discard the currently queued plans and replace them with
  ///    this one.
  ///    Otherwise this plan will go on the end of the plan stack.
  ///
  /// \param[in] type
  ///    Type of step to do, only eStepTypeInto and eStepTypeOver are supported
  ///    by this plan.
  ///
  /// \param[in] range
  ///    The address range to step through.
  ///
  /// \param[in] addr_context
  ///    When dealing with stepping through inlined functions the current PC is
  ///    not enough information to know
  ///    what "step" means.  For instance a series of nested inline functions
  ///    might start at the same address.
  //     The \a addr_context provides the current symbol context the step
  ///    is supposed to be out of.
  //   FIXME: Currently unused.
  ///
  /// \param[in] step_in_target
  ///    Name if function we are trying to step into.  We will step out if we
  ///    don't land in that function.
  ///
  /// \param[in] stop_other_threads
  ///    \b true if we will stop other threads while we single step this one.
  ///
  /// \param[out] status
  ///     A status with an error if queuing failed.
  ///
  /// \param[in] step_in_avoids_code_without_debug_info
  ///    If eLazyBoolYes we will step out if we step into code with no debug
  ///    info.
  ///    If eLazyBoolCalculate we will consult the default set in the thread.
  ///
  /// \param[in] step_out_avoids_code_without_debug_info
  ///    If eLazyBoolYes, if the step over steps out it will continue to step
  ///    out till it comes to a frame with debug info.
  ///    If eLazyBoolCalculate, it will consult the default set in the thread.
  ///
  /// \return
  ///     A shared pointer to the newly queued thread plan, or nullptr if the
  ///     plan could not be queued.
  virtual lldb::ThreadPlanSP 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 = eLazyBoolCalculate,
      LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);

  // Helper function that takes a LineEntry to step, insted of an AddressRange.
  // This may combine multiple LineEntries of the same source line number to
  // step over a longer address range in a single operation.
  virtual lldb::ThreadPlanSP 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 = eLazyBoolCalculate,
      LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);

  /// Queue the plan used to step out of the function at the current PC of
  /// \a thread.
  ///
  /// \param[in] abort_other_plans
  ///    \b true if we discard the currently queued plans and replace them with
  ///    this one.
  ///    Otherwise this plan will go on the end of the plan stack.
  ///
  /// \param[in] addr_context
  ///    When dealing with stepping through inlined functions the current PC is
  ///    not enough information to know
  ///    what "step" means.  For instance a series of nested inline functions
  ///    might start at the same address.
  //     The \a addr_context provides the current symbol context the step
  ///    is supposed to be out of.
  //   FIXME: Currently unused.
  ///
  /// \param[in] first_insn
  ///     \b true if this is the first instruction of a function.
  ///
  /// \param[in] stop_other_threads
  ///    \b true if we will stop other threads while we single step this one.
  ///
  /// \param[in] report_stop_vote
  ///    See standard meanings for the stop & run votes in ThreadPlan.h.
  ///
  /// \param[in] report_run_vote
  ///    See standard meanings for the stop & run votes in ThreadPlan.h.
  ///
  /// \param[out] status
  ///     A status with an error if queuing failed.
  ///
  /// \param[in] step_out_avoids_code_without_debug_info
  ///    If eLazyBoolYes, if the step over steps out it will continue to step
  ///    out till it comes to a frame with debug info.
  ///    If eLazyBoolCalculate, it will consult the default set in the thread.
  ///
  /// \return
  ///     A shared pointer to the newly queued thread plan, or nullptr if the
  ///     plan could not be queued.
  virtual lldb::ThreadPlanSP 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 = eLazyBoolCalculate);

  /// Queue the plan used to step out of the function at the current PC of
  /// a thread.  This version does not consult the should stop here callback,
  /// and should only
  /// be used by other thread plans when they need to retain control of the step
  /// out.
  ///
  /// \param[in] abort_other_plans
  ///    \b true if we discard the currently queued plans and replace them with
  ///    this one.
  ///    Otherwise this plan will go on the end of the plan stack.
  ///
  /// \param[in] addr_context
  ///    When dealing with stepping through inlined functions the current PC is
  ///    not enough information to know
  ///    what "step" means.  For instance a series of nested inline functions
  ///    might start at the same address.
  //     The \a addr_context provides the current symbol context the step
  ///    is supposed to be out of.
  //   FIXME: Currently unused.
  ///
  /// \param[in] first_insn
  ///     \b true if this is the first instruction of a function.
  ///
  /// \param[in] stop_other_threads
  ///    \b true if we will stop other threads while we single step this one.
  ///
  /// \param[in] report_stop_vote
  ///    See standard meanings for the stop & run votes in ThreadPlan.h.
  ///
  /// \param[in] report_run_vote
  ///    See standard meanings for the stop & run votes in ThreadPlan.h.
  ///
  /// \param[in] frame_idx
  ///     The fame index.
  ///
  /// \param[out] status
  ///     A status with an error if queuing failed.
  ///
  /// \param[in] continue_to_next_branch
  ///    Normally this will enqueue a plan that will put a breakpoint on the
  ///    return address and continue
  ///    to there.  If continue_to_next_branch is true, this is an operation not
  ///    involving the user --
  ///    e.g. stepping "next" in a source line and we instruction stepped into
  ///    another function --
  ///    so instead of putting a breakpoint on the return address, advance the
  ///    breakpoint to the
  ///    end of the source line that is doing the call, or until the next flow
  ///    control instruction.
  ///    If the return value from the function call is to be retrieved /
  ///    displayed to the user, you must stop
  ///    on the return address.  The return value may be stored in volatile
  ///    registers which are overwritten
  ///    before the next branch instruction.
  ///
  /// \return
  ///     A shared pointer to the newly queued thread plan, or nullptr if the
  ///     plan could not be queued.
  virtual lldb::ThreadPlanSP 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 = false);

  /// Gets the plan used to step through the code that steps from a function
  /// call site at the current PC into the actual function call.
  ///
  /// \param[in] return_stack_id
  ///    The stack id that we will return to (by setting backstop breakpoints on
  ///    the return
  ///    address to that frame) if we fail to step through.
  ///
  /// \param[in] abort_other_plans
  ///    \b true if we discard the currently queued plans and replace them with
  ///    this one.
  ///    Otherwise this plan will go on the end of the plan stack.
  ///
  /// \param[in] stop_other_threads
  ///    \b true if we will stop other threads while we single step this one.
  ///
  /// \param[out] status
  ///     A status with an error if queuing failed.
  ///
  /// \return
  ///     A shared pointer to the newly queued thread plan, or nullptr if the
  ///     plan could not be queued.
  virtual lldb::ThreadPlanSP
  QueueThreadPlanForStepThrough(StackID &return_stack_id,
                                bool abort_other_plans, bool stop_other_threads,
                                Status &status);

  /// Gets the plan used to continue from the current PC.
  /// This is a simple plan, mostly useful as a backstop when you are continuing
  /// for some particular purpose.
  ///
  /// \param[in] abort_other_plans
  ///    \b true if we discard the currently queued plans and replace them with
  ///    this one.
  ///    Otherwise this plan will go on the end of the plan stack.
  ///
  /// \param[in] target_addr
  ///    The address to which we're running.
  ///
  /// \param[in] stop_other_threads
  ///    \b true if we will stop other threads while we single step this one.
  ///
  /// \param[out] status
  ///     A status with an error if queuing failed.
  ///
  /// \return
  ///     A shared pointer to the newly queued thread plan, or nullptr if the
  ///     plan could not be queued.
  virtual lldb::ThreadPlanSP
  QueueThreadPlanForRunToAddress(bool abort_other_plans, Address &target_addr,
                                 bool stop_other_threads, Status &status);

  virtual lldb::ThreadPlanSP QueueThreadPlanForStepUntil(
      bool abort_other_plans, lldb::addr_t *address_list, size_t num_addresses,
      bool stop_others, uint32_t frame_idx, Status &status);

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

  // Thread Plan accessors:

  /// Format the thread plan information for auto completion.
  ///
  /// \param[in] request
  ///     The reference to the completion handler.
  void AutoCompleteThreadPlans(CompletionRequest &request) const;

  /// Gets the plan which will execute next on the plan stack.
  ///
  /// \return
  ///     A pointer to the next executed plan.
  ThreadPlan *GetCurrentPlan() const;

  /// Unwinds the thread stack for the innermost expression plan currently
  /// on the thread plan stack.
  ///
  /// \return
  ///     An error if the thread plan could not be unwound.

  Status UnwindInnermostExpression();

  /// Gets the outer-most plan that was popped off the plan stack in the
  /// most recent stop.  Useful for printing the stop reason accurately.
  ///
  /// \return
  ///     A pointer to the last completed plan.
  lldb::ThreadPlanSP GetCompletedPlan() const;

  /// Gets the outer-most return value from the completed plans
  ///
  /// \return
  ///     A ValueObjectSP, either empty if there is no return value,
  ///     or containing the return value.
  lldb::ValueObjectSP GetReturnValueObject() const;

  /// Gets the outer-most expression variable from the completed plans
  ///
  /// \return
  ///     A ExpressionVariableSP, either empty if there is no
  ///     plan completed an expression during the current stop
  ///     or the expression variable that was made for the completed expression.
  lldb::ExpressionVariableSP GetExpressionVariable() const;

  ///  Checks whether the given plan is in the completed plans for this
  ///  stop.
  ///
  /// \param[in] plan
  ///     Pointer to the plan you're checking.
  ///
  /// \return
  ///     Returns true if the input plan is in the completed plan stack,
  ///     false otherwise.
  bool IsThreadPlanDone(ThreadPlan *plan) const;

  ///  Checks whether the given plan is in the discarded plans for this
  ///  stop.
  ///
  /// \param[in] plan
  ///     Pointer to the plan you're checking.
  ///
  /// \return
  ///     Returns true if the input plan is in the discarded plan stack,
  ///     false otherwise.
  bool WasThreadPlanDiscarded(ThreadPlan *plan) const;

  /// Check if we have completed plan to override breakpoint stop reason
  ///
  /// \return
  ///     Returns true if completed plan stack is not empty
  ///     false otherwise.
  bool CompletedPlanOverridesBreakpoint() const;

  /// Queues a generic thread plan.
  ///
  /// \param[in] plan_sp
  ///    The plan to queue.
  ///
  /// \param[in] abort_other_plans
  ///    \b true if we discard the currently queued plans and replace them with
  ///    this one.
  ///    Otherwise this plan will go on the end of the plan stack.
  ///
  /// \return
  ///     A pointer to the last completed plan.
  Status QueueThreadPlan(lldb::ThreadPlanSP &plan_sp, bool abort_other_plans);

  /// Discards the plans queued on the plan stack of the current thread.  This
  /// is
  /// arbitrated by the "Master" ThreadPlans, using the "OkayToDiscard" call.
  //  But if \a force is true, all thread plans are discarded.
  void DiscardThreadPlans(bool force);

  /// Discards the plans queued on the plan stack of the current thread up to
  /// and
  /// including up_to_plan_sp.
  //
  // \param[in] up_to_plan_sp
  //   Discard all plans up to and including this one.
  void DiscardThreadPlansUpToPlan(lldb::ThreadPlanSP &up_to_plan_sp);

  void DiscardThreadPlansUpToPlan(ThreadPlan *up_to_plan_ptr);

  /// Discards the plans queued on the plan stack of the current thread up to
  /// and
  /// including the plan in that matches \a thread_index counting only
  /// the non-Private plans.
  ///
  /// \param[in] thread_index
  ///   Discard all plans up to and including this user plan given by this
  ///   index.
  ///
  /// \return
  ///    \b true if there was a thread plan with that user index, \b false
  ///    otherwise.
  bool DiscardUserThreadPlansUpToIndex(uint32_t thread_index);

  virtual bool CheckpointThreadState(ThreadStateCheckpoint &saved_state);

  virtual bool
  RestoreRegisterStateFromCheckpoint(ThreadStateCheckpoint &saved_state);

  void RestoreThreadStateFromCheckpoint(ThreadStateCheckpoint &saved_state);

  // Get the thread index ID. The index ID that is guaranteed to not be re-used
  // by a process. They start at 1 and increase with each new thread. This
  // allows easy command line access by a unique ID that is easier to type than
  // the actual system thread ID.
  uint32_t GetIndexID() const;

  // Get the originating thread's index ID.
  // In the case of an "extended" thread -- a thread which represents the stack
  // that enqueued/spawned work that is currently executing -- we need to
  // provide the IndexID of the thread that actually did this work.  We don't
  // want to just masquerade as that thread's IndexID by using it in our own
  // IndexID because that way leads to madness - but the driver program which
  // is iterating over extended threads may ask for the OriginatingThreadID to
  // display that information to the user.
  // Normal threads will return the same thing as GetIndexID();
  virtual uint32_t GetExtendedBacktraceOriginatingIndexID() {
    return GetIndexID();
  }

  // The API ID is often the same as the Thread::GetID(), but not in all cases.
  // Thread::GetID() is the user visible thread ID that clients would want to
  // see. The API thread ID is the thread ID that is used when sending data
  // to/from the debugging protocol.
  virtual lldb::user_id_t GetProtocolID() const { return GetID(); }

  // lldb::ExecutionContextScope pure virtual functions
  lldb::TargetSP CalculateTarget() override;

  lldb::ProcessSP CalculateProcess() override;

  lldb::ThreadSP CalculateThread() override;

  lldb::StackFrameSP CalculateStackFrame() override;

  void CalculateExecutionContext(ExecutionContext &exe_ctx) override;

  lldb::StackFrameSP
  GetStackFrameSPForStackFramePtr(StackFrame *stack_frame_ptr);

  size_t GetStatus(Stream &strm, uint32_t start_frame, uint32_t num_frames,
                   uint32_t num_frames_with_source, bool stop_format,
                   bool only_stacks = false);

  size_t GetStackFrameStatus(Stream &strm, uint32_t first_frame,
                             uint32_t num_frames, bool show_frame_info,
                             uint32_t num_frames_with_source);

  // We need a way to verify that even though we have a thread in a shared
  // pointer that the object itself is still valid. Currently this won't be the
  // case if DestroyThread() was called. DestroyThread is called when a thread
  // has been removed from the Process' thread list.
  bool IsValid() const { return !m_destroy_called; }

  // Sets and returns a valid stop info based on the process stop ID and the
  // current thread plan. If the thread stop ID does not match the process'
  // stop ID, the private stop reason is not set and an invalid StopInfoSP may
  // be returned.
  //
  // NOTE: This function must be called before the current thread plan is
  // moved to the completed plan stack (in Thread::ShouldStop()).
  //
  // NOTE: If subclasses override this function, ensure they do not overwrite
  // the m_actual_stop_info if it is valid.  The stop info may be a
  // "checkpointed and restored" stop info, so if it is still around it is
  // right even if you have not calculated this yourself, or if it disagrees
  // with what you might have calculated.
  virtual lldb::StopInfoSP GetPrivateStopInfo();

  // Calculate the stop info that will be shown to lldb clients.  For instance,
  // a "step out" is implemented by running to a breakpoint on the function
  // return PC, so the process plugin initially sets the stop info to a
  // StopInfoBreakpoint. But once we've run the ShouldStop machinery, we
  // discover that there's a completed ThreadPlanStepOut, and that's really
  // the StopInfo we want to show.  That will happen naturally the next
  // time GetStopInfo is called, but if you want to force the replacement,
  // you can call this.

  void CalculatePublicStopInfo();

  // Ask the thread subclass to set its stop info.
  //
  // Thread subclasses should call Thread::SetStopInfo(...) with the reason the
  // thread stopped.
  //
  // \return
  //      True if Thread::SetStopInfo(...) was called, false otherwise.
  virtual bool CalculateStopInfo() = 0;

  // Gets the temporary resume state for a thread.
  //
  // This value gets set in each thread by complex debugger logic in
  // Thread::ShouldResume() and an appropriate thread resume state will get set
  // in each thread every time the process is resumed prior to calling
  // Process::DoResume(). The lldb_private::Process subclass should adhere to
  // the thread resume state request which will be one of:
  //
  //  eStateRunning   - thread will resume when process is resumed
  //  eStateStepping  - thread should step 1 instruction and stop when process
  //                    is resumed
  //  eStateSuspended - thread should not execute any instructions when
  //                    process is resumed
  lldb::StateType GetTemporaryResumeState() const {
    return m_temporary_resume_state;
  }

  void SetStopInfo(const lldb::StopInfoSP &stop_info_sp);

  void ResetStopInfo();

  void SetShouldReportStop(Vote vote);

  /// Sets the extended backtrace token for this thread
  ///
  /// Some Thread subclasses may maintain a token to help with providing
  /// an extended backtrace.  The SystemRuntime plugin will set/request this.
  ///
  /// \param [in] token The extended backtrace token.
  virtual void SetExtendedBacktraceToken(uint64_t token) {}

  /// Gets the extended backtrace token for this thread
  ///
  /// Some Thread subclasses may maintain a token to help with providing
  /// an extended backtrace.  The SystemRuntime plugin will set/request this.
  ///
  /// \return
  ///     The token needed by the SystemRuntime to create an extended backtrace.
  ///     LLDB_INVALID_ADDRESS is returned if no token is available.
  virtual uint64_t GetExtendedBacktraceToken() { return LLDB_INVALID_ADDRESS; }

  lldb::ValueObjectSP GetCurrentException();

  lldb::ThreadSP GetCurrentExceptionBacktrace();

protected:
  friend class ThreadPlan;
  friend class ThreadList;
  friend class ThreadEventData;
  friend class StackFrameList;
  friend class StackFrame;
  friend class OperatingSystem;

  // This is necessary to make sure thread assets get destroyed while the
  // thread is still in good shape to call virtual thread methods.  This must
  // be called by classes that derive from Thread in their destructor.
  virtual void DestroyThread();

  ThreadPlanStack &GetPlans() const;

  void PushPlan(lldb::ThreadPlanSP plan_sp);

  void PopPlan();

  void DiscardPlan();

  ThreadPlan *GetPreviousPlan(ThreadPlan *plan) const;

  virtual Unwind &GetUnwinder();

  // Check to see whether the thread is still at the last breakpoint hit that
  // stopped it.
  virtual bool IsStillAtLastBreakpointHit();

  // Some threads are threads that are made up by OperatingSystem plugins that
  // are threads that exist and are context switched out into memory. The
  // OperatingSystem plug-in need a ways to know if a thread is "real" or made
  // up.
  virtual bool IsOperatingSystemPluginThread() const { return false; }

  // Subclasses that have a way to get an extended info dictionary for this
  // thread should fill
  virtual lldb_private::StructuredData::ObjectSP FetchThreadExtendedInfo() {
    return StructuredData::ObjectSP();
  }

  lldb::StackFrameListSP GetStackFrameList();

  void SetTemporaryResumeState(lldb::StateType new_state) {
    m_temporary_resume_state = new_state;
  }

  void FrameSelectedCallback(lldb_private::StackFrame *frame);

  // Classes that inherit from Process can see and modify these
  lldb::ProcessWP m_process_wp;    ///< The process that owns this thread.
  lldb::StopInfoSP m_stop_info_sp; ///< The private stop reason for this thread
  uint32_t m_stop_info_stop_id; // This is the stop id for which the StopInfo is
                                // valid.  Can use this so you know that
  // the thread's m_stop_info_sp is current and you don't have to fetch it
  // again
  uint32_t m_stop_info_override_stop_id; // The stop ID containing the last time
                                         // the stop info was checked against
                                         // the stop info override
  const uint32_t m_index_id; ///< A unique 1 based index assigned to each thread
                             ///for easy UI/command line access.
  lldb::RegisterContextSP m_reg_context_sp; ///< The register context for this
                                            ///thread's current register state.
  lldb::StateType m_state;                  ///< The state of our process.
  mutable std::recursive_mutex
      m_state_mutex;       ///< Multithreaded protection for m_state.
  mutable std::recursive_mutex
      m_frame_mutex; ///< Multithreaded protection for m_state.
  lldb::StackFrameListSP m_curr_frames_sp; ///< The stack frames that get lazily
                                           ///populated after a thread stops.
  lldb::StackFrameListSP m_prev_frames_sp; ///< The previous stack frames from
                                           ///the last time this thread stopped.
  int m_resume_signal; ///< The signal that should be used when continuing this
                       ///thread.
  lldb::StateType m_resume_state; ///< This state is used to force a thread to
                                  ///be suspended from outside the ThreadPlan
                                  ///logic.
  lldb::StateType m_temporary_resume_state; ///< This state records what the
                                            ///thread was told to do by the
                                            ///thread plan logic for the current
                                            ///resume.
  /// It gets set in Thread::ShouldResume.
  std::unique_ptr<lldb_private::Unwind> m_unwinder_up;
  bool m_destroy_called; // This is used internally to make sure derived Thread
                         // classes call DestroyThread.
  LazyBool m_override_should_notify;
  mutable std::unique_ptr<ThreadPlanStack> m_null_plan_stack_up;

private:
  bool m_extended_info_fetched; // Have we tried to retrieve the m_extended_info
                                // for this thread?
  StructuredData::ObjectSP m_extended_info; // The extended info for this thread

  void BroadcastSelectedFrameChange(StackID &new_frame_id);

  Thread(const Thread &) = delete;
  const Thread &operator=(const Thread &) = delete;
};

} // namespace lldb_private

#endif // LLDB_TARGET_THREAD_H
