diff options
Diffstat (limited to 'lldb/tools')
| -rw-r--r-- | lldb/tools/lldb-mi/MICmdCmdStack.cpp | 194 | ||||
| -rw-r--r-- | lldb/tools/lldb-mi/MICmdCmdStack.h | 36 | ||||
| -rw-r--r-- | lldb/tools/lldb-mi/MICmdCommands.cpp | 1 | ||||
| -rw-r--r-- | lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp | 49 | ||||
| -rw-r--r-- | lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h | 4 |
5 files changed, 277 insertions, 7 deletions
diff --git a/lldb/tools/lldb-mi/MICmdCmdStack.cpp b/lldb/tools/lldb-mi/MICmdCmdStack.cpp index 1a23a9de03f..d608ad49fac 100644 --- a/lldb/tools/lldb-mi/MICmdCmdStack.cpp +++ b/lldb/tools/lldb-mi/MICmdCmdStack.cpp @@ -850,6 +850,200 @@ CMICmdCmdStackListLocals::CreateSelf(void) //--------------------------------------------------------------------------------------- //++ ------------------------------------------------------------------------------------ +// Details: CMICmdCmdStackListVariables constructor. +// Type: Method. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMICmdCmdStackListVariables::CMICmdCmdStackListVariables(void) + : m_bThreadInvalid(false) + , m_miValueList(true) + , m_constStrArgThread("thread") + , m_constStrArgFrame("frame") + , m_constStrArgPrintValues("print-values") + , m_constStrArgNoValues("no-values") + , m_constStrArgAllValues("all-values") + , m_constStrArgSimpleValues("simple-values") +{ + // Command factory matches this name with that received from the stdin stream + m_strMiCmd = "stack-list-variables"; + + // Required by the CMICmdFactory when registering *this command + m_pSelfCreatorFn = &CMICmdCmdStackListVariables::CreateSelf; +} + +//++ ------------------------------------------------------------------------------------ +// Details: CMICmdCmdStackListVariables destructor. +// Type: Overrideable. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMICmdCmdStackListVariables::~CMICmdCmdStackListVariables(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 - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool +CMICmdCmdStackListVariables::ParseArgs(void) +{ + bool bOk = + m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1))); + bOk = bOk && + m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgFrame, false, true, CMICmdArgValListBase::eArgValType_Number, 1))); + bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgPrintValues, false, true))); + bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgNoValues, false, true))); + bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgAllValues, false, true))); + bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgSimpleValues, false, true))); + return (bOk && 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 - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool +CMICmdCmdStackListVariables::Execute(void) +{ + CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread); + CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame); + CMICMDBASE_GETOPTION(pArgPrintValues, Number, m_constStrArgPrintValues); + CMICMDBASE_GETOPTION(pArgNoValues, OptionLong, m_constStrArgNoValues); + CMICMDBASE_GETOPTION(pArgAllValues, OptionLong, m_constStrArgAllValues); + CMICMDBASE_GETOPTION(pArgSimpleValues, OptionLong, m_constStrArgSimpleValues); + + // Retrieve the --thread option's thread ID (only 1) + MIuint64 nThreadId = UINT64_MAX; + if (pArgThread->GetFound()) + { + if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) + { + SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str())); + return MIstatus::failure; + } + } + + MIuint64 nFrame = UINT64_MAX; + if (pArgFrame->GetFound()) + { + if (!pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame)) + { + SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgFrame.c_str())); + return MIstatus::failure; + } + } + + CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat; + if (pArgPrintValues->GetFound()) + { + const MIuint nPrintValues = pArgPrintValues->GetValue(); + if (nPrintValues >= CMICmnLLDBDebugSessionInfo::kNumVariableInfoFormats) + { + SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PRINT_VALUES), m_cmdData.strMiCmd.c_str())); + return MIstatus::failure; + } + eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(nPrintValues); + } + else if (pArgNoValues->GetFound()) + eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues; + else if (pArgAllValues->GetFound()) + eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues; + else if (pArgSimpleValues->GetFound()) + eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues; + else + { + SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PRINT_VALUES), m_cmdData.strMiCmd.c_str())); + return MIstatus::failure; + } + + CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); + lldb::SBProcess sbProcess = rSessionInfo.GetProcess(); + lldb::SBThread thread = (nThreadId != UINT64_MAX) ? sbProcess.GetThreadByIndexID(nThreadId) : sbProcess.GetSelectedThread(); + m_bThreadInvalid = !thread.IsValid(); + if (m_bThreadInvalid) + return MIstatus::success; + + const lldb::StopReason eStopReason = thread.GetStopReason(); + if ((eStopReason == lldb::eStopReasonNone) || (eStopReason == lldb::eStopReasonInvalid)) + { + m_bThreadInvalid = true; + return MIstatus::success; + } + + lldb::SBFrame frame = (nFrame != UINT64_MAX) ? thread.GetFrameAtIndex(nFrame) : thread.GetSelectedFrame(); + + CMICmnMIValueList miValueList(true); + const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Arguments | CMICmnLLDBDebugSessionInfo::eVariableType_Locals; + if (!rSessionInfo.MIResponseFormVariableInfo(frame, maskVarTypes, eVarInfoFormat, miValueList, 10, true)) + return MIstatus::failure; + m_miValueList = miValueList; + + 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 - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool +CMICmdCmdStackListVariables::Acknowledge(void) +{ + if (m_bThreadInvalid) + { + // MI print "%s^done,variables=[]" + const CMICmnMIValueList miValueList(true); + const CMICmnMIValueResult miValueResult("variables", miValueList); + const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult); + m_miResultRecord = miRecordResult; + return MIstatus::success; + } + + // MI print "%s^done,variables=[%s]" + const CMICmnMIValueResult miValueResult("variables", m_miValueList); + 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 * +CMICmdCmdStackListVariables::CreateSelf(void) +{ + return new CMICmdCmdStackListVariables(); +} + +//--------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------- + +//++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdStackSelectFrame constructor. // Type: Method. // Args: None. diff --git a/lldb/tools/lldb-mi/MICmdCmdStack.h b/lldb/tools/lldb-mi/MICmdCmdStack.h index 732df0240e2..f5b02976f3e 100644 --- a/lldb/tools/lldb-mi/MICmdCmdStack.h +++ b/lldb/tools/lldb-mi/MICmdCmdStack.h @@ -214,6 +214,42 @@ class CMICmdCmdStackListLocals : public CMICmdBase //++ ============================================================================ // Details: MI command class. MI commands derived from the command base class. +// *this class implements MI command "stack-list-variables". +//-- +class CMICmdCmdStackListVariables : public CMICmdBase +{ + // Statics: +public: + // Required by the CMICmdFactory when registering *this command + static CMICmdBase *CreateSelf(void); + + // Methods: +public: + /* ctor */ CMICmdCmdStackListVariables(void); + + // Overridden: +public: + // From CMICmdInvoker::ICmd + virtual bool Execute(void); + virtual bool Acknowledge(void); + virtual bool ParseArgs(void); + // From CMICmnBase + /* dtor */ virtual ~CMICmdCmdStackListVariables(void); + + // Attributes +private: + bool m_bThreadInvalid; // True = yes invalid thread, false = thread object valid + CMICmnMIValueList m_miValueList; + const CMIUtilString m_constStrArgThread; + const CMIUtilString m_constStrArgFrame; + const CMIUtilString m_constStrArgPrintValues; + const CMIUtilString m_constStrArgNoValues; + const CMIUtilString m_constStrArgAllValues; + const CMIUtilString m_constStrArgSimpleValues; +}; + +//++ ============================================================================ +// Details: MI command class. MI commands derived from the command base class. // *this class implements MI command "stack-select-frame". //-- class CMICmdCmdStackSelectFrame : public CMICmdBase diff --git a/lldb/tools/lldb-mi/MICmdCommands.cpp b/lldb/tools/lldb-mi/MICmdCommands.cpp index 2d8f24887a1..9afe30e8c2c 100644 --- a/lldb/tools/lldb-mi/MICmdCommands.cpp +++ b/lldb/tools/lldb-mi/MICmdCommands.cpp @@ -115,6 +115,7 @@ MICmnCommands::RegisterAll(void) bOk &= Register<CMICmdCmdStackListFrames>(); bOk &= Register<CMICmdCmdStackListArguments>(); bOk &= Register<CMICmdCmdStackListLocals>(); + bOk &= Register<CMICmdCmdStackListVariables>(); bOk &= Register<CMICmdCmdStackSelectFrame>(); bOk &= Register<CMICmdCmdSupportListFeatures>(); bOk &= Register<CMICmdCmdSymbolListLines>(); diff --git a/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp b/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp index 58a30f5cb11..ca788108857 100644 --- a/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp +++ b/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp @@ -431,7 +431,8 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo(const SMICmdData &vCmdData, bool CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes, const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList, - const MIuint vnMaxDepth /* = 10 */) + const MIuint vnMaxDepth, /* = 10 */ + const bool vbMarkArgs /* = false*/) { bool bOk = MIstatus::success; lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame); @@ -440,14 +441,40 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo(const lldb::SBFrame &vrFr const bool bLocals = (vMaskVarTypes & eVariableType_Locals); const bool bStatics = (vMaskVarTypes & eVariableType_Statics); const bool bInScopeOnly = (vMaskVarTypes & eVariableType_InScope); - lldb::SBValueList listArg = rFrame.GetVariables(bArg, bLocals, bStatics, bInScopeOnly); - const MIuint nArgs = listArg.GetSize(); + + // Handle arguments first + lldb::SBValueList listArg = rFrame.GetVariables(bArg, false, false, false); + bOk = bOk && MIResponseForVariableInfoInternal(veVarInfoFormat, vwrMiValueList, listArg, vnMaxDepth, true, vbMarkArgs); + + // Handle remaining variables + lldb::SBValueList listVars = rFrame.GetVariables(false, bLocals, bStatics, bInScopeOnly); + bOk = bOk && MIResponseForVariableInfoInternal(veVarInfoFormat, vwrMiValueList, listVars, vnMaxDepth, false, vbMarkArgs); + + return bOk; +} + +bool +CMICmnLLDBDebugSessionInfo::MIResponseForVariableInfoInternal(const VariableInfoFormat_e veVarInfoFormat, + CMICmnMIValueList &vwrMiValueList, + const lldb::SBValueList &vwrSBValueList, + const MIuint vnMaxDepth, + const bool vbIsArgs, + const bool vbMarkArgs) +{ + bool bOk = MIstatus::success; + const MIuint nArgs = vwrSBValueList.GetSize(); for (MIuint i = 0; bOk && (i < nArgs); i++) { CMICmnMIValueTuple miValueTuple; - lldb::SBValue value = listArg.GetValueAtIndex(i); + lldb::SBValue value = vwrSBValueList.GetValueAtIndex(i); const CMICmnMIValueConst miValueConst(value.GetName()); const CMICmnMIValueResult miValueResultName("name", miValueConst); + if (vbMarkArgs && vbIsArgs) + { + const CMICmnMIValueConst miValueConstArg("1"); + const CMICmnMIValueResult miValueResultArg("arg", miValueConstArg); + miValueTuple.Add(miValueResultArg); + } if (veVarInfoFormat != eVariableInfoFormat_NoValues) { const MIuint nChildren = value.GetNumChildren(); @@ -468,8 +495,18 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo(const lldb::SBFrame &vrFr } } } - // If we are printing name only then no need to put it in the tuple. - vwrMiValueList.Add(miValueResultName); + + if (vbMarkArgs) + { + // If we are printing names only with vbMarkArgs, we still need to add the name to the value tuple + miValueTuple.Add(miValueResultName); // name + vwrMiValueList.Add(miValueTuple); + } + else + { + // If we are printing name only then no need to put it in the tuple. + vwrMiValueList.Add(miValueResultName); + } } return bOk; } diff --git a/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h b/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h index 7516db02678..94205956ff4 100644 --- a/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h +++ b/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h @@ -159,7 +159,7 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton<CMIC const ThreadInfoFormat_e veThreadInfoFormat, CMICmnMIValueTuple &vwrMIValueTuple); bool MIResponseFormVariableInfo(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes, const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList, - const MIuint vnMaxDepth = 10); + const MIuint vnMaxDepth = 10, const bool vbMarkArgs = false); bool MIResponseFormBrkPtFrameInfo(const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple); bool MIResponseFormBrkPtInfo(const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple); bool GetBrkPtInfo(const lldb::SBBreakpoint &vBrkPt, SBrkPtInfo &vrwBrkPtInfo) const; @@ -204,6 +204,8 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton<CMIC CMIUtilString &vwPath, MIuint &vwnLine); bool GetThreadFrames(const SMICmdData &vCmdData, const MIuint vThreadIdx, const FrameInfoFormat_e veFrameInfoFormat, CMIUtilString &vwrThreadFrames); + bool MIResponseForVariableInfoInternal(const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList, + const lldb::SBValueList &vwrSBValueList, const MIuint vnMaxDepth, const bool vbIsArgs, const bool vbMarkArgs); // Overridden: private: |

