aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Target/Thread.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/lldb/Target/Thread.h')
-rw-r--r--include/lldb/Target/Thread.h2701
1 files changed, 1286 insertions, 1415 deletions
diff --git a/include/lldb/Target/Thread.h b/include/lldb/Target/Thread.h
index f3cf97325e16..63449bbf930e 100644
--- a/include/lldb/Target/Thread.h
+++ b/include/lldb/Target/Thread.h
@@ -19,7 +19,6 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/Event.h"
#include "lldb/Core/StructuredData.h"
@@ -28,1452 +27,1324 @@
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/RegisterCheckpoint.h"
#include "lldb/Target/StackFrameList.h"
+#include "lldb/lldb-private.h"
#define LLDB_THREAD_MAX_STOP_EXC_DATA 8
namespace lldb_private {
-class ThreadProperties : public Properties
-{
+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;
-};
-
-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 const ConstString &
- GetFlavorString ();
-
- const 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.
- 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 == false)
- {
- 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 proces.
- ///
- /// @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;
- }
+ ThreadProperties(bool is_global);
- 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;
- }
+ ~ThreadProperties() override;
- 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();
- }
-
- Error
- ReturnFromFrameWithIndex (uint32_t frame_idx, lldb::ValueObjectSP return_value_sp, bool broadcast = false);
-
- Error
- ReturnFromFrame (lldb::StackFrameSP frame_sp, lldb::ValueObjectSP return_value_sp, bool broadcast = false);
-
- Error
- 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();
- }
+ //------------------------------------------------------------------
+ /// 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();
- uint32_t
- GetSelectedFrameIndex ()
- {
- return GetStackFrameList()->GetSelectedFrameIndex();
- }
+ FileSpecList &GetLibrariesToAvoid() const;
- lldb::StackFrameSP
- GetSelectedFrame ();
+ bool GetTraceEnabledState() const;
- uint32_t
- SetSelectedFrame (lldb_private::StackFrame *frame, bool broadcast = false);
+ bool GetStepInAvoidsNoDebug() const;
- bool
- SetSelectedFrameByIndex (uint32_t frame_idx, bool broadcast = false);
+ bool GetStepOutAvoidsNoDebug() const;
+};
- bool
- SetSelectedFrameByIndexNoisily (uint32_t frame_idx, Stream &output_stream);
+typedef std::shared_ptr<ThreadProperties> ThreadPropertiesSP;
- void
- SetDefaultFileAndLineToSelectedFrame()
- {
- GetStackFrameList()->SetDefaultFileAndLineToSelectedFrame();
- }
+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)
+ };
- virtual lldb::RegisterContextSP
- GetRegisterContext () = 0;
+ static ConstString &GetStaticBroadcasterClass();
- virtual lldb::RegisterContextSP
- CreateRegisterContextForFrame (StackFrame *frame) = 0;
-
- virtual void
- ClearStackFrames ();
+ ConstString &GetBroadcasterClass() const override {
+ return GetStaticBroadcasterClass();
+ }
- virtual bool
- SetBackingThread (const lldb::ThreadSP &thread_sp)
- {
- return false;
- }
-
- virtual lldb::ThreadSP
- GetBackingThread () const
- {
- return lldb::ThreadSP();
- }
+ class ThreadEventData : public EventData {
+ public:
+ ThreadEventData(const lldb::ThreadSP thread_sp);
- 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.
- }
+ ThreadEventData(const lldb::ThreadSP thread_sp, const StackID &stack_id);
- void
- DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx);
-
- 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 Error
- 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 Error
- 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 Error
- 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.
- ///
- /// @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);
-
- //------------------------------------------------------------------
- /// 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[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,
- 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,
- 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[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,
- 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,
- 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[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, // = eVoteYes,
- Vote run_vote, // = eVoteNoOpinion);
- uint32_t frame_idx,
- 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] 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, // = eVoteYes,
- Vote run_vote, // = eVoteNoOpinion);
- uint32_t frame_idx,
- 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.
- ///
- /// @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);
-
- //------------------------------------------------------------------
- /// 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 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);
-
- virtual lldb::ThreadPlanSP
- QueueThreadPlanForStepUntil (bool abort_other_plans,
- lldb::addr_t *address_list,
- size_t num_addresses,
- bool stop_others,
- uint32_t frame_idx);
-
- virtual lldb::ThreadPlanSP
- QueueThreadPlanForStepScripted (bool abort_other_plans,
- const char *class_name,
- bool stop_other_threads);
-
- //------------------------------------------------------------------
- // 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.
- //------------------------------------------------------------------
-
- Error
- 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);
-
- //------------------------------------------------------------------
- /// 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);
-
- 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 ();
- }
+ ThreadEventData();
- //------------------------------------------------------------------
- // 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();
- }
+ ~ThreadEventData() override;
- //------------------------------------------------------------------
- // 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);
-
- 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;
- }
+ static const ConstString &GetFlavorString();
- // 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;
+ const ConstString &GetFlavor() const override {
+ return ThreadEventData::GetFlavorString();
}
- void
- SetStopInfo (const lldb::StopInfoSP &stop_info_sp);
-
- 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;
+ 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.
+ 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 == false) {
+ 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();
+ }
+
+ Error ReturnFromFrameWithIndex(uint32_t frame_idx,
+ lldb::ValueObjectSP return_value_sp,
+ bool broadcast = false);
+
+ Error ReturnFromFrame(lldb::StackFrameSP frame_sp,
+ lldb::ValueObjectSP return_value_sp,
+ bool broadcast = false);
+
+ Error 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 Error
+ 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 Error 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 Error 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.
+ ///
+ /// @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);
+
+ //------------------------------------------------------------------
+ /// 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[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,
+ 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,
+ 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[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,
+ 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,
+ 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[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, // = eVoteYes,
+ Vote run_vote, // = eVoteNoOpinion);
+ uint32_t frame_idx,
+ 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] 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, // = eVoteYes,
+ Vote run_vote, // = eVoteNoOpinion);
+ uint32_t frame_idx, 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.
+ ///
+ /// @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);
+
+ //------------------------------------------------------------------
+ /// 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 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);
+
+ virtual lldb::ThreadPlanSP
+ QueueThreadPlanForStepUntil(bool abort_other_plans,
+ lldb::addr_t *address_list, size_t num_addresses,
+ bool stop_others, uint32_t frame_idx);
+
+ virtual lldb::ThreadPlanSP
+ QueueThreadPlanForStepScripted(bool abort_other_plans, const char *class_name,
+ bool stop_other_threads);
+
+ //------------------------------------------------------------------
+ // 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.
+ //------------------------------------------------------------------
+
+ Error 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);
+
+ //------------------------------------------------------------------
+ /// 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);
+
+ 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);
+
+ 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 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; }
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();
- }
+ 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_ap;
+ bool m_destroy_called; // This is used internally to make sure derived Thread
+ // classes call DestroyThread.
+ LazyBool m_override_should_notify;
- 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_ap;
- 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
+ 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);
+ bool PlanIsBasePlan(ThreadPlan *plan_ptr);
+
+ void BroadcastSelectedFrameChange(StackID &new_frame_id);
- void
- BroadcastSelectedFrameChange(StackID &new_frame_id);
-
- DISALLOW_COPY_AND_ASSIGN (Thread);
+ DISALLOW_COPY_AND_ASSIGN(Thread);
};
} // namespace lldb_private