//++ ------------------------------------------------------------------------------------
// Details:	Form MI partial response by appending more MI value type objects to the 
//			tuple type object past in.
// Type:	Method.
// Args:	vrThread		- (R) LLDB thread object.
//			vwrMIValueTuple	- (W) MI value tuple object.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo( const lldb::SBThread & vrThread, const MIuint vnLevel, CMICmnMIValueTuple & vwrMiValueTuple )
{
	lldb::SBThread & rThread = const_cast< lldb::SBThread & >( vrThread );
	
	lldb::SBFrame frame = rThread.GetFrameAtIndex( vnLevel );
	lldb::addr_t pc = 0;
	CMIUtilString fnName;
	CMIUtilString fileName;
	CMIUtilString path; 
	MIuint nLine = 0;
	if( !GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) )
		return MIstatus::failure;
	
	CMICmnMIValueList miValueList( true );
	const MIuint vMaskVarTypes = 0x1000;
	if( !MIResponseFormVariableInfo( frame, vMaskVarTypes, miValueList ) )
		return MIstatus::failure;

	// MI print "{level=\"0\",addr=\"0x%08llx\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"}"
	const CMIUtilString strLevel( CMIUtilString::Format( "%d", vnLevel ) );
	const CMICmnMIValueConst miValueConst( strLevel );
	const CMICmnMIValueResult miValueResult( "level", miValueConst );
	CMICmnMIValueTuple miValueTuple( miValueResult );
	if( !MIResponseFormFrameInfo( pc, fnName, miValueList.GetString(), fileName, path, nLine, miValueTuple ) )
		return MIstatus::failure;

	vwrMiValueTuple = miValueTuple;

	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 CMICmdCmdThreadInfo::Acknowledge() {
  if (m_bSingleThread) {
    if (m_bThreadInvalid) {
      const CMICmnMIValueConst miValueConst("invalid thread id");
      const CMICmnMIValueResult miValueResult("msg", miValueConst);
      const CMICmnMIResultRecord miRecordResult(
          m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
          miValueResult);
      m_miResultRecord = miRecordResult;
      return MIstatus::success;
    }

    // MI print
    // "%s^done,threads=[{id=\"%d\",target-id=\"%s\",frame={},state=\"%s\"}]
    const CMICmnMIValueList miValueList(m_miValueTupleThread);
    const CMICmnMIValueResult miValueResult("threads", 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
  VecMIValueTuple_t::const_iterator it = m_vecMIValueTuple.begin();
  if (it == m_vecMIValueTuple.end()) {
    const CMICmnMIValueConst miValueConst("[]");
    const CMICmnMIValueResult miValueResult("threads", miValueConst);
    const CMICmnMIResultRecord miRecordResult(
        m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
        miValueResult);
    m_miResultRecord = miRecordResult;
    return MIstatus::success;
  }
  CMICmnMIValueList miValueList(*it);
  ++it;
  while (it != m_vecMIValueTuple.end()) {
    const CMICmnMIValueTuple &rTuple(*it);
    miValueList.Add(rTuple);

    // Next
    ++it;
  }

  CMICmnMIValueResult miValueResult("threads", miValueList);
  if (m_bHasCurrentThread) {
    CMIUtilString strCurrThreadId = "current-thread-id";
    miValueResult.Add(strCurrThreadId, m_miValueCurrThreadId);
  }
  const CMICmnMIResultRecord miRecordResult(
      m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
      miValueResult);
  m_miResultRecord = miRecordResult;

  return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Form MI partial response by appending more MI value type objects to the
//          tuple type object past in.
// Type:    Method.
// Args:    vrThread        - (R) LLDB thread object.
//          vwrMIValueTuple - (W) MI value tuple object.
//          vArgInfo        - (R) Args information in MI response form.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo(const lldb::SBThread &vrThread, const MIuint vnLevel,
                                                    const FrameInfoFormat_e veFrameInfoFormat, CMICmnMIValueTuple &vwrMiValueTuple)
{
    lldb::SBThread &rThread = const_cast<lldb::SBThread &>(vrThread);

    lldb::SBFrame frame = rThread.GetFrameAtIndex(vnLevel);
    lldb::addr_t pc = 0;
    CMIUtilString fnName;
    CMIUtilString fileName;
    CMIUtilString path;
    MIuint nLine = 0;
    if (!GetFrameInfo(frame, pc, fnName, fileName, path, nLine))
        return MIstatus::failure;

    // MI print "{level=\"0\",addr=\"0x%016" PRIx64 "\",func=\"%s\",file=\"%s\",fullname=\"%s\",line=\"%d\"}"
    const CMIUtilString strLevel(CMIUtilString::Format("%d", vnLevel));
    const CMICmnMIValueConst miValueConst(strLevel);
    const CMICmnMIValueResult miValueResult("level", miValueConst);
    vwrMiValueTuple.Add(miValueResult);
    const CMIUtilString strAddr(CMIUtilString::Format("0x%016" PRIx64, pc));
    const CMICmnMIValueConst miValueConst2(strAddr);
    const CMICmnMIValueResult miValueResult2("addr", miValueConst2);
    vwrMiValueTuple.Add(miValueResult2);
    const CMICmnMIValueConst miValueConst3(fnName);
    const CMICmnMIValueResult miValueResult3("func", miValueConst3);
    vwrMiValueTuple.Add(miValueResult3);
    if (veFrameInfoFormat != eFrameInfoFormat_NoArguments)
    {
        CMICmnMIValueList miValueList(true);
        const MIuint maskVarTypes = eVariableType_Arguments;
        if (veFrameInfoFormat == eFrameInfoFormat_AllArgumentsInSimpleForm)
        {
            if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList, 0))
                return MIstatus::failure;
        }
        else
            if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList))
                return MIstatus::failure;

        const CMICmnMIValueResult miValueResult4("args", miValueList);
        vwrMiValueTuple.Add(miValueResult4);
    }
    const CMICmnMIValueConst miValueConst5(fileName);
    const CMICmnMIValueResult miValueResult5("file", miValueConst5);
    vwrMiValueTuple.Add(miValueResult5);
    const CMICmnMIValueConst miValueConst6(path);
    const CMICmnMIValueResult miValueResult6("fullname", miValueConst6);
    vwrMiValueTuple.Add(miValueResult6);
    const CMIUtilString strLine(CMIUtilString::Format("%d", nLine));
    const CMICmnMIValueConst miValueConst7(strLine);
    const CMICmnMIValueResult miValueResult7("line", miValueConst7);
    vwrMiValueTuple.Add(miValueResult7);

    return MIstatus::success;
}
Beispiel #4
0
//++ ------------------------------------------------------------------------------------
// 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;
    if (!rSessionInfo.MIResponseFormVariableInfo(frame, maskVarTypes, eVarInfoFormat, miValueList))
        return MIstatus::failure;

    m_miValueList = miValueList;

    return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details:	Retrieve the specified thread's frame information.
// Type:	Method.
// Args:	vCmdData		- (R) A command's information.
//			vThreadIdx		- (R) Thread index.
//			vwrThreadFrames	- (W) Frame data.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmnLLDBDebugSessionInfo::GetThreadFrames( const SMICmdData & vCmdData, const MIuint vThreadIdx, CMICmnMIValueTuple & vwrThreadFrames ) 
{
	lldb::SBThread thread = m_lldbProcess.GetThreadByIndexID( vThreadIdx );
	const uint32_t nFrames = thread.GetNumFrames();
	if( nFrames == 0 )
	{
		vwrThreadFrames = CMICmnMIValueTuple();
		return MIstatus::success;
	}

	CMICmnMIValueTuple miValueTupleAll;
	for( MIuint nLevel = 0; nLevel < nFrames; nLevel++ )
	{
		lldb::SBFrame frame = thread.GetFrameAtIndex( nLevel );
		lldb::addr_t pc = 0;
		CMIUtilString fnName;
		CMIUtilString fileName;
		CMIUtilString path; 
		MIuint nLine = 0;
		if( !GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) )
			return MIstatus::failure;

		// Function args
		CMICmnMIValueList miValueList( true );
		const MIuint vMaskVarTypes = 0x1000;
		if( !MIResponseFormVariableInfo( frame, vMaskVarTypes, miValueList ) )
			return MIstatus::failure;

		const MIchar * pUnknown = "??";
		if( fnName != pUnknown )
		{
			std::replace( fnName.begin(), fnName.end(), ')', ' ' );
			std::replace( fnName.begin(), fnName.end(), '(', ' ' );
			std::replace( fnName.begin(), fnName.end(), '\'', ' ' );
		}

		const CMIUtilString strLevel( CMIUtilString::Format( "%d", nLevel ) );
		const CMICmnMIValueConst miValueConst( strLevel );
		const CMICmnMIValueResult miValueResult( "level", miValueConst );
		miValueTupleAll.Add( miValueResult );
		
		CMICmnMIValueTuple miValueTuple( miValueResult );
		if( !MIResponseFormFrameInfo( pc, fnName, miValueList.GetString(), fileName, path, nLine, miValueTuple ) )
			return MIstatus::failure;
	}

	vwrThreadFrames = miValueTupleAll;

	return MIstatus::success;
}
Beispiel #6
0
//++ ------------------------------------------------------------------------------------
// 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 CMICmdCmdSupportListFeatures::Acknowledge() {
  // Declare supported features here
  const CMICmnMIValueConst miValueConst1("data-read-memory-bytes");
  const CMICmnMIValueConst miValueConst2("exec-run-start-option");
  // Some features may depend on host and/or target, decide what to add below
  CMICmnMIValueList miValueList(true);
  miValueList.Add(miValueConst1);
  miValueList.Add(miValueConst2);
  const CMICmnMIValueResult miValueResult("features", miValueList);
  const CMICmnMIResultRecord miRecordResult(
      m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
      miValueResult);
  m_miResultRecord = miRecordResult;

  return MIstatus::success;
}
Beispiel #8
0
//++ ------------------------------------------------------------------------------------
// 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;
}
Beispiel #9
0
//++ ------------------------------------------------------------------------------------
// 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:	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 CMICmdCmdListThreadGroups::Acknowledge( void )
{
	if( m_bHaveArgOption )
	{
		if( m_bHaveArgRecurse )
		{
			const CMICmnMIValueConst miValueConst( MIRSRC( IDS_WORD_NOT_IMPLEMENTED_BRKTS ) );
			const CMICmnMIValueResult miValueResult( "msg", miValueConst );
			const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
			m_miResultRecord = miRecordResult;
			
			return MIstatus::success;
		}

		const CMICmnMIValueConst miValueConst1( "i1" );
		const CMICmnMIValueResult miValueResult1( "id", miValueConst1 );
		CMICmnMIValueTuple miTuple( miValueResult1 );

		const CMICmnMIValueConst miValueConst2( "process" );
		const CMICmnMIValueResult miValueResult2( "type", miValueConst2 );
		miTuple.Add( miValueResult2 );

		CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
		const lldb::pid_t pid = rSessionInfo.m_lldbProcess.GetProcessID();
		const CMIUtilString strPid( CMIUtilString::Format( "%lld", pid ) );
		const CMICmnMIValueConst miValueConst3( strPid );
		const CMICmnMIValueResult miValueResult3( "pid", miValueConst3 );
		miTuple.Add( miValueResult3 );

		const CMICmnMIValueConst miValueConst4( MIRSRC( IDS_WORD_NOT_IMPLEMENTED_BRKTS ) );
		const CMICmnMIValueResult miValueResult4( "num_children", miValueConst4 );
		miTuple.Add( miValueResult4 );

		const CMICmnMIValueConst miValueConst5( MIRSRC( IDS_WORD_NOT_IMPLEMENTED_BRKTS ) );
		const CMICmnMIValueResult miValueResult5( "cores", miValueConst5 );
		miTuple.Add( miValueResult5 );

		const CMICmnMIValueList miValueList( miTuple );
		const CMICmnMIValueResult miValueResult6( "groups", miValueList );
		const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 );
		m_miResultRecord = miRecordResult;
		
		return MIstatus::success;
	}
	
	if( !m_bIsI1 )
	{
		const CMICmnMIValueConst miValueConst1( "i1" );
		const CMICmnMIValueResult miValueResult1( "id", miValueConst1 );
		CMICmnMIValueTuple miTuple( miValueResult1 );

		const CMICmnMIValueConst miValueConst2( "process" );
		const CMICmnMIValueResult miValueResult2( "type", miValueConst2 );
		miTuple.Add( miValueResult2 );

		CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
		const lldb::pid_t pid = rSessionInfo.m_lldbProcess.GetProcessID();
		const CMIUtilString strPid( CMIUtilString::Format( "%lld", pid ) );
		const CMICmnMIValueConst miValueConst3( strPid );
		const CMICmnMIValueResult miValueResult3( "pid", miValueConst3 );
		miTuple.Add( miValueResult3 );

		lldb::SBTarget & rTrgt = rSessionInfo.m_lldbTarget;
		const MIchar * pDir = rTrgt.GetExecutable().GetDirectory();
		const MIchar * pFileName = rTrgt.GetExecutable().GetFilename();
		const CMIUtilString strFile( CMIUtilString::Format( "%s/%s", pDir, pFileName ) );
		const CMICmnMIValueConst miValueConst4( strFile );
		const CMICmnMIValueResult miValueResult4( "executable", miValueConst4 );
		miTuple.Add( miValueResult4 );
		
		const CMICmnMIValueList miValueList( miTuple );
		const CMICmnMIValueResult miValueResult5( "groups", miValueList );
		const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult5 );
		m_miResultRecord = miRecordResult;
		return MIstatus::success;
	}
	
	// Build up a list of thread information from tuples
	VecMIValueTuple_t::const_iterator it = m_vecMIValueTuple.begin();
	if( it == m_vecMIValueTuple.end() )
	{
		const CMICmnMIValueConst miValueConst( "[]" );
		const CMICmnMIValueResult miValueResult( "threads", miValueConst );
		const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
		m_miResultRecord = miRecordResult;
		return MIstatus::success;
	}
	CMICmnMIValueList miValueList( *it );
	++it;
	while( it != m_vecMIValueTuple.end() )
	{
		const CMICmnMIValueTuple & rTuple( *it );
		miValueList.Add( rTuple );

		// Next
		++it;
	}

	const CMICmnMIValueResult miValueResult( "threads", miValueList );
	const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
	m_miResultRecord = miRecordResult;

	return MIstatus::success;
}
Beispiel #11
0
//++ ------------------------------------------------------------------------------------
// 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;
}