| //===-- 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 "MICmnConfig.h" |
| #include "MICmdCmdStack.h" |
| #include "MICmnMIResultRecord.h" |
| #include "MICmnMIValueConst.h" |
| #include "MICmnMIOutOfBandRecord.h" |
| #include "MICmnLLDBDebugger.h" |
| #include "MICmnLLDBDebugSessionInfo.h" |
| #include "MICmdArgContext.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 ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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() ); |
| m_nThreadFrames = rSessionInfo.m_lldbProcess.GetThreadByIndexID( nThreadId ).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 ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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::SBThread thread = rSessionInfo.m_lldbProcess.GetThreadByIndexID( nThreadId ); |
| 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 ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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; |
| if( nThreadId == UINT64_MAX ) |
| thread = rProcess.GetSelectedThread(); |
| else |
| thread = rProcess.GetThreadByIndexID( nThreadId ); |
| 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 = thread.GetFrameAtIndex( 0 ); |
| CMICmnMIValueList miValueList( true ); |
| const MIuint vMaskVarTypes = 0x1000; |
| if( !rSessionInfo.MIResponseFormVariableInfo( frame, vMaskVarTypes, 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 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]}]" |
| const CMICmnMIValueConst miValueConst( "0" ); |
| const CMICmnMIValueResult miValueResult( "level", miValueConst ); |
| CMICmnMIValueTuple miValueTuple( miValueResult ); |
| const CMICmnMIValueResult miValueResult2( "args", m_miValueList ); |
| miValueTuple.Add( miValueResult2 ); |
| const CMICmnMIValueResult miValueResult3( "frame", miValueTuple ); |
| const CMICmnMIValueList miValueList( miValueResult3 ); |
| const CMICmnMIValueResult miValueResult4( "stack-args", 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, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgPrintValues, true, false ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // 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( 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; |
| if( nThreadId == UINT64_MAX ) |
| thread = rProcess.GetSelectedThread(); |
| else |
| thread = rProcess.GetThreadByIndexID( nThreadId ); |
| 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 = thread.GetFrameAtIndex( 0 ); |
| CMICmnMIValueList miValueList( true ); |
| const MIuint vMaskVarTypes = 0x0100; |
| if( !rSessionInfo.MIResponseFormVariableInfo( frame, vMaskVarTypes, 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(); |
| } |
| |