//===-- 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 liblldb_Thread_h_
#define liblldb_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/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 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;

    DISALLOW_COPY_AND_ASSIGN(ThreadEventData);
  };

  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.
    std::vector<lldb::ThreadPlanSP> m_completed_plan_stack;
    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] process
  ///
  /// \param [in] tid
  ///
  /// \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.
  /// \return
  ///    The User resume state for this thread.
  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 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 const char *RunModeAsCString(lldb::RunMode mode);

  static const char *StopReasonAsCString(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.
  }

  // 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.
  virtual lldb::ThreadPlanSP QueueFundamentalPlan(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] stop_vote
  /// \param[in] 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 stop_vote, Vote 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] stop_vote
  ///
  /// \param[in] run_vote
  ///    See standard meanings for the stop & run votes in ThreadPlan.h.
  ///
  /// \param[in] frame_idx
  ///
  /// \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 stop_vote, Vote 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,
                                 bool stop_other_threads, Status &status);

  // Thread Plan accessors:

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

  /// 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();

  /// 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();

  /// 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();

  ///  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);

  ///  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);

  /// 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();

  /// 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] up_to_plan_sp
  ///   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);

  /// Prints the current plan stack.
  ///
  /// \param[in] s
  ///    The stream to which to dump the plan stack info.
  ///
  void DumpThreadPlans(
      Stream *s,
      lldb::DescriptionLevel desc_level = lldb::eDescriptionLevelVerbose,
      bool include_internal = true, bool ignore_boring = false) const;

  virtual bool CheckpointThreadState(ThreadStateCheckpoint &saved_state);

  virtual bool
  RestoreRegisterStateFromCheckpoint(ThreadStateCheckpoint &saved_state);

  virtual bool
  RestoreThreadStateFromCheckpoint(ThreadStateCheckpoint &saved_state);

  void EnableTracer(bool value, bool single_step);

  void SetTracer(lldb::ThreadPlanTracerSP &tracer_sp);

  // 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();

  // 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
  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();

  void PushPlan(lldb::ThreadPlanSP &plan_sp);

  void PopPlan();

  void DiscardPlan();

  ThreadPlan *GetPreviousPlan(ThreadPlan *plan);

  typedef std::vector<lldb::ThreadPlanSP> plan_stack;

  virtual lldb_private::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 FunctionOptimizationWarning(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.
  plan_stack m_plan_stack; ///< The stack of plans this thread is executing.
  plan_stack m_completed_plan_stack; ///< Plans that have been completed by this
                                     ///stop.  They get deleted when the thread
                                     ///resumes.
  plan_stack m_discarded_plan_stack; ///< Plans that have been discarded by this
                                     ///stop.  They get deleted when the thread
                                     ///resumes.
  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;

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

private:
  bool PlanIsBasePlan(ThreadPlan *plan_ptr);

  void BroadcastSelectedFrameChange(StackID &new_frame_id);

  DISALLOW_COPY_AND_ASSIGN(Thread);
};

} // namespace lldb_private

#endif // liblldb_Thread_h_
