Changeset View
Changeset View
Standalone View
Standalone View
lldb/include/lldb/Target/StackFrame.h
Show All 29 Lines | |||||
namespace lldb_private { | namespace lldb_private { | ||||
/// @class StackFrame StackFrame.h "lldb/Target/StackFrame.h" | /// @class StackFrame StackFrame.h "lldb/Target/StackFrame.h" | ||||
/// | /// | ||||
/// This base class provides an interface to stack frames. | /// This base class provides an interface to stack frames. | ||||
/// | /// | ||||
/// StackFrames may have a Canonical Frame Address (CFA) or not. | /// StackFrames may have a Canonical Frame Address (CFA) or not. | ||||
/// A frame may have a plain pc value or it may have a pc value + stop_id | /// A frame may have a plain pc value or it may indicate a specific point in | ||||
/// to indicate a specific point in the debug session so the correct section | /// the debug session so the correct section load list is used for | ||||
/// load list is used for symbolication. | /// symbolication. | ||||
/// | /// | ||||
/// Local variables may be available, or not. A register context may be | /// Local variables may be available, or not. A register context may be | ||||
/// available, or not. | /// available, or not. | ||||
class StackFrame : public ExecutionContextScope, | class StackFrame : public ExecutionContextScope, | ||||
public std::enable_shared_from_this<StackFrame> { | public std::enable_shared_from_this<StackFrame> { | ||||
public: | public: | ||||
enum ExpressionPathOption { | enum ExpressionPathOption { | ||||
eExpressionPathOptionCheckPtrVsMember = (1u << 0), | eExpressionPathOptionCheckPtrVsMember = (1u << 0), | ||||
eExpressionPathOptionsNoFragileObjcIvar = (1u << 1), | eExpressionPathOptionsNoFragileObjcIvar = (1u << 1), | ||||
eExpressionPathOptionsNoSyntheticChildren = (1u << 2), | eExpressionPathOptionsNoSyntheticChildren = (1u << 2), | ||||
eExpressionPathOptionsNoSyntheticArrayRange = (1u << 3), | eExpressionPathOptionsNoSyntheticArrayRange = (1u << 3), | ||||
eExpressionPathOptionsAllowDirectIVarAccess = (1u << 4), | eExpressionPathOptionsAllowDirectIVarAccess = (1u << 4), | ||||
eExpressionPathOptionsInspectAnonymousUnions = (1u << 5) | eExpressionPathOptionsInspectAnonymousUnions = (1u << 5) | ||||
}; | }; | ||||
enum class Kind { | |||||
/// A regular stack frame with access to registers and local variables. | |||||
Regular, | |||||
/// A historical stack frame -- possibly without CFA or registers or | |||||
/// local variables. | |||||
History, | |||||
/// An artificial stack frame (e.g a synthesized result of inferring | |||||
aprantl: `e.g.,` | |||||
/// missing tail call frames from a backtrace) with limited support for | |||||
/// local variables. | |||||
Artificial | |||||
}; | |||||
//------------------------------------------------------------------ | //------------------------------------------------------------------ | ||||
/// Construct a StackFrame object without supplying a RegisterContextSP. | /// Construct a StackFrame object without supplying a RegisterContextSP. | ||||
/// | /// | ||||
/// This is the one constructor that doesn't take a RegisterContext | /// This is the one constructor that doesn't take a RegisterContext | ||||
/// parameter. This ctor may be called when creating a history StackFrame; | /// parameter. This ctor may be called when creating a history StackFrame; | ||||
/// these are used if we've collected a stack trace of pc addresses at some | /// these are used if we've collected a stack trace of pc addresses at some | ||||
/// point in the past. We may only have pc values. We may have pc values | /// point in the past. We may only have pc values. We may have a CFA, | ||||
/// and the stop_id when the stack trace was recorded. We may have a CFA, | |||||
/// or more likely, we won't. | /// or more likely, we won't. | ||||
/// | /// | ||||
/// @param [in] thread_sp | /// @param [in] thread_sp | ||||
/// The Thread that this frame belongs to. | /// The Thread that this frame belongs to. | ||||
/// | /// | ||||
/// @param [in] frame_idx | /// @param [in] frame_idx | ||||
/// This StackFrame's frame index number in the Thread. If inlined stack | /// This StackFrame's frame index number in the Thread. If inlined stack | ||||
/// frames are being created, this may differ from the concrete_frame_idx | /// frames are being created, this may differ from the concrete_frame_idx | ||||
Show All 14 Lines | public: | ||||
/// @param [in] cfa_is_valid | /// @param [in] cfa_is_valid | ||||
/// A history stack frame may not have a CFA value collected. We want to | /// A history stack frame may not have a CFA value collected. We want to | ||||
/// distinguish between "no CFA available" and a CFA of | /// distinguish between "no CFA available" and a CFA of | ||||
/// LLDB_INVALID_ADDRESS. | /// LLDB_INVALID_ADDRESS. | ||||
/// | /// | ||||
/// @param [in] pc | /// @param [in] pc | ||||
/// The current pc value of this stack frame. | /// The current pc value of this stack frame. | ||||
/// | /// | ||||
/// @param [in] stop_id | /// @param [in] frame_kind | ||||
/// The stop_id which should be used when looking up symbols for the pc | |||||
/// value, | |||||
/// if appropriate. This argument is ignored if stop_id_is_valid is false. | |||||
/// | |||||
/// @param [in] stop_id_is_valid | |||||
/// If the stop_id argument provided is not needed for this StackFrame, this | |||||
/// should be false. If this is a history stack frame and we know the | |||||
/// stop_id | |||||
/// when the pc value was collected, that stop_id should be provided and | |||||
/// this | |||||
/// will be true. | |||||
/// | |||||
/// @param [in] is_history_frame | |||||
/// If this is a historical stack frame -- possibly without CFA or registers | |||||
/// or | |||||
/// local variables -- then this should be set to true. | |||||
/// | /// | ||||
/// @param [in] sc_ptr | /// @param [in] sc_ptr | ||||
/// Optionally seed the StackFrame with the SymbolContext information that | /// Optionally seed the StackFrame with the SymbolContext information that | ||||
/// has | /// has | ||||
/// already been discovered. | /// already been discovered. | ||||
//------------------------------------------------------------------ | //------------------------------------------------------------------ | ||||
StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, | StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, | ||||
lldb::user_id_t concrete_frame_idx, lldb::addr_t cfa, | lldb::user_id_t concrete_frame_idx, lldb::addr_t cfa, | ||||
bool cfa_is_valid, lldb::addr_t pc, uint32_t stop_id, | bool cfa_is_valid, lldb::addr_t pc, Kind frame_kind, | ||||
bool stop_id_is_valid, bool is_history_frame, | |||||
const SymbolContext *sc_ptr); | const SymbolContext *sc_ptr); | ||||
StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, | StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, | ||||
lldb::user_id_t concrete_frame_idx, | lldb::user_id_t concrete_frame_idx, | ||||
const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, | const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, | ||||
lldb::addr_t pc, const SymbolContext *sc_ptr); | lldb::addr_t pc, const SymbolContext *sc_ptr); | ||||
StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, | StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, | ||||
▲ Show 20 Lines • Show All 268 Lines • ▼ Show 20 Lines | public: | ||||
/// the debugger. | /// the debugger. | ||||
/// | /// | ||||
/// @return | /// @return | ||||
/// true if this is an inlined frame. | /// true if this is an inlined frame. | ||||
//------------------------------------------------------------------ | //------------------------------------------------------------------ | ||||
bool IsInlined(); | bool IsInlined(); | ||||
//------------------------------------------------------------------ | //------------------------------------------------------------------ | ||||
/// Query whether this frame is part of a historical backtrace. | |||||
//------------------------------------------------------------------ | |||||
bool IsHistorical() const; | |||||
//------------------------------------------------------------------ | |||||
/// Query whether this frame is artificial (e.g a synthesized result of | |||||
/// inferring missing tail call frames from a backtrace). Artificial frames | |||||
/// may have limited support for inspecting variables. | |||||
//------------------------------------------------------------------ | |||||
bool IsArtificial() const; | |||||
//------------------------------------------------------------------ | |||||
/// Query this frame to find what frame it is in this Thread's | /// Query this frame to find what frame it is in this Thread's | ||||
/// StackFrameList. | /// StackFrameList. | ||||
/// | /// | ||||
/// @return | /// @return | ||||
/// StackFrame index 0 indicates the currently-executing function. Inline | /// StackFrame index 0 indicates the currently-executing function. Inline | ||||
/// frames are included in this frame index count. | /// frames are included in this frame index count. | ||||
//------------------------------------------------------------------ | //------------------------------------------------------------------ | ||||
uint32_t GetFrameIndex() const; | uint32_t GetFrameIndex() const; | ||||
//------------------------------------------------------------------ | //------------------------------------------------------------------ | ||||
/// Set this frame's synthetic frame index. | |||||
//------------------------------------------------------------------ | |||||
void SetFrameIndex(uint32_t index) { m_frame_index = index; } | |||||
//------------------------------------------------------------------ | |||||
/// Query this frame to find what frame it is in this Thread's | /// Query this frame to find what frame it is in this Thread's | ||||
/// StackFrameList, not counting inlined frames. | /// StackFrameList, not counting inlined frames. | ||||
/// | /// | ||||
/// @return | /// @return | ||||
/// StackFrame index 0 indicates the currently-executing function. Inline | /// StackFrame index 0 indicates the currently-executing function. Inline | ||||
/// frames are not included in this frame index count; their concrete | /// frames are not included in this frame index count; their concrete | ||||
/// frame index will be the same as the concrete frame that they are | /// frame index will be the same as the concrete frame that they are | ||||
/// derived from. | /// derived from. | ||||
▲ Show 20 Lines • Show All 131 Lines • ▼ Show 20 Lines | Address m_frame_code_addr; // The frame code address (might not be the same as | ||||
// the actual PC for inlined frames) as a | // the actual PC for inlined frames) as a | ||||
// section/offset address | // section/offset address | ||||
SymbolContext m_sc; | SymbolContext m_sc; | ||||
Flags m_flags; | Flags m_flags; | ||||
Scalar m_frame_base; | Scalar m_frame_base; | ||||
Status m_frame_base_error; | Status m_frame_base_error; | ||||
bool m_cfa_is_valid; // Does this frame have a CFA? Different from CFA == | bool m_cfa_is_valid; // Does this frame have a CFA? Different from CFA == | ||||
// LLDB_INVALID_ADDRESS | // LLDB_INVALID_ADDRESS | ||||
uint32_t m_stop_id; | Kind m_stack_frame_kind; | ||||
bool m_stop_id_is_valid; // Does this frame have a stop_id? Use it when | |||||
// referring to the m_frame_code_addr. | |||||
bool m_is_history_frame; | |||||
lldb::VariableListSP m_variable_list_sp; | lldb::VariableListSP m_variable_list_sp; | ||||
ValueObjectList m_variable_list_value_objects; // Value objects for each | ValueObjectList m_variable_list_value_objects; // Value objects for each | ||||
// variable in | // variable in | ||||
// m_variable_list_sp | // m_variable_list_sp | ||||
StreamString m_disassembly; | StreamString m_disassembly; | ||||
std::recursive_mutex m_mutex; | std::recursive_mutex m_mutex; | ||||
DISALLOW_COPY_AND_ASSIGN(StackFrame); | DISALLOW_COPY_AND_ASSIGN(StackFrame); | ||||
}; | }; | ||||
} // namespace lldb_private | } // namespace lldb_private | ||||
#endif // liblldb_StackFrame_h_ | #endif // liblldb_StackFrame_h_ |
e.g.,