forked from OSchip/llvm-project
657 lines
24 KiB
C++
657 lines
24 KiB
C++
//===-- 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 commmand
|
|
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.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
|
|
m_miResultRecord = miRecordResult;
|
|
|
|
return MIstatus::success;
|
|
}
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
// Details: Required by the CMICmdFactory when registering *this commmand. 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 commmand
|
|
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.nMiCmdNumber, 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.nMiCmdNumber, 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.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
|
|
m_miResultRecord = miRecordResult;
|
|
|
|
return MIstatus::success;
|
|
}
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
// Details: Required by the CMICmdFactory when registering *this commmand. 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 commmand
|
|
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.nMiCmdNumber, 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.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult4 );
|
|
m_miResultRecord = miRecordResult;
|
|
|
|
return MIstatus::success;
|
|
}
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
// Details: Required by the CMICmdFactory when registering *this commmand. 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 commmand
|
|
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.nMiCmdNumber, 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.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
|
|
m_miResultRecord = miRecordResult;
|
|
|
|
return MIstatus::success;
|
|
}
|
|
|
|
//++ ------------------------------------------------------------------------------------
|
|
// Details: Required by the CMICmdFactory when registering *this commmand. 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();
|
|
}
|
|
|