Index: test/tools/lldb-mi/TestMiStack.py =================================================================== --- test/tools/lldb-mi/TestMiStack.py +++ test/tools/lldb-mi/TestMiStack.py @@ -194,6 +194,34 @@ @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows") @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races @skipIfLinux # llvm.org/pr22411: Failure presumably due to known thread races + def test_lldbmi_stack_info_frame(self): + """Test that 'lldb-mi --interpreter' can show information about current frame.""" + + self.spawnLldbMi(args = None) + + # Test that -stack-info-frame fails when program isn't running + self.runCmd("-stack-info-frame") + self.expect("\^error,msg=\"Command 'stack-info-frame'. Invalid process during debug session\"") + + # Load executable + self.runCmd("-file-exec-and-symbols %s" % self.myexe) + self.expect("\^done") + + # Run to main + self.runCmd("-break-insert -f main") + self.expect("\^done,bkpt={number=\"1\"") + self.runCmd("-exec-run") + self.expect("\^running") + self.expect("\*stopped,reason=\"breakpoint-hit\"") + + # Test that -stack-info-frame works when program is running + self.runCmd("-stack-info-frame") + self.expect("\^done,frame=\{level=\"0\",addr=\".+\",func=\"main\",file=\"main\.c\",fullname=\".*main\.c\",line=\"\d+\"\}") + + @lldbmi_test + @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows") + @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races + @skipIfLinux # llvm.org/pr22411: Failure presumably due to known thread races def test_lldbmi_stack_list_frames(self): """Test that 'lldb-mi --interpreter' can lists the frames on the stack.""" Index: tools/lldb-mi/MICmdCmdStack.h =================================================================== --- tools/lldb-mi/MICmdCmdStack.h +++ tools/lldb-mi/MICmdCmdStack.h @@ -11,6 +11,7 @@ // File: MICmdCmdStack.h // // Overview: CMICmdCmdStackInfoDepth interface. +// CMICmdCmdStackInfoFrame interface. // CMICmdCmdStackListFrames interface. // CMICmdCmdStackListArguments interface. // CMICmdCmdStackListLocals interface. @@ -36,6 +37,7 @@ // In-house headers: #include "MICmdBase.h" #include "MICmnMIValueList.h" +#include "MICmnMIValueTuple.h" //++ ============================================================================ // Details: MI command class. MI commands derived from the command base class. @@ -73,6 +75,35 @@ //++ ============================================================================ // Details: MI command class. MI commands derived from the command base class. +// *this class implements MI command "stack-info-frame". +//-- +class CMICmdCmdStackInfoFrame : public CMICmdBase +{ + // Statics: + public: + // Required by the CMICmdFactory when registering *this command + static CMICmdBase *CreateSelf(void); + + // Methods: + public: + /* ctor */ CMICmdCmdStackInfoFrame(void); + + // Overridden: + public: + // From CMICmdInvoker::ICmd + virtual bool Execute(void); + virtual bool Acknowledge(void); + virtual bool ParseArgs(void); + // From CMICmnBase + /* dtor */ virtual ~CMICmdCmdStackInfoFrame(void); + + // Attributes: + private: + CMICmnMIValueTuple m_miValueTuple; +}; + +//++ ============================================================================ +// Details: MI command class. MI commands derived from the command base class. // *this class implements MI command "stack-list-frames". // Gotchas: None. // Authors: Illya Rudkin 21/03/2014. Index: tools/lldb-mi/MICmdCmdStack.cpp =================================================================== --- tools/lldb-mi/MICmdCmdStack.cpp +++ tools/lldb-mi/MICmdCmdStack.cpp @@ -11,6 +11,7 @@ // File: MICmdCmdStack.cpp // // Overview: CMICmdCmdStackInfoDepth implementation. +// CMICmdCmdStackInfoFrame implementation. // CMICmdCmdStackListFrames implementation. // CMICmdCmdStackListArguments implementation. // CMICmdCmdStackListLocals implementation. @@ -158,6 +159,113 @@ //--------------------------------------------------------------------------------------- //++ ------------------------------------------------------------------------------------ +// Details: CMICmdCmdStackInfoFrame constructor. +// Type: Method. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMICmdCmdStackInfoFrame::CMICmdCmdStackInfoFrame(void) +{ + // Command factory matches this name with that received from the stdin stream + m_strMiCmd = "stack-info-frame"; + + // Required by the CMICmdFactory when registering *this command + m_pSelfCreatorFn = &CMICmdCmdStackInfoFrame::CreateSelf; +} + +//++ ------------------------------------------------------------------------------------ +// Details: CMICmdCmdStackInfoFrame destructor. +// Type: Overrideable. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMICmdCmdStackInfoFrame::~CMICmdCmdStackInfoFrame(void) +{ +} + +//++ ------------------------------------------------------------------------------------ +// Details: The invoker requires this function. The parses the command line options +// arguments to extract values for each of those arguments. +// Type: Overridden. +// Args: None. +// Return: MIstatus::success - Function succeeded. +// MIstatus::failure - Function failed. +// Throws: None. +//-- +bool +CMICmdCmdStackInfoFrame::ParseArgs(void) +{ + return ParseValidateCmdOptions(); +} + +//++ ------------------------------------------------------------------------------------ +// Details: The invoker requires this function. The command does work in this function. +// The command is likely to communicate with the LLDB SBDebugger in here. +// Type: Overridden. +// Args: None. +// Return: MIstatus::success - Function succeeded. +// MIstatus::failure - Function failed. +// Throws: None. +//-- +bool +CMICmdCmdStackInfoFrame::Execute(void) +{ + CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); + lldb::SBProcess sbProcess = rSessionInfo.GetProcess(); + if (!sbProcess.IsValid()) + { + SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS), m_cmdData.strMiCmd.c_str())); + return MIstatus::failure; + } + + lldb::SBThread sbThread = sbProcess.GetSelectedThread(); + MIuint nFrameId = sbThread.GetSelectedFrame().GetFrameID(); + if (!rSessionInfo.MIResponseFormFrameInfo(sbThread, nFrameId, m_miValueTuple)) + return MIstatus::failure; + + return MIstatus::success; +} + +//++ ------------------------------------------------------------------------------------ +// Details: The invoker requires this function. The command prepares a MI Record Result +// for the work carried out in the Execute(). +// Type: Overridden. +// Args: None. +// Return: MIstatus::success - Function succeeded. +// MIstatus::failure - Function failed. +// Throws: None. +//-- +bool +CMICmdCmdStackInfoFrame::Acknowledge(void) +{ + const CMICmnMIValueResult miValueResult("frame", m_miValueTuple); + const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult); + m_miResultRecord = miRecordResult; + + return MIstatus::success; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Required by the CMICmdFactory when registering *this command. The factory +// calls this function to create an instance of *this command. +// Type: Static method. +// Args: None. +// Return: CMICmdBase * - Pointer to a new command. +// Throws: None. +//-- +CMICmdBase * +CMICmdCmdStackInfoFrame::CreateSelf(void) +{ + return new CMICmdCmdStackInfoFrame(); +} + +//--------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------- + +//++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdStackListFrames constructor. // Type: Method. // Args: None. Index: tools/lldb-mi/MICmdCommands.cpp =================================================================== --- tools/lldb-mi/MICmdCommands.cpp +++ tools/lldb-mi/MICmdCommands.cpp @@ -117,6 +117,7 @@ bOk &= Register(); bOk &= Register(); bOk &= Register(); + bOk &= Register(); bOk &= Register(); bOk &= Register(); bOk &= Register();