| //===-- Thread.h ------------------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef liblldb_Thread_h_ |
| #define liblldb_Thread_h_ |
| |
| #include "lldb/lldb-private.h" |
| #include "lldb/Host/Mutex.h" |
| #include "lldb/Core/UserID.h" |
| #include "lldb/Core/UserSettingsController.h" |
| #include "lldb/Target/ExecutionContextScope.h" |
| #include "lldb/Target/StackFrameList.h" |
| |
| #define LLDB_THREAD_MAX_STOP_EXC_DATA 8 |
| |
| namespace lldb_private { |
| |
| class ThreadInstanceSettings : public InstanceSettings |
| { |
| public: |
| |
| ThreadInstanceSettings (const lldb::UserSettingsControllerSP &owner_sp, bool live_instance = true, const char *name = NULL); |
| |
| ThreadInstanceSettings (const ThreadInstanceSettings &rhs); |
| |
| virtual |
| ~ThreadInstanceSettings (); |
| |
| ThreadInstanceSettings& |
| operator= (const ThreadInstanceSettings &rhs); |
| |
| |
| void |
| UpdateInstanceSettingsVariable (const ConstString &var_name, |
| const char *index_value, |
| const char *value, |
| const ConstString &instance_name, |
| const SettingEntry &entry, |
| VarSetOperationType op, |
| Error &err, |
| bool pending); |
| |
| bool |
| GetInstanceSettingsValue (const SettingEntry &entry, |
| const ConstString &var_name, |
| StringList &value, |
| Error *err); |
| |
| RegularExpression * |
| GetSymbolsToAvoidRegexp() |
| { |
| return m_avoid_regexp_ap.get(); |
| } |
| |
| static const ConstString & |
| StepAvoidRegexpVarName (); |
| |
| bool |
| GetTraceEnabledState() |
| { |
| return m_trace_enabled; |
| } |
| static const ConstString & |
| GetTraceThreadVarName (); |
| |
| protected: |
| |
| void |
| CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings, |
| bool pending); |
| |
| const ConstString |
| CreateInstanceName (); |
| |
| private: |
| |
| std::auto_ptr<RegularExpression> m_avoid_regexp_ap; |
| bool m_trace_enabled; |
| }; |
| |
| class Thread : |
| public STD_ENABLE_SHARED_FROM_THIS(Thread), |
| public UserID, |
| public ExecutionContextScope, |
| public ThreadInstanceSettings |
| { |
| public: |
| |
| class SettingsController : public UserSettingsController |
| { |
| public: |
| |
| SettingsController (); |
| |
| virtual |
| ~SettingsController (); |
| |
| static SettingEntry global_settings_table[]; |
| static SettingEntry instance_settings_table[]; |
| |
| protected: |
| |
| lldb::InstanceSettingsSP |
| CreateInstanceSettings (const char *instance_name); |
| |
| private: |
| |
| // Class-wide settings. |
| |
| DISALLOW_COPY_AND_ASSIGN (SettingsController); |
| }; |
| |
| // TODO: You shouldn't just checkpoint the register state alone, so this should get |
| // moved to protected. To do that ThreadStateCheckpoint needs to be returned as a token... |
| class RegisterCheckpoint |
| { |
| public: |
| |
| RegisterCheckpoint() : |
| m_stack_id (), |
| m_data_sp () |
| { |
| } |
| |
| RegisterCheckpoint (const StackID &stack_id) : |
| m_stack_id (stack_id), |
| m_data_sp () |
| { |
| } |
| |
| ~RegisterCheckpoint() |
| { |
| } |
| |
| const RegisterCheckpoint& |
| operator= (const RegisterCheckpoint &rhs) |
| { |
| if (this != &rhs) |
| { |
| this->m_stack_id = rhs.m_stack_id; |
| this->m_data_sp = rhs.m_data_sp; |
| } |
| return *this; |
| } |
| |
| RegisterCheckpoint (const RegisterCheckpoint &rhs) : |
| m_stack_id (rhs.m_stack_id), |
| m_data_sp (rhs.m_data_sp) |
| { |
| } |
| |
| const StackID & |
| GetStackID() |
| { |
| return m_stack_id; |
| } |
| |
| void |
| SetStackID (const StackID &stack_id) |
| { |
| m_stack_id = stack_id; |
| } |
| |
| lldb::DataBufferSP & |
| GetData() |
| { |
| return m_data_sp; |
| } |
| |
| const lldb::DataBufferSP & |
| GetData() const |
| { |
| return m_data_sp; |
| } |
| |
| protected: |
| StackID m_stack_id; |
| lldb::DataBufferSP m_data_sp; |
| }; |
| |
| 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. |
| RegisterCheckpoint register_backup; // You need to restore the registers, of course... |
| }; |
| |
| void |
| UpdateInstanceName (); |
| |
| static void |
| SettingsInitialize (); |
| |
| static void |
| SettingsTerminate (); |
| |
| static lldb::UserSettingsControllerSP & |
| GetSettingsController (); |
| |
| Thread (const lldb::ProcessSP &process_sp, lldb::tid_t tid); |
| virtual ~Thread(); |
| |
| 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); |
| |
| lldb::StateType |
| GetResumeState () const |
| { |
| return m_resume_state; |
| } |
| |
| void |
| SetResumeState (lldb::StateType state) |
| { |
| m_resume_state = state; |
| } |
| |
| // This function is called on all the threads before "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 (); |
| |
| // Override this to do platform specific tasks before resume, but always |
| // call the Thread::WillResume at the end of your work. |
| |
| virtual bool |
| 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 (); |
| |
| virtual void |
| RefreshStateAfterStop() = 0; |
| |
| void |
| WillStop (); |
| |
| bool |
| ShouldStop (Event *event_ptr); |
| |
| Vote |
| ShouldReportStop (Event *event_ptr); |
| |
| Vote |
| ShouldReportRun (Event *event_ptr); |
| |
| // 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 (); |
| |
| // 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 NULL; |
| } |
| |
| virtual const char * |
| GetName () |
| { |
| return NULL; |
| } |
| |
| virtual const char * |
| GetQueueName () |
| { |
| return NULL; |
| } |
| |
| 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); |
| |
| virtual lldb::StackFrameSP |
| GetFrameWithStackID (const StackID &stack_id) |
| { |
| return GetStackFrameList()->GetFrameWithStackID (stack_id); |
| } |
| |
| uint32_t |
| GetSelectedFrameIndex () |
| { |
| return GetStackFrameList()->GetSelectedFrameIndex(); |
| } |
| |
| lldb::StackFrameSP |
| GetSelectedFrame () |
| { |
| lldb::StackFrameListSP stack_frame_list_sp(GetStackFrameList()); |
| return stack_frame_list_sp->GetFrameAtIndex (stack_frame_list_sp->GetSelectedFrameIndex()); |
| } |
| |
| uint32_t |
| SetSelectedFrame (lldb_private::StackFrame *frame) |
| { |
| return GetStackFrameList()->SetSelectedFrame(frame); |
| } |
| |
| bool |
| SetSelectedFrameByIndex (uint32_t frame_idx) |
| { |
| return GetStackFrameList()->SetSelectedFrameByIndex(frame_idx); |
| } |
| |
| void |
| SetDefaultFileAndLineToSelectedFrame() |
| { |
| GetStackFrameList()->SetDefaultFileAndLineToSelectedFrame(); |
| } |
| |
| virtual lldb::RegisterContextSP |
| GetRegisterContext () = 0; |
| |
| virtual lldb::RegisterContextSP |
| CreateRegisterContextForFrame (StackFrame *frame) = 0; |
| |
| virtual void |
| ClearStackFrames (); |
| |
| void |
| DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx); |
| |
| //------------------------------------------------------------------ |
| // 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. |
| //------------------------------------------------------------------ |
| |
| //------------------------------------------------------------------ |
| /// 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 pointer to the newly queued thread plan, or NULL if the plan could not be queued. |
| //------------------------------------------------------------------ |
| virtual ThreadPlan * |
| QueueFundamentalPlan (bool abort_other_plans); |
| |
| //------------------------------------------------------------------ |
| /// Queues the plan used to step over a breakpoint at the current PC of \a thread. |
| /// The default version returned by Process handles trap based breakpoints, and |
| /// will disable the breakpoint, single step over it, then re-enable it. |
| /// |
| /// @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 newly queued thread plan, or NULL if the plan could not be queued. |
| //------------------------------------------------------------------ |
| virtual ThreadPlan * |
| QueueThreadPlanForStepOverBreakpointPlan (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. |
| /// |
| /// @return |
| /// A pointer to the newly queued thread plan, or NULL if the plan could not be queued. |
| //------------------------------------------------------------------ |
| virtual ThreadPlan * |
| QueueThreadPlanForStepSingleInstruction (bool step_over, |
| bool abort_other_plans, |
| bool stop_other_threads); |
| |
| //------------------------------------------------------------------ |
| /// Queues the plan used to step through an address range, stepping into or over |
| /// function calls depending on the value of StepType. |
| /// |
| /// @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. |
| /// |
| /// @return |
| /// A pointer to the newly queued thread plan, or NULL if the plan could not be queued. |
| //------------------------------------------------------------------ |
| virtual ThreadPlan * |
| QueueThreadPlanForStepRange (bool abort_other_plans, |
| StepType type, |
| const AddressRange &range, |
| const SymbolContext &addr_context, |
| lldb::RunMode stop_other_threads, |
| bool avoid_code_without_debug_info); |
| |
| //------------------------------------------------------------------ |
| /// 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. |
| /// |
| /// @return |
| /// A pointer to the newly queued thread plan, or NULL if the plan could not be queued. |
| //------------------------------------------------------------------ |
| virtual ThreadPlan * |
| QueueThreadPlanForStepOut (bool abort_other_plans, |
| SymbolContext *addr_context, |
| bool first_insn, |
| bool stop_other_threads, |
| Vote stop_vote, // = eVoteYes, |
| Vote run_vote, // = eVoteNoOpinion); |
| uint32_t frame_idx); |
| |
| //------------------------------------------------------------------ |
| /// 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] 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. |
| /// |
| /// @return |
| /// A pointer to the newly queued thread plan, or NULL if the plan could not be queued. |
| //------------------------------------------------------------------ |
| virtual ThreadPlan * |
| QueueThreadPlanForStepThrough (bool abort_other_plans, |
| bool stop_other_threads); |
| |
| //------------------------------------------------------------------ |
| /// 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. |
| /// |
| /// @return |
| /// A pointer to the newly queued thread plan, or NULL if the plan could not be queued. |
| //------------------------------------------------------------------ |
| virtual ThreadPlan * |
| QueueThreadPlanForRunToAddress (bool abort_other_plans, |
| Address &target_addr, |
| bool stop_other_threads); |
| |
| virtual ThreadPlan * |
| QueueThreadPlanForStepUntil (bool abort_other_plans, |
| lldb::addr_t *address_list, |
| size_t num_addresses, |
| bool stop_others, |
| uint32_t frame_idx); |
| |
| virtual ThreadPlan * |
| QueueThreadPlanForCallFunction (bool abort_other_plans, |
| Address& function, |
| lldb::addr_t arg, |
| bool stop_other_threads, |
| bool discard_on_error = false); |
| |
| //------------------------------------------------------------------ |
| // Thread Plan accessors: |
| //------------------------------------------------------------------ |
| |
| //------------------------------------------------------------------ |
| /// Gets the plan which will execute next on the plan stack. |
| /// |
| /// @return |
| /// A pointer to the next executed plan. |
| //------------------------------------------------------------------ |
| ThreadPlan * |
| GetCurrentPlan (); |
| |
| private: |
| bool |
| PlanIsBasePlan (ThreadPlan *plan_ptr); |
| |
| public: |
| |
| //------------------------------------------------------------------ |
| /// 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 (); |
| |
| //------------------------------------------------------------------ |
| /// 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); |
| |
| //------------------------------------------------------------------ |
| /// 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. |
| //------------------------------------------------------------------ |
| void |
| 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); |
| |
| //------------------------------------------------------------------ |
| /// Prints the current plan stack. |
| /// |
| /// @param[in] s |
| /// The stream to which to dump the plan stack info. |
| /// |
| //------------------------------------------------------------------ |
| void |
| DumpThreadPlans (Stream *s) const; |
| |
| virtual bool |
| CheckpointThreadState (ThreadStateCheckpoint &saved_state); |
| |
| virtual bool |
| RestoreThreadStateFromCheckpoint (ThreadStateCheckpoint &saved_state); |
| |
| void |
| EnableTracer (bool value, bool single_step); |
| |
| void |
| SetTracer (lldb::ThreadPlanTracerSP &tracer_sp); |
| |
| //------------------------------------------------------------------ |
| /// 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 NULL if all symbols are allowed. |
| /// |
| //------------------------------------------------------------------ |
| RegularExpression * |
| GetSymbolsToAvoidRegexp() |
| { |
| return ThreadInstanceSettings::GetSymbolsToAvoidRegexp(); |
| } |
| |
| // 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; |
| |
| //------------------------------------------------------------------ |
| // lldb::ExecutionContextScope pure virtual functions |
| //------------------------------------------------------------------ |
| virtual lldb::TargetSP |
| CalculateTarget (); |
| |
| virtual lldb::ProcessSP |
| CalculateProcess (); |
| |
| virtual lldb::ThreadSP |
| CalculateThread (); |
| |
| virtual lldb::StackFrameSP |
| CalculateStackFrame (); |
| |
| virtual void |
| CalculateExecutionContext (ExecutionContext &exe_ctx); |
| |
| 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); |
| |
| size_t |
| GetStackFrameStatus (Stream& strm, |
| uint32_t first_frame, |
| uint32_t num_frames, |
| bool show_frame_info, |
| uint32_t num_frames_with_source, |
| uint32_t source_lines_before, |
| uint32_t source_lines_after); |
| |
| // 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; |
| } |
| protected: |
| |
| friend class ThreadPlan; |
| friend class ThreadList; |
| friend class StackFrameList; |
| |
| // 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); |
| |
| // When you implement this method, make sure you don't overwrite the m_actual_stop_info if it claims to be |
| // 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 |
| GetPrivateStopReason () = 0; |
| |
| typedef std::vector<lldb::ThreadPlanSP> plan_stack; |
| |
| void |
| SetStopInfo (const lldb::StopInfoSP &stop_info_sp); |
| |
| virtual bool |
| SaveFrameZeroState (RegisterCheckpoint &checkpoint); |
| |
| virtual bool |
| RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint); |
| |
| virtual lldb_private::Unwind * |
| GetUnwinder (); |
| |
| lldb::StackFrameListSP |
| GetStackFrameList (); |
| |
| lldb::StateType GetTemporaryResumeState() |
| { |
| return m_temporary_resume_state; |
| } |
| |
| lldb::StateType SetTemporaryResumeState(lldb::StateType resume_state) |
| { |
| lldb::StateType old_temp_resume_state = m_temporary_resume_state; |
| m_temporary_resume_state = resume_state; |
| return old_temp_resume_state; |
| } |
| |
| struct ThreadState |
| { |
| uint32_t orig_stop_id; |
| lldb::StopInfoSP stop_info_sp; |
| RegisterCheckpoint register_backup; |
| }; |
| |
| //------------------------------------------------------------------ |
| // Classes that inherit from Process can see and modify these |
| //------------------------------------------------------------------ |
| lldb::ProcessWP m_process_wp; ///< The process that owns this thread. |
| lldb::StopInfoSP m_actual_stop_info_sp; ///< The private stop reason for this thread |
| 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 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 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::WillResume. |
| std::auto_ptr<lldb_private::Unwind> m_unwinder_ap; |
| bool m_destroy_called; // This is used internally to make sure derived Thread classes call DestroyThread. |
| uint32_t m_thread_stop_reason_stop_id; // This is the stop id for which the StopInfo is valid. Can use this so you know that |
| // the thread's m_actual_stop_info_sp is current and you don't have to fetch it again |
| |
| private: |
| //------------------------------------------------------------------ |
| // For Thread only |
| //------------------------------------------------------------------ |
| |
| DISALLOW_COPY_AND_ASSIGN (Thread); |
| |
| }; |
| |
| } // namespace lldb_private |
| |
| #endif // liblldb_Thread_h_ |