diff options
Diffstat (limited to 'include/lldb/Target/StackFrame.h')
-rw-r--r-- | include/lldb/Target/StackFrame.h | 998 |
1 files changed, 503 insertions, 495 deletions
diff --git a/include/lldb/Target/StackFrame.h b/include/lldb/Target/StackFrame.h index b3cc57f176ca..34bd187b776c 100644 --- a/include/lldb/Target/StackFrame.h +++ b/include/lldb/Target/StackFrame.h @@ -33,514 +33,522 @@ namespace lldb_private { /// /// @brief This base class provides an interface to stack frames. /// -/// 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 -/// to indicate a specific point in the debug session so the correct section +/// 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 +/// to indicate a specific point in the debug session so the correct section /// load list is used for symbolication. /// /// Local variables may be available, or not. A register context may be /// available, or not. -class StackFrame : - public ExecutionContextScope, - public std::enable_shared_from_this<StackFrame> -{ +class StackFrame : public ExecutionContextScope, + public std::enable_shared_from_this<StackFrame> { public: - enum ExpressionPathOption - { - eExpressionPathOptionCheckPtrVsMember = (1u << 0), - eExpressionPathOptionsNoFragileObjcIvar = (1u << 1), - eExpressionPathOptionsNoSyntheticChildren = (1u << 2), - eExpressionPathOptionsNoSyntheticArrayRange = (1u << 3), - eExpressionPathOptionsAllowDirectIVarAccess = (1u << 4), - eExpressionPathOptionsInspectAnonymousUnions = (1u << 5) - }; - - //------------------------------------------------------------------ - /// Construct a StackFrame object without supplying a RegisterContextSP. - /// - /// This is the one constructor that doesn't take a RegisterContext - /// 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 point in the past. We may only have pc values. We may have pc - /// values and the stop_id when the stack trace was recorded. We may have a - /// CFA, or more likely, we won't. - /// - /// @param [in] thread_sp - /// The Thread that this frame belongs to. - /// - /// @param [in] frame_idx - /// This StackFrame's frame index number in the Thread. If inlined stack - /// frames are being created, this may differ from the concrete_frame_idx - /// which is the frame index without any inlined stack frames. - /// - /// @param [in] concrete_frame_idx - /// The StackFrame's frame index number in the Thread without any inlined - /// stack frames being included in the index. - /// - /// @param [in] cfa - /// The Canonical Frame Address (this terminology from DWARF) for this - /// stack frame. The CFA for a stack frame does not change over the - /// span of the stack frame's existence. It is often the value of the - /// caller's stack pointer before the call instruction into this frame's - /// function. It is usually not the same as the frame pointer register's - /// value. - /// - /// @param [in] cfa_is_valid - /// A history stack frame may not have a CFA value collected. We want to - /// distinguish between "no CFA available" and a CFA of - /// LLDB_INVALID_ADDRESS. - /// - /// @param [in] pc - /// The current pc value of this stack frame. - /// - /// @param [in] stop_id - /// 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 - /// Optionally seed the StackFrame with the SymbolContext information that has - /// already been discovered. - //------------------------------------------------------------------ - StackFrame (const lldb::ThreadSP &thread_sp, - lldb::user_id_t frame_idx, - lldb::user_id_t concrete_frame_idx, - lldb::addr_t cfa, - bool cfa_is_valid, - lldb::addr_t pc, - uint32_t stop_id, - bool stop_id_is_valid, - bool is_history_frame, - const SymbolContext *sc_ptr); - - StackFrame (const lldb::ThreadSP &thread_sp, - lldb::user_id_t frame_idx, - lldb::user_id_t concrete_frame_idx, - const lldb::RegisterContextSP ®_context_sp, - lldb::addr_t cfa, - lldb::addr_t pc, - const SymbolContext *sc_ptr); - - StackFrame (const lldb::ThreadSP &thread_sp, - lldb::user_id_t frame_idx, - lldb::user_id_t concrete_frame_idx, - const lldb::RegisterContextSP ®_context_sp, - lldb::addr_t cfa, - const Address& pc, - const SymbolContext *sc_ptr); - - ~StackFrame() override; - - lldb::ThreadSP - GetThread () const - { - return m_thread_wp.lock(); - } - - StackID& - GetStackID(); - - //------------------------------------------------------------------ - /// Get an Address for the current pc value in this StackFrame. - /// - /// May not be the same as the actual PC value for inlined stack frames. - /// - /// @return - /// The Address object set to the current PC value. - //------------------------------------------------------------------ - const Address& - GetFrameCodeAddress(); - - //------------------------------------------------------------------ - /// Change the pc value for a given thread. - /// - /// Change the current pc value for the frame on this thread. - /// - /// @param[in] pc - /// The load address that the pc will be set to. - /// - /// @return - /// true if the pc was changed. false if this failed -- possibly - /// because this frame is not a live StackFrame. - //------------------------------------------------------------------ - bool - ChangePC (lldb::addr_t pc); - - //------------------------------------------------------------------ - /// Provide a SymbolContext for this StackFrame's current pc value. - /// - /// The StackFrame maintains this SymbolContext and adds additional information - /// to it on an as-needed basis. This helps to avoid different functions - /// looking up symbolic information for a given pc value multiple times. - /// - /// @params [in] resolve_scope - /// Flags from the SymbolContextItem enumerated type which specify what - /// type of symbol context is needed by this caller. - /// - /// @return - /// A SymbolContext reference which includes the types of information - /// requested by resolve_scope, if they are available. - //------------------------------------------------------------------ - const SymbolContext& - GetSymbolContext (uint32_t resolve_scope); - - //------------------------------------------------------------------ - /// Return the Canonical Frame Address (DWARF term) for this frame. - /// - /// The CFA is typically the value of the stack pointer register before - /// the call invocation is made. It will not change during the lifetime - /// of a stack frame. It is often not the same thing as the frame pointer - /// register value. - /// - /// Live StackFrames will always have a CFA but other types of frames may - /// not be able to supply one. - /// - /// @param [out] value - /// The address of the CFA for this frame, if available. - /// - /// @param [out] error_ptr - /// If there is an error determining the CFA address, this may contain a - /// string explaining the failure. - /// - /// @return - /// Returns true if the CFA value was successfully set in value. Some - /// frames may be unable to provide this value; they will return false. - //------------------------------------------------------------------ - bool - GetFrameBaseValue(Scalar &value, Error *error_ptr); - - //------------------------------------------------------------------ - /// Get the current lexical scope block for this StackFrame, if possible. - /// - /// If debug information is available for this stack frame, return a - /// pointer to the innermost lexical Block that the frame is currently - /// executing. - /// - /// @return - /// A pointer to the current Block. nullptr is returned if this can - /// not be provided. - //------------------------------------------------------------------ - Block * - GetFrameBlock (); - - //------------------------------------------------------------------ - /// Get the RegisterContext for this frame, if possible. - /// - /// Returns a shared pointer to the RegisterContext for this stack frame. - /// Only a live StackFrame object will be able to return a RegisterContext - - /// callers must be prepared for an empty shared pointer being returned. - /// - /// Even a live StackFrame RegisterContext may not be able to provide all - /// registers. Only the currently executing frame (frame 0) can reliably - /// provide every register in the register context. - /// - /// @return - /// The RegisterContext shared point for this frame. - //------------------------------------------------------------------ - lldb::RegisterContextSP - GetRegisterContext (); - - const lldb::RegisterContextSP & - GetRegisterContextSP () const - { - return m_reg_context_sp; - } - - //------------------------------------------------------------------ - /// Retrieve the list of variables that are in scope at this StackFrame's pc. - /// - /// A frame that is not live may return an empty VariableList for a given - /// pc value even though variables would be available at this point if - /// it were a live stack frame. - /// - /// @param[in] get_file_globals - /// Whether to also retrieve compilation-unit scoped variables - /// that are visible to the entire compilation unit (e.g. file - /// static in C, globals that are homed in this CU). - /// - /// @return - /// A pointer to a list of variables. - //------------------------------------------------------------------ - VariableList * - GetVariableList (bool get_file_globals); - - //------------------------------------------------------------------ - /// Retrieve the list of variables that are in scope at this StackFrame's pc. - /// - /// A frame that is not live may return an empty VariableListSP for a - /// given pc value even though variables would be available at this point - /// if it were a live stack frame. - /// - /// @param[in] get_file_globals - /// Whether to also retrieve compilation-unit scoped variables - /// that are visible to the entire compilation unit (e.g. file - /// static in C, globals that are homed in this CU). - /// - /// @return - /// A pointer to a list of variables. - //------------------------------------------------------------------ - lldb::VariableListSP - GetInScopeVariableList (bool get_file_globals, bool must_have_valid_location = false); - - //------------------------------------------------------------------ - /// Create a ValueObject for a variable name / pathname, possibly - /// including simple dereference/child selection syntax. - /// - /// @param[in] var_expr - /// The string specifying a variable to base the VariableObject off - /// of. - /// - /// @param[in] use_dynamic - /// Whether the correct dynamic type of an object pointer should be - /// determined before creating the object, or if the static type is - /// sufficient. One of the DynamicValueType enumerated values. - /// - /// @param[in] options - /// An unsigned integer of flags, values from StackFrame::ExpressionPathOption - /// enum. - /// @param[in] var_sp - /// A VariableSP that will be set to the variable described in the - /// var_expr path. - /// - /// @param[in] error - /// Record any errors encountered while evaluating var_expr. - /// - /// @return - /// A shared pointer to the ValueObject described by var_expr. - //------------------------------------------------------------------ - lldb::ValueObjectSP - GetValueForVariableExpressionPath (const char *var_expr, - lldb::DynamicValueType use_dynamic, - uint32_t options, - lldb::VariableSP &var_sp, - Error &error); - - //------------------------------------------------------------------ - /// Determine whether this StackFrame has debug information available or not - /// - /// @return - // true if debug information is available for this frame (function, - // compilation unit, block, etc.) - //------------------------------------------------------------------ - bool - HasDebugInformation (); - - //------------------------------------------------------------------ - /// Return the disassembly for the instructions of this StackFrame's function - /// as a single C string. - /// - /// @return - // C string with the assembly instructions for this function. - //------------------------------------------------------------------ - const char * - Disassemble (); - - //------------------------------------------------------------------ - /// Print a description for this frame using the frame-format formatter settings. - /// - /// @param [in] strm - /// The Stream to print the description to. - /// - /// @param [in] frame_marker - /// Optional string that will be prepended to the frame output description. - //------------------------------------------------------------------ - void - DumpUsingSettingsFormat(Stream *strm, const char *frame_marker = nullptr); - - //------------------------------------------------------------------ - /// Print a description for this frame using a default format. - /// - /// @param [in] strm - /// The Stream to print the description to. - /// - /// @param [in] show_frame_index - /// Whether to print the frame number or not. - /// - /// @param [in] show_fullpaths - /// Whether to print the full source paths or just the file base name. - //------------------------------------------------------------------ - void - Dump (Stream *strm, bool show_frame_index, bool show_fullpaths); - - //------------------------------------------------------------------ - /// Print a description of this stack frame and/or the source context/assembly - /// for this stack frame. - /// - /// @param[in] strm - /// The Stream to send the output to. - /// - /// @param[in] show_frame_info - /// If true, print the frame info by calling DumpUsingSettingsFormat(). - /// - /// @param[in] show_source - /// If true, print source or disassembly as per the user's settings. - /// - /// @param[in] frame_marker - /// Passed to DumpUsingSettingsFormat() for the frame info printing. - /// - /// @return - /// Returns true if successful. - //------------------------------------------------------------------ - bool - GetStatus(Stream &strm, - bool show_frame_info, - bool show_source, - const char *frame_marker = nullptr); - - //------------------------------------------------------------------ - /// Query whether this frame is a concrete frame on the call stack, - /// or if it is an inlined frame derived from the debug information - /// and presented by the debugger. - /// - /// @return - /// true if this is an inlined frame. - //------------------------------------------------------------------ - bool - IsInlined (); - - //------------------------------------------------------------------ - /// Query this frame to find what frame it is in this Thread's StackFrameList. - /// - /// @return - /// StackFrame index 0 indicates the currently-executing function. Inline - /// frames are included in this frame index count. - //------------------------------------------------------------------ - uint32_t - GetFrameIndex () const; - - //------------------------------------------------------------------ - /// Query this frame to find what frame it is in this Thread's StackFrameList, - /// not counting inlined frames. - /// - /// @return - /// StackFrame index 0 indicates the currently-executing function. Inline - /// frames are not included in this frame index count; their concrete - /// frame index will be the same as the concrete frame that they are - /// derived from. - //------------------------------------------------------------------ - uint32_t - GetConcreteFrameIndex () const - { - return m_concrete_frame_index; - } - - //------------------------------------------------------------------ - /// Create a ValueObject for a given Variable in this StackFrame. - /// - /// @params [in] variable_sp - /// The Variable to base this ValueObject on - /// - /// @params [in] use_dynamic - /// Whether the correct dynamic type of the variable should be - /// determined before creating the ValueObject, or if the static type - /// is sufficient. One of the DynamicValueType enumerated values. - /// - /// @return - // A ValueObject for this variable. - //------------------------------------------------------------------ - lldb::ValueObjectSP - GetValueObjectForFrameVariable (const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic); - - //------------------------------------------------------------------ - /// Add an arbitrary Variable object (e.g. one that specifics a global or static) - /// to a StackFrame's list of ValueObjects. - /// - /// @params [in] variable_sp - /// The Variable to base this ValueObject on - /// - /// @params [in] use_dynamic - /// Whether the correct dynamic type of the variable should be - /// determined before creating the ValueObject, or if the static type - /// is sufficient. One of the DynamicValueType enumerated values. - /// - /// @return - // A ValueObject for this variable. - //------------------------------------------------------------------ - lldb::ValueObjectSP - TrackGlobalVariable (const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic); - - //------------------------------------------------------------------ - /// Query this frame to determine what the default language should be - /// when parsing expressions given the execution context. - /// - /// @return - /// The language of the frame if known, else lldb::eLanguageTypeUnknown. - //------------------------------------------------------------------ - lldb::LanguageType - GetLanguage (); - - // similar to GetLanguage(), but is allowed to take a potentially incorrect guess - // if exact information is not available - lldb::LanguageType - GuessLanguage (); - - //------------------------------------------------------------------ - // 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; + enum ExpressionPathOption { + eExpressionPathOptionCheckPtrVsMember = (1u << 0), + eExpressionPathOptionsNoFragileObjcIvar = (1u << 1), + eExpressionPathOptionsNoSyntheticChildren = (1u << 2), + eExpressionPathOptionsNoSyntheticArrayRange = (1u << 3), + eExpressionPathOptionsAllowDirectIVarAccess = (1u << 4), + eExpressionPathOptionsInspectAnonymousUnions = (1u << 5) + }; + + //------------------------------------------------------------------ + /// Construct a StackFrame object without supplying a RegisterContextSP. + /// + /// This is the one constructor that doesn't take a RegisterContext + /// 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 point in the past. We may only have pc values. We may have pc + /// values and the stop_id when the stack trace was recorded. We may have a + /// CFA, or more likely, we won't. + /// + /// @param [in] thread_sp + /// The Thread that this frame belongs to. + /// + /// @param [in] frame_idx + /// This StackFrame's frame index number in the Thread. If inlined stack + /// frames are being created, this may differ from the concrete_frame_idx + /// which is the frame index without any inlined stack frames. + /// + /// @param [in] concrete_frame_idx + /// The StackFrame's frame index number in the Thread without any inlined + /// stack frames being included in the index. + /// + /// @param [in] cfa + /// The Canonical Frame Address (this terminology from DWARF) for this + /// stack frame. The CFA for a stack frame does not change over the + /// span of the stack frame's existence. It is often the value of the + /// caller's stack pointer before the call instruction into this frame's + /// function. It is usually not the same as the frame pointer register's + /// value. + /// + /// @param [in] cfa_is_valid + /// A history stack frame may not have a CFA value collected. We want to + /// distinguish between "no CFA available" and a CFA of + /// LLDB_INVALID_ADDRESS. + /// + /// @param [in] pc + /// The current pc value of this stack frame. + /// + /// @param [in] stop_id + /// 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 + /// Optionally seed the StackFrame with the SymbolContext information that + /// has + /// already been discovered. + //------------------------------------------------------------------ + StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, + lldb::user_id_t concrete_frame_idx, lldb::addr_t cfa, + bool cfa_is_valid, lldb::addr_t pc, uint32_t stop_id, + bool stop_id_is_valid, bool is_history_frame, + const SymbolContext *sc_ptr); + + StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, + lldb::user_id_t concrete_frame_idx, + const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, + lldb::addr_t pc, const SymbolContext *sc_ptr); + + StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, + lldb::user_id_t concrete_frame_idx, + const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, + const Address &pc, const SymbolContext *sc_ptr); + + ~StackFrame() override; + + lldb::ThreadSP GetThread() const { return m_thread_wp.lock(); } + + StackID &GetStackID(); + + //------------------------------------------------------------------ + /// Get an Address for the current pc value in this StackFrame. + /// + /// May not be the same as the actual PC value for inlined stack frames. + /// + /// @return + /// The Address object set to the current PC value. + //------------------------------------------------------------------ + const Address &GetFrameCodeAddress(); + + //------------------------------------------------------------------ + /// Change the pc value for a given thread. + /// + /// Change the current pc value for the frame on this thread. + /// + /// @param[in] pc + /// The load address that the pc will be set to. + /// + /// @return + /// true if the pc was changed. false if this failed -- possibly + /// because this frame is not a live StackFrame. + //------------------------------------------------------------------ + bool ChangePC(lldb::addr_t pc); + + //------------------------------------------------------------------ + /// Provide a SymbolContext for this StackFrame's current pc value. + /// + /// The StackFrame maintains this SymbolContext and adds additional + /// information + /// to it on an as-needed basis. This helps to avoid different functions + /// looking up symbolic information for a given pc value multiple times. + /// + /// @params [in] resolve_scope + /// Flags from the SymbolContextItem enumerated type which specify what + /// type of symbol context is needed by this caller. + /// + /// @return + /// A SymbolContext reference which includes the types of information + /// requested by resolve_scope, if they are available. + //------------------------------------------------------------------ + const SymbolContext &GetSymbolContext(uint32_t resolve_scope); + + //------------------------------------------------------------------ + /// Return the Canonical Frame Address (DWARF term) for this frame. + /// + /// The CFA is typically the value of the stack pointer register before + /// the call invocation is made. It will not change during the lifetime + /// of a stack frame. It is often not the same thing as the frame pointer + /// register value. + /// + /// Live StackFrames will always have a CFA but other types of frames may + /// not be able to supply one. + /// + /// @param [out] value + /// The address of the CFA for this frame, if available. + /// + /// @param [out] error_ptr + /// If there is an error determining the CFA address, this may contain a + /// string explaining the failure. + /// + /// @return + /// Returns true if the CFA value was successfully set in value. Some + /// frames may be unable to provide this value; they will return false. + //------------------------------------------------------------------ + bool GetFrameBaseValue(Scalar &value, Error *error_ptr); + + //------------------------------------------------------------------ + /// Get the DWARFExpression corresponding to the Canonical Frame Address. + /// + /// Often a register (bp), but sometimes a register + offset. + /// + /// @param [out] error_ptr + /// If there is an error determining the CFA address, this may contain a + /// string explaining the failure. + /// + /// @return + /// Returns the corresponding DWARF expression, or NULL. + //------------------------------------------------------------------ + DWARFExpression *GetFrameBaseExpression(Error *error_ptr); + + //------------------------------------------------------------------ + /// Get the current lexical scope block for this StackFrame, if possible. + /// + /// If debug information is available for this stack frame, return a + /// pointer to the innermost lexical Block that the frame is currently + /// executing. + /// + /// @return + /// A pointer to the current Block. nullptr is returned if this can + /// not be provided. + //------------------------------------------------------------------ + Block *GetFrameBlock(); + + //------------------------------------------------------------------ + /// Get the RegisterContext for this frame, if possible. + /// + /// Returns a shared pointer to the RegisterContext for this stack frame. + /// Only a live StackFrame object will be able to return a RegisterContext - + /// callers must be prepared for an empty shared pointer being returned. + /// + /// Even a live StackFrame RegisterContext may not be able to provide all + /// registers. Only the currently executing frame (frame 0) can reliably + /// provide every register in the register context. + /// + /// @return + /// The RegisterContext shared point for this frame. + //------------------------------------------------------------------ + lldb::RegisterContextSP GetRegisterContext(); + + const lldb::RegisterContextSP &GetRegisterContextSP() const { + return m_reg_context_sp; + } + + //------------------------------------------------------------------ + /// Retrieve the list of variables that are in scope at this StackFrame's pc. + /// + /// A frame that is not live may return an empty VariableList for a given + /// pc value even though variables would be available at this point if + /// it were a live stack frame. + /// + /// @param[in] get_file_globals + /// Whether to also retrieve compilation-unit scoped variables + /// that are visible to the entire compilation unit (e.g. file + /// static in C, globals that are homed in this CU). + /// + /// @return + /// A pointer to a list of variables. + //------------------------------------------------------------------ + VariableList *GetVariableList(bool get_file_globals); + + //------------------------------------------------------------------ + /// Retrieve the list of variables that are in scope at this StackFrame's pc. + /// + /// A frame that is not live may return an empty VariableListSP for a + /// given pc value even though variables would be available at this point + /// if it were a live stack frame. + /// + /// @param[in] get_file_globals + /// Whether to also retrieve compilation-unit scoped variables + /// that are visible to the entire compilation unit (e.g. file + /// static in C, globals that are homed in this CU). + /// + /// @return + /// A pointer to a list of variables. + //------------------------------------------------------------------ + lldb::VariableListSP + GetInScopeVariableList(bool get_file_globals, + bool must_have_valid_location = false); + + //------------------------------------------------------------------ + /// Create a ValueObject for a variable name / pathname, possibly + /// including simple dereference/child selection syntax. + /// + /// @param[in] var_expr + /// The string specifying a variable to base the VariableObject off + /// of. + /// + /// @param[in] use_dynamic + /// Whether the correct dynamic type of an object pointer should be + /// determined before creating the object, or if the static type is + /// sufficient. One of the DynamicValueType enumerated values. + /// + /// @param[in] options + /// An unsigned integer of flags, values from + /// StackFrame::ExpressionPathOption + /// enum. + /// @param[in] var_sp + /// A VariableSP that will be set to the variable described in the + /// var_expr path. + /// + /// @param[in] error + /// Record any errors encountered while evaluating var_expr. + /// + /// @return + /// A shared pointer to the ValueObject described by var_expr. + //------------------------------------------------------------------ + lldb::ValueObjectSP GetValueForVariableExpressionPath( + llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, + uint32_t options, lldb::VariableSP &var_sp, Error &error); + + //------------------------------------------------------------------ + /// Determine whether this StackFrame has debug information available or not + /// + /// @return + // true if debug information is available for this frame (function, + // compilation unit, block, etc.) + //------------------------------------------------------------------ + bool HasDebugInformation(); + + //------------------------------------------------------------------ + /// Return the disassembly for the instructions of this StackFrame's function + /// as a single C string. + /// + /// @return + // C string with the assembly instructions for this function. + //------------------------------------------------------------------ + const char *Disassemble(); + + //------------------------------------------------------------------ + /// Print a description for this frame using the frame-format formatter + /// settings. + /// + /// @param [in] strm + /// The Stream to print the description to. + /// + /// @param [in] frame_marker + /// Optional string that will be prepended to the frame output description. + //------------------------------------------------------------------ + void DumpUsingSettingsFormat(Stream *strm, + const char *frame_marker = nullptr); + + //------------------------------------------------------------------ + /// Print a description for this frame using a default format. + /// + /// @param [in] strm + /// The Stream to print the description to. + /// + /// @param [in] show_frame_index + /// Whether to print the frame number or not. + /// + /// @param [in] show_fullpaths + /// Whether to print the full source paths or just the file base name. + //------------------------------------------------------------------ + void Dump(Stream *strm, bool show_frame_index, bool show_fullpaths); + + //------------------------------------------------------------------ + /// Print a description of this stack frame and/or the source context/assembly + /// for this stack frame. + /// + /// @param[in] strm + /// The Stream to send the output to. + /// + /// @param[in] show_frame_info + /// If true, print the frame info by calling DumpUsingSettingsFormat(). + /// + /// @param[in] show_source + /// If true, print source or disassembly as per the user's settings. + /// + /// @param[in] frame_marker + /// Passed to DumpUsingSettingsFormat() for the frame info printing. + /// + /// @return + /// Returns true if successful. + //------------------------------------------------------------------ + bool GetStatus(Stream &strm, bool show_frame_info, bool show_source, + const char *frame_marker = nullptr); + + //------------------------------------------------------------------ + /// Query whether this frame is a concrete frame on the call stack, + /// or if it is an inlined frame derived from the debug information + /// and presented by the debugger. + /// + /// @return + /// true if this is an inlined frame. + //------------------------------------------------------------------ + bool IsInlined(); + + //------------------------------------------------------------------ + /// Query this frame to find what frame it is in this Thread's StackFrameList. + /// + /// @return + /// StackFrame index 0 indicates the currently-executing function. Inline + /// frames are included in this frame index count. + //------------------------------------------------------------------ + uint32_t GetFrameIndex() const; + + //------------------------------------------------------------------ + /// Query this frame to find what frame it is in this Thread's StackFrameList, + /// not counting inlined frames. + /// + /// @return + /// StackFrame index 0 indicates the currently-executing function. Inline + /// frames are not included in this frame index count; their concrete + /// frame index will be the same as the concrete frame that they are + /// derived from. + //------------------------------------------------------------------ + uint32_t GetConcreteFrameIndex() const { return m_concrete_frame_index; } + + //------------------------------------------------------------------ + /// Create a ValueObject for a given Variable in this StackFrame. + /// + /// @params [in] variable_sp + /// The Variable to base this ValueObject on + /// + /// @params [in] use_dynamic + /// Whether the correct dynamic type of the variable should be + /// determined before creating the ValueObject, or if the static type + /// is sufficient. One of the DynamicValueType enumerated values. + /// + /// @return + // A ValueObject for this variable. + //------------------------------------------------------------------ + lldb::ValueObjectSP + GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp, + lldb::DynamicValueType use_dynamic); + + //------------------------------------------------------------------ + /// Add an arbitrary Variable object (e.g. one that specifics a global or + /// static) + /// to a StackFrame's list of ValueObjects. + /// + /// @params [in] variable_sp + /// The Variable to base this ValueObject on + /// + /// @params [in] use_dynamic + /// Whether the correct dynamic type of the variable should be + /// determined before creating the ValueObject, or if the static type + /// is sufficient. One of the DynamicValueType enumerated values. + /// + /// @return + // A ValueObject for this variable. + //------------------------------------------------------------------ + lldb::ValueObjectSP TrackGlobalVariable(const lldb::VariableSP &variable_sp, + lldb::DynamicValueType use_dynamic); + + //------------------------------------------------------------------ + /// Query this frame to determine what the default language should be + /// when parsing expressions given the execution context. + /// + /// @return + /// The language of the frame if known, else lldb::eLanguageTypeUnknown. + //------------------------------------------------------------------ + lldb::LanguageType GetLanguage(); + + // similar to GetLanguage(), but is allowed to take a potentially incorrect + // guess + // if exact information is not available + lldb::LanguageType GuessLanguage(); + + //------------------------------------------------------------------ + /// Attempt to econstruct the ValueObject for a given raw address touched by + /// the current instruction. The ExpressionPath should indicate how to get + /// to this value using "frame variable." + /// + /// @params [in] addr + /// The raw address. + /// + /// @return + /// The ValueObject if found. If valid, it has a valid ExpressionPath. + //------------------------------------------------------------------ + lldb::ValueObjectSP GuessValueForAddress(lldb::addr_t addr); + + //------------------------------------------------------------------ + /// Attempt to reconstruct the ValueObject for the address contained in a + /// given register plus an offset. The ExpressionPath should indicate how to + /// get to this value using "frame variable." + /// + /// @params [in] reg + /// The name of the register. + /// + /// @params [in] offset + /// The offset from the register. Particularly important for sp... + /// + /// @return + /// The ValueObject if found. If valid, it has a valid ExpressionPath. + //------------------------------------------------------------------ + lldb::ValueObjectSP GuessValueForRegisterAndOffset(ConstString reg, + int64_t offset); + + //------------------------------------------------------------------ + // 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; protected: - friend class StackFrameList; + friend class StackFrameList; - void - SetSymbolContextScope (SymbolContextScope *symbol_scope); + void SetSymbolContextScope(SymbolContextScope *symbol_scope); - void - UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame); + void UpdateCurrentFrameFromPreviousFrame(StackFrame &prev_frame); - void - UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame); + void UpdatePreviousFrameFromCurrentFrame(StackFrame &curr_frame); + + bool HasCachedData() const; - bool - HasCachedData () const; - private: - //------------------------------------------------------------------ - // For StackFrame only - //------------------------------------------------------------------ - lldb::ThreadWP m_thread_wp; - uint32_t m_frame_index; - uint32_t m_concrete_frame_index; - lldb::RegisterContextSP m_reg_context_sp; - StackID m_id; - Address m_frame_code_addr; // The frame code address (might not be the same as the actual PC for inlined frames) as a section/offset address - SymbolContext m_sc; - Flags m_flags; - Scalar m_frame_base; - Error m_frame_base_error; - bool m_cfa_is_valid; // Does this frame have a CFA? Different from CFA == LLDB_INVALID_ADDRESS - uint32_t m_stop_id; - 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; - ValueObjectList m_variable_list_value_objects; // Value objects for each variable in m_variable_list_sp - StreamString m_disassembly; - std::recursive_mutex m_mutex; - - DISALLOW_COPY_AND_ASSIGN (StackFrame); + //------------------------------------------------------------------ + // For StackFrame only + //------------------------------------------------------------------ + lldb::ThreadWP m_thread_wp; + uint32_t m_frame_index; + uint32_t m_concrete_frame_index; + lldb::RegisterContextSP m_reg_context_sp; + StackID m_id; + Address m_frame_code_addr; // The frame code address (might not be the same as + // the actual PC for inlined frames) as a + // section/offset address + SymbolContext m_sc; + Flags m_flags; + Scalar m_frame_base; + Error m_frame_base_error; + bool m_cfa_is_valid; // Does this frame have a CFA? Different from CFA == + // LLDB_INVALID_ADDRESS + uint32_t m_stop_id; + 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; + ValueObjectList m_variable_list_value_objects; // Value objects for each + // variable in + // m_variable_list_sp + StreamString m_disassembly; + std::recursive_mutex m_mutex; + + DISALLOW_COPY_AND_ASSIGN(StackFrame); }; } // namespace lldb_private |