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.h256
1 files changed, 237 insertions, 19 deletions
diff --git a/include/lldb/Target/Thread.h b/include/lldb/Target/Thread.h
index 20687e977bff..cba09e164105 100644
--- a/include/lldb/Target/Thread.h
+++ b/include/lldb/Target/Thread.h
@@ -14,6 +14,7 @@
#include "lldb/Host/Mutex.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/Event.h"
+#include "lldb/Core/StructuredData.h"
#include "lldb/Core/UserID.h"
#include "lldb/Core/UserSettingsController.h"
#include "lldb/Target/ExecutionContextScope.h"
@@ -49,6 +50,12 @@ public:
bool
GetTraceEnabledState() const;
+
+ bool
+ GetStepInAvoidsNoDebug () const;
+
+ bool
+ GetStepOutAvoidsNoDebug () const;
};
typedef std::shared_ptr<ThreadProperties> ThreadPropertiesSP;
@@ -153,7 +160,25 @@ public:
static const ThreadPropertiesSP &
GetGlobalProperties();
- Thread (Process &process, lldb::tid_t tid);
+ //------------------------------------------------------------------
+ /// 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);
+
virtual ~Thread();
lldb::ProcessSP
@@ -185,10 +210,22 @@ public:
{
return m_resume_state;
}
-
+
+ // This sets the "external resume state" of the thread. If the thread is suspended here, it should never
+ // get scheduled. Note that just because a thread is marked as "running" does not mean we will let it run in
+ // a given bit of process control. For instance "step" tries to stay on the selected thread it was issued on,
+ // which may involve suspending other threads temporarily. This temporary suspension is NOT reflected in the
+ // state set here and reported in GetResumeState.
+ //
+ // If you are just preparing all threads to run, you should not override the threads that are
+ // marked as suspended by the debugger. In that case, pass override_suspend = false. If you want
+ // to force the thread to run (e.g. the "thread continue" command, or are resetting the state
+ // (e.g. in SBThread::Resume()), then pass true to override_suspend.
void
- SetResumeState (lldb::StateType state)
+ SetResumeState (lldb::StateType state, bool override_suspend = false)
{
+ if (m_resume_state == lldb::eStateSuspended && !override_suspend)
+ return;
m_resume_state = state;
}
@@ -270,6 +307,28 @@ public:
return NULL;
}
+ //------------------------------------------------------------------
+ /// 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 ()
{
@@ -281,6 +340,21 @@ public:
{
}
+ //------------------------------------------------------------------
+ /// 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 ()
{
@@ -292,6 +366,16 @@ public:
{
}
+ //------------------------------------------------------------------
+ /// 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
+ /// NULL.
+ //------------------------------------------------------------------
virtual const char *
GetQueueName ()
{
@@ -303,6 +387,44 @@ public:
{
}
+ //------------------------------------------------------------------
+ /// 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 uint32_t
GetStackFrameCount()
{
@@ -412,6 +534,9 @@ public:
void
DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx);
+ bool
+ GetDescription (Stream &s, lldb::DescriptionLevel level, bool json_output);
+
//------------------------------------------------------------------
/// Default implementation for stepping into.
///
@@ -422,17 +547,22 @@ public:
/// If true and the frame has debug info, then do a source level
/// step in, else do a single instruction step in.
///
- /// @param[in] avoid_code_without_debug_info
+ /// @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 wether it
+ /// 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,
- bool avoid_code_without_debug_info);
+ LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate,
+ LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
//------------------------------------------------------------------
/// Default implementation for stepping over.
@@ -448,7 +578,8 @@ public:
/// An error that describes anything that went wrong
//------------------------------------------------------------------
virtual Error
- StepOver (bool source_step);
+ StepOver (bool source_step,
+ LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
//------------------------------------------------------------------
/// Default implementation for stepping out.
@@ -487,6 +618,19 @@ public:
virtual lldb::addr_t
GetThreadLocalData (const lldb::ModuleSP module);
+ //------------------------------------------------------------------
+ /// 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:
@@ -574,14 +718,19 @@ public:
/// @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 NULL 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);
+ const AddressRange &range,
+ 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.
@@ -609,19 +758,25 @@ public:
/// @param[in] stop_other_threads
/// \b true if we will stop other threads while we single step this one.
///
- /// @param[in] avoid_code_without_debug_info
- /// If \b true we will step out if we step into code with no debug info.
+ /// @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 NULL 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,
- bool avoid_code_without_debug_info);
+ 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);
//------------------------------------------------------------------
/// Queue the plan used to step out of the function at the current PC of
@@ -648,6 +803,10 @@ public:
/// @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 NULL if the plan could not be queued.
//------------------------------------------------------------------
@@ -658,7 +817,46 @@ public:
bool stop_other_threads,
Vote stop_vote, // = eVoteYes,
Vote run_vote, // = eVoteNoOpinion);
- uint32_t frame_idx);
+ 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.
+ ///
+ /// @return
+ /// A shared pointer to the newly queued thread plan, or NULL 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);
//------------------------------------------------------------------
/// Gets the plan used to step through the code that steps from a function
@@ -768,6 +966,17 @@ public:
GetReturnValueObject ();
//------------------------------------------------------------------
+ /// Gets the outer-most expression variable from the completed plans
+ ///
+ /// @return
+ /// A ClangExpressionVariableSP, 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::ClangExpressionVariableSP
+ GetExpressionVariable ();
+
+ //------------------------------------------------------------------
/// Checks whether the given plan is in the completed plans for this
/// stop.
///
@@ -1066,6 +1275,13 @@ protected:
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 ();
@@ -1091,11 +1307,13 @@ protected:
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::ShoudResume.
+ /// 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
//------------------------------------------------------------------
// For Thread only
//------------------------------------------------------------------