summaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/tools/lldb-mi/MICmdCmdStack.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/tools/lldb-mi/MICmdCmdStack.cpp')
-rw-r--r--contrib/llvm-project/lldb/tools/lldb-mi/MICmdCmdStack.cpp1053
1 files changed, 1053 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/tools/lldb-mi/MICmdCmdStack.cpp b/contrib/llvm-project/lldb/tools/lldb-mi/MICmdCmdStack.cpp
new file mode 100644
index 000000000000..599db37417f5
--- /dev/null
+++ b/contrib/llvm-project/lldb/tools/lldb-mi/MICmdCmdStack.cpp
@@ -0,0 +1,1053 @@
+//===-- MICmdCmdStack.cpp ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// Overview: CMICmdCmdStackInfoDepth implementation.
+// CMICmdCmdStackInfoFrame implementation.
+// CMICmdCmdStackListFrames implementation.
+// CMICmdCmdStackListArguments implementation.
+// CMICmdCmdStackListLocals implementation.
+// CMICmdCmdStackSelectFrame implementation.
+
+// Third Party Headers:
+#include "lldb/API/SBThread.h"
+
+// In-house headers:
+#include "MICmdArgValListOfN.h"
+#include "MICmdArgValNumber.h"
+#include "MICmdArgValOptionLong.h"
+#include "MICmdArgValOptionShort.h"
+#include "MICmdArgValPrintValues.h"
+#include "MICmdArgValString.h"
+#include "MICmdArgValThreadGrp.h"
+#include "MICmdCmdStack.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+#include "MICmnLLDBDebugger.h"
+#include "MICmnMIOutOfBandRecord.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueConst.h"
+
+#include <algorithm>
+
+//++
+// Details: CMICmdCmdStackInfoDepth constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackInfoDepth::CMICmdCmdStackInfoDepth()
+ : m_nThreadFrames(0), m_constStrArgMaxDepth("max-depth") {
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "stack-info-depth";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdStackInfoDepth::CreateSelf;
+}
+
+//++
+// Details: CMICmdCmdStackInfoDepth destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackInfoDepth::~CMICmdCmdStackInfoDepth() {}
+
+//++
+// 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 CMICmdCmdStackInfoDepth::ParseArgs() {
+ m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgMaxDepth, false, false));
+ 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 - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackInfoDepth::Execute() {
+ CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
+ CMICMDBASE_GETOPTION(pArgMaxDepth, Number, m_constStrArgMaxDepth);
+
+ // Retrieve the --thread option's thread ID (only 1)
+ MIuint64 nThreadId = UINT64_MAX;
+ if (pArgThread->GetFound() &&
+ !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;
+ }
+
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(
+ CMICmnLLDBDebugSessionInfo::Instance());
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
+ lldb::SBThread thread = (nThreadId != UINT64_MAX)
+ ? sbProcess.GetThreadByIndexID(nThreadId)
+ : sbProcess.GetSelectedThread();
+ m_nThreadFrames = thread.GetNumFrames();
+
+ 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 CMICmdCmdStackInfoDepth::Acknowledge() {
+ const CMIUtilString strDepth(CMIUtilString::Format("%d", m_nThreadFrames));
+ const CMICmnMIValueConst miValueConst(strDepth);
+ const CMICmnMIValueResult miValueResult("depth", miValueConst);
+ 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 *CMICmdCmdStackInfoDepth::CreateSelf() {
+ return new CMICmdCmdStackInfoDepth();
+}
+
+
+//++
+// Details: CMICmdCmdStackInfoFrame constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackInfoFrame::CMICmdCmdStackInfoFrame() {
+ // 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() {}
+
+//++
+// 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() { 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() {
+ 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,
+ CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_NoArguments,
+ 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() {
+ 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() {
+ return new CMICmdCmdStackInfoFrame();
+}
+
+
+//++
+// Details: CMICmdCmdStackListFrames constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackListFrames::CMICmdCmdStackListFrames()
+ : m_nThreadFrames(0), m_constStrArgFrameLow("low-frame"),
+ m_constStrArgFrameHigh("high-frame") {
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "stack-list-frames";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdStackListFrames::CreateSelf;
+}
+
+//++
+// Details: CMICmdCmdStackListFrames destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackListFrames::~CMICmdCmdStackListFrames() {
+ m_vecMIValueResult.clear();
+}
+
+//++
+// 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 CMICmdCmdStackListFrames::ParseArgs() {
+ m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrameLow, false, true));
+ m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrameHigh, false, true));
+ 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 - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackListFrames::Execute() {
+ CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
+ CMICMDBASE_GETOPTION(pArgFrameLow, Number, m_constStrArgFrameLow);
+ CMICMDBASE_GETOPTION(pArgFrameHigh, Number, m_constStrArgFrameHigh);
+
+ // Retrieve the --thread option's thread ID (only 1)
+ MIuint64 nThreadId = UINT64_MAX;
+ if (pArgThread->GetFound() &&
+ !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;
+ }
+
+ // Frame low and high options are not mandatory
+ MIuint nFrameHigh =
+ pArgFrameHigh->GetFound() ? pArgFrameHigh->GetValue() : UINT32_MAX;
+ const MIuint nFrameLow =
+ pArgFrameLow->GetFound() ? pArgFrameLow->GetValue() : 0;
+
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(
+ CMICmnLLDBDebugSessionInfo::Instance());
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
+ lldb::SBThread thread = (nThreadId != UINT64_MAX)
+ ? sbProcess.GetThreadByIndexID(nThreadId)
+ : sbProcess.GetSelectedThread();
+ MIuint nThreadFrames = thread.GetNumFrames();
+
+ // Adjust nThreadFrames for the nFrameHigh argument as we use nFrameHigh+1 in
+ // the min calc as the arg
+ // is not an index, but a frame id value.
+ if (nFrameHigh < UINT32_MAX) {
+ nFrameHigh++;
+ nThreadFrames = (nFrameHigh < nThreadFrames) ? nFrameHigh : nThreadFrames;
+ }
+
+ m_nThreadFrames = nThreadFrames;
+ if (nThreadFrames == 0)
+ return MIstatus::success;
+
+ m_vecMIValueResult.clear();
+ for (MIuint nLevel = nFrameLow; nLevel < nThreadFrames; nLevel++) {
+ CMICmnMIValueTuple miValueTuple;
+ if (!rSessionInfo.MIResponseFormFrameInfo(
+ thread, nLevel,
+ CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_NoArguments,
+ miValueTuple))
+ return MIstatus::failure;
+
+ const CMICmnMIValueResult miValueResult8("frame", miValueTuple);
+ m_vecMIValueResult.push_back(miValueResult8);
+ }
+
+ 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 CMICmdCmdStackListFrames::Acknowledge() {
+ if (m_nThreadFrames == 0) {
+ // MI print "3^done,stack=[{}]"
+ const CMICmnMIValueTuple miValueTuple;
+ const CMICmnMIValueList miValueList(miValueTuple);
+ const CMICmnMIValueResult miValueResult("stack", miValueList);
+ const CMICmnMIResultRecord miRecordResult(
+ m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
+ miValueResult);
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+ }
+
+ // Build up a list of thread information from tuples
+ VecMIValueResult_t::const_iterator it = m_vecMIValueResult.begin();
+ if (it == m_vecMIValueResult.end()) {
+ // MI print "3^done,stack=[{}]"
+ const CMICmnMIValueTuple miValueTuple;
+ const CMICmnMIValueList miValueList(miValueTuple);
+ const CMICmnMIValueResult miValueResult("stack", miValueList);
+ const CMICmnMIResultRecord miRecordResult(
+ m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
+ miValueResult);
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+ CMICmnMIValueList miValueList(*it);
+ ++it;
+ while (it != m_vecMIValueResult.end()) {
+ const CMICmnMIValueResult &rTuple(*it);
+ miValueList.Add(rTuple);
+
+ // Next
+ ++it;
+ }
+ const CMICmnMIValueResult miValueResult("stack", 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 *CMICmdCmdStackListFrames::CreateSelf() {
+ return new CMICmdCmdStackListFrames();
+}
+
+
+//++
+// Details: CMICmdCmdStackListArguments constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackListArguments::CMICmdCmdStackListArguments()
+ : m_bThreadInvalid(false), m_miValueList(true),
+ m_constStrArgPrintValues("print-values"),
+ m_constStrArgFrameLow("low-frame"), m_constStrArgFrameHigh("high-frame") {
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "stack-list-arguments";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdStackListArguments::CreateSelf;
+}
+
+//++
+// Details: CMICmdCmdStackListArguments destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackListArguments::~CMICmdCmdStackListArguments() {}
+
+//++
+// 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 CMICmdCmdStackListArguments::ParseArgs() {
+ m_setCmdArgs.Add(
+ new CMICmdArgValPrintValues(m_constStrArgPrintValues, true, true));
+ m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrameLow, false, true));
+ m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrameHigh, false, true));
+ 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 - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackListArguments::Execute() {
+ CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
+ CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
+ CMICMDBASE_GETOPTION(pArgFrameLow, Number, m_constStrArgFrameLow);
+ CMICMDBASE_GETOPTION(pArgFrameHigh, Number, m_constStrArgFrameHigh);
+
+ // 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;
+ }
+ }
+
+ const CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
+ static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
+ pArgPrintValues->GetValue());
+
+ MIuint nFrameLow = 0;
+ MIuint nFrameHigh = UINT32_MAX;
+ if (pArgFrameLow->GetFound() && pArgFrameHigh->GetFound()) {
+ nFrameLow = pArgFrameLow->GetValue();
+ nFrameHigh = pArgFrameHigh->GetValue() + 1;
+ } else if (pArgFrameLow->GetFound() || pArgFrameHigh->GetFound()) {
+ // Only low-frame or high-frame was specified but both are required
+ SetError(
+ CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_FRAME_RANGE_INVALID),
+ 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;
+ }
+
+ const MIuint nFrames = thread.GetNumFrames();
+ if (nFrameLow >= nFrames) {
+ // The low-frame is larger than the actual number of frames
+ SetError(
+ CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_FRAME_RANGE_INVALID),
+ m_cmdData.strMiCmd.c_str()));
+ return MIstatus::failure;
+ }
+
+ nFrameHigh = std::min(nFrameHigh, nFrames);
+ for (MIuint i = nFrameLow; i < nFrameHigh; i++) {
+ lldb::SBFrame frame = thread.GetFrameAtIndex(i);
+ CMICmnMIValueList miValueList(true);
+ const MIuint maskVarTypes =
+ CMICmnLLDBDebugSessionInfo::eVariableType_Arguments;
+ if (!rSessionInfo.MIResponseFormVariableInfo(frame, maskVarTypes,
+ eVarInfoFormat, miValueList))
+ return MIstatus::failure;
+ const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", i));
+ const CMICmnMIValueResult miValueResult("level", miValueConst);
+ CMICmnMIValueTuple miValueTuple(miValueResult);
+ const CMICmnMIValueResult miValueResult2("args", miValueList);
+ miValueTuple.Add(miValueResult2);
+ const CMICmnMIValueResult miValueResult3("frame", miValueTuple);
+ m_miValueList.Add(miValueResult3);
+ }
+
+ 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 CMICmdCmdStackListArguments::Acknowledge() {
+ if (m_bThreadInvalid) {
+ // MI print "%s^done,stack-args=[]"
+ const CMICmnMIValueList miValueList(true);
+ const CMICmnMIValueResult miValueResult("stack-args", miValueList);
+ const CMICmnMIResultRecord miRecordResult(
+ m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
+ miValueResult);
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ // MI print
+ // "%s^done,stack-args=[frame={level=\"0\",args=[%s]},frame={level=\"1\",args=[%s]}]"
+ const CMICmnMIValueResult miValueResult4("stack-args", m_miValueList);
+ const CMICmnMIResultRecord miRecordResult(
+ m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
+ miValueResult4);
+ 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 *CMICmdCmdStackListArguments::CreateSelf() {
+ return new CMICmdCmdStackListArguments();
+}
+
+
+//++
+// Details: CMICmdCmdStackListLocals constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackListLocals::CMICmdCmdStackListLocals()
+ : m_bThreadInvalid(false), m_miValueList(true),
+ m_constStrArgPrintValues("print-values") {
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "stack-list-locals";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdStackListLocals::CreateSelf;
+}
+
+//++
+// Details: CMICmdCmdStackListLocals destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackListLocals::~CMICmdCmdStackListLocals() {}
+
+//++
+// 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 CMICmdCmdStackListLocals::ParseArgs() {
+ m_setCmdArgs.Add(
+ new CMICmdArgValPrintValues(m_constStrArgPrintValues, true, true));
+ 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 - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackListLocals::Execute() {
+ CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
+ CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
+ CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
+
+ // 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;
+ }
+ }
+
+ const CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
+ static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
+ pArgPrintValues->GetValue());
+
+ 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_Locals |
+ CMICmnLLDBDebugSessionInfo::eVariableType_InScope;
+ if (!rSessionInfo.MIResponseFormVariableInfo(frame, maskVarTypes,
+ eVarInfoFormat, miValueList))
+ 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 CMICmdCmdStackListLocals::Acknowledge() {
+ if (m_bThreadInvalid) {
+ // MI print "%s^done,locals=[]"
+ const CMICmnMIValueList miValueList(true);
+ const CMICmnMIValueResult miValueResult("locals", miValueList);
+ const CMICmnMIResultRecord miRecordResult(
+ m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
+ miValueResult);
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ // MI print "%s^done,locals=[%s]"
+ const CMICmnMIValueResult miValueResult("locals", 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 *CMICmdCmdStackListLocals::CreateSelf() {
+ return new CMICmdCmdStackListLocals();
+}
+
+
+//++
+// Details: CMICmdCmdStackListVariables constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackListVariables::CMICmdCmdStackListVariables()
+ : m_bThreadInvalid(false), m_miValueList(true),
+ m_constStrArgPrintValues("print-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() {}
+
+//++
+// 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() {
+ m_setCmdArgs.Add(
+ new CMICmdArgValPrintValues(m_constStrArgPrintValues, true, true));
+ 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 - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool CMICmdCmdStackListVariables::Execute() {
+ CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
+ CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
+ CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
+
+ // 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;
+ }
+ }
+
+ const CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
+ static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
+ pArgPrintValues->GetValue());
+
+ 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 |
+ CMICmnLLDBDebugSessionInfo::eVariableType_InScope;
+ 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() {
+ 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() {
+ return new CMICmdCmdStackListVariables();
+}
+
+
+//++
+// Details: CMICmdCmdStackSelectFrame constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackSelectFrame::CMICmdCmdStackSelectFrame()
+ : m_bFrameInvalid(false), m_constStrArgFrameId("frame_id") {
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "stack-select-frame";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdStackSelectFrame::CreateSelf;
+}
+
+//++
+// Details: CMICmdCmdStackSelectFrame destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackSelectFrame::~CMICmdCmdStackSelectFrame() {}
+
+//++
+// 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 CMICmdCmdStackSelectFrame::ParseArgs() {
+ m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrameId, true, false));
+ 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 CMICmdCmdStackSelectFrame::Execute() {
+ CMICMDBASE_GETOPTION(pArgFrame, Number, m_constStrArgFrameId);
+
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(
+ CMICmnLLDBDebugSessionInfo::Instance());
+ lldb::SBThread sbThread = rSessionInfo.GetProcess().GetSelectedThread();
+
+ const MIuint nFrameId = pArgFrame->GetValue();
+ m_bFrameInvalid = (nFrameId >= sbThread.GetNumFrames());
+ if (m_bFrameInvalid)
+ return MIstatus::success;
+
+ lldb::SBFrame sbFrame = sbThread.SetSelectedFrame(nFrameId);
+ m_bFrameInvalid = !sbFrame.IsValid();
+
+ 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 CMICmdCmdStackSelectFrame::Acknowledge() {
+ if (m_bFrameInvalid) {
+ // MI print "%s^error,msg=\"Command '-stack-select-frame'. Frame ID
+ // invalid\""
+ const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
+ MIRSRC(IDS_CMD_ERR_FRAME_INVALID), m_cmdData.strMiCmd.c_str()));
+ const CMICmnMIValueResult miValueResult("msg", miValueConst);
+ const CMICmnMIResultRecord miRecordResult(
+ m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
+ miValueResult);
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+ }
+
+ const CMICmnMIResultRecord miRecordResult(
+ m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
+ 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 *CMICmdCmdStackSelectFrame::CreateSelf() {
+ return new CMICmdCmdStackSelectFrame();
+}