diff options
Diffstat (limited to 'tools/lldb-mi/MICmdCmdStack.cpp')
-rw-r--r-- | tools/lldb-mi/MICmdCmdStack.cpp | 634 |
1 files changed, 634 insertions, 0 deletions
diff --git a/tools/lldb-mi/MICmdCmdStack.cpp b/tools/lldb-mi/MICmdCmdStack.cpp new file mode 100644 index 000000000000..5f5b355758c4 --- /dev/null +++ b/tools/lldb-mi/MICmdCmdStack.cpp @@ -0,0 +1,634 @@ +//===-- MICmdCmdStack.cpp ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +//++ +// File: MICmdCmdStack.cpp +// +// Overview: CMICmdCmdStackInfoDepth implementation. +// CMICmdCmdStackListFrames implementation. +// CMICmdCmdStackListArguments implementation. +// CMICmdCmdStackListLocals implementation. +// +// Environment: Compilers: Visual C++ 12. +// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 +// Libraries: See MIReadmetxt. +// +// Copyright: None. +//-- + +// Third Party Headers: +#include <lldb/API/SBThread.h> + +// In-house headers: +#include "MICmdCmdStack.h" +#include "MICmnMIResultRecord.h" +#include "MICmnMIValueConst.h" +#include "MICmnMIOutOfBandRecord.h" +#include "MICmnLLDBDebugger.h" +#include "MICmnLLDBDebugSessionInfo.h" +#include "MICmdArgValNumber.h" +#include "MICmdArgValString.h" +#include "MICmdArgValThreadGrp.h" +#include "MICmdArgValOptionLong.h" +#include "MICmdArgValOptionShort.h" +#include "MICmdArgValListOfN.h" + +//++ ------------------------------------------------------------------------------------ +// Details: CMICmdCmdStackInfoDepth constructor. +// Type: Method. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMICmdCmdStackInfoDepth::CMICmdCmdStackInfoDepth( void ) +: m_nThreadFrames( 0 ) +, m_constStrArgThread( "thread" ) +, 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( 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 CMICmdCmdStackInfoDepth::ParseArgs( void ) +{ + bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); + bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgMaxDepth, false, false ) ) ); + 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 CMICmdCmdStackInfoDepth::Execute( void ) +{ + 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->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 & rProcess = rSessionInfo.m_lldbProcess; + lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID( nThreadId ) : rProcess.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( void ) +{ + 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( void ) +{ + return new CMICmdCmdStackInfoDepth(); +} + +//--------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------- + +//++ ------------------------------------------------------------------------------------ +// Details: CMICmdCmdStackListFrames constructor. +// Type: Method. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMICmdCmdStackListFrames::CMICmdCmdStackListFrames( void ) +: m_nThreadFrames( 0 ) +, m_constStrArgThread( "thread" ) +, 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( void ) +{ + 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( void ) +{ + bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); + bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgFrameLow, false, true ) ) ); + bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgFrameHigh, 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 CMICmdCmdStackListFrames::Execute( void ) +{ + 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->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() : UINT64_MAX; + const MIuint nFrameLow = pArgFrameLow->GetFound() ? pArgFrameLow->GetValue() : 0; + + CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); + lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess; + lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID( nThreadId ) : rProcess.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, 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( void ) +{ + 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( void ) +{ + return new CMICmdCmdStackListFrames(); +} + +//--------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------- + +//++ ------------------------------------------------------------------------------------ +// Details: CMICmdCmdStackListArguments constructor. +// Type: Method. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMICmdCmdStackListArguments::CMICmdCmdStackListArguments( void ) +: m_bThreadInvalid( false ) +, m_miValueList( true ) +, m_constStrArgThread( "thread" ) +, m_constStrArgPrintValues( "print-values" ) +{ + // 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( 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 CMICmdCmdStackListArguments::ParseArgs( void ) +{ + bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); + bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgPrintValues, true, false ) ) ); + 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 CMICmdCmdStackListArguments::Execute( void ) +{ + CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread ); + CMICMDBASE_GETOPTION( pArgPrintValues, Number, 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; + } + } + + CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); + lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess; + lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID( nThreadId ) : rProcess.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(); + for( MIuint i = 0; i < nFrames; i++ ) + { + lldb::SBFrame frame = thread.GetFrameAtIndex( i ); + CMICmnMIValueList miValueList( true ); + const MIuint maskVarTypes = 0x1000; + if( !rSessionInfo.MIResponseFormVariableInfo3( frame, maskVarTypes, 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( void ) +{ + 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( void ) +{ + return new CMICmdCmdStackListArguments(); +} + +//--------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------- + +//++ ------------------------------------------------------------------------------------ +// Details: CMICmdCmdStackListLocals constructor. +// Type: Method. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMICmdCmdStackListLocals::CMICmdCmdStackListLocals( void ) +: m_bThreadInvalid( false ) +, m_miValueList( true ) +, m_constStrArgThread( "thread" ) +, m_constStrArgFrame( "frame" ) +, 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( 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 CMICmdCmdStackListLocals::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, true, false ) ) ); + 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 CMICmdCmdStackListLocals::Execute( void ) +{ + CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread ); + CMICMDBASE_GETOPTION( pArgFrame, OptionLong, m_constStrArgFrame ); + + // 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 & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); + lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess; + lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID( nThreadId ) : rProcess.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(); MIunused( nFrames ); + lldb::SBFrame frame = (nFrame != UINT64_MAX) ? thread.GetFrameAtIndex( nFrame ) : thread.GetSelectedFrame(); + CMICmnMIValueList miValueList( true ); + const MIuint maskVarTypes = 0x0110; + if( !rSessionInfo.MIResponseFormVariableInfo( frame, maskVarTypes, 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( void ) +{ + 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( void ) +{ + return new CMICmdCmdStackListLocals(); +} + |