예제 #1
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 CMICmdCmdBreakCondition::Execute( void )
{
	CMICMDBASE_GETOPTION( pArgNumber, Number, m_constStrArgNamedNumber );
	CMICMDBASE_GETOPTION( pArgExpr, String, m_constStrArgNamedExpr );					

	m_nBrkPtId = pArgNumber->GetValue();
	m_strBrkPtExpr = pArgExpr->GetValue();
	m_strBrkPtExpr += GetRestOfExpressionNotSurroundedInQuotes();

	CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
	lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( m_nBrkPtId ) );
	if( brkPt.IsValid() )
	{
		brkPt.SetCondition( m_strBrkPtExpr.c_str() );

		CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
		if( !rSessionInfo.RecordBrkPtInfoGet( m_nBrkPtId, sBrkPtInfo ) )
		{
			SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_nBrkPtId ) );
			return MIstatus::failure;
		}
		sBrkPtInfo.m_strCondition = m_strBrkPtExpr;
		rSessionInfo.RecordBrkPtInfo( m_nBrkPtId, sBrkPtInfo );
	}
	else
	{
		const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
		SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkPtId.c_str() ) );
		return MIstatus::failure;
	}

	return MIstatus::success;
}
예제 #2
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 CMICmdCmdBreakAfter::Execute( void )
{
	CMICMDBASE_GETOPTION( pArgNumber, Number, m_constStrArgNamedNumber );
	CMICMDBASE_GETOPTION( pArgCount, Number, m_constStrArgNamedCount );

	m_nBrkPtId = pArgNumber->GetValue();
	m_nBrkPtCount = pArgCount->GetValue();

	CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
	lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( m_nBrkPtId ) );
	if( brkPt.IsValid() )
	{
		brkPt.SetIgnoreCount( m_nBrkPtCount );

		CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
		if( !rSessionInfo.RecordBrkPtInfoGet( m_nBrkPtId, sBrkPtInfo ) )
		{
			SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_nBrkPtId ) );
			return MIstatus::failure;
		}
		sBrkPtInfo.m_nIgnore = m_nBrkPtCount;
		rSessionInfo.RecordBrkPtInfo( m_nBrkPtId, sBrkPtInfo );
	}
	else
	{
		const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
		SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkPtId.c_str() ) );
		return MIstatus::failure;
	}

	return MIstatus::success;
}
예제 #3
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;
}
예제 #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 CMICmdCmdInterpreterExec::Execute( void )
{
	CMICMDBASE_GETOPTION( pArgInterpreter, String, m_constStrArgNamedInterpreter );
	CMICMDBASE_GETOPTION( pArgCommand, String, m_constStrArgNamedCommand );
	const CMIUtilString & rStrInterpreter( pArgInterpreter->GetValue() );
	const CMIUtilString & rStrCommand( pArgCommand->GetValue() );
	const CMIUtilString strCmd( CMIUtilString::Format( "%s %s", rStrInterpreter.c_str(), rStrCommand.c_str() ) );
	CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
	const lldb::ReturnStatus rtn = rSessionInfo.m_rLldbDebugger.GetCommandInterpreter().HandleCommand( strCmd.c_str(), m_lldbResult, true ); MIunused( rtn );
	
	return MIstatus::success;
}
예제 #5
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.
//			Synopis: -list-thread-groups [ --available ] [ --recurse 1 ] [ group ... ]
//			This command does not follow the MI documentation exactly. Has an extra
//			argument "i1" to handle. 
//			Ref: http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Miscellaneous-Commands.html#GDB_002fMI-Miscellaneous-Commands
// Type:	Overridden.
// Args:	None.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmdCmdListThreadGroups::Execute( void )
{
	if( m_setCmdArgs.IsArgContextEmpty() )
		// No options so "top level thread groups"
		return MIstatus::success;

	CMICMDBASE_GETOPTION( pArgAvailable, OptionLong, m_constStrArgNamedAvailable );
	CMICMDBASE_GETOPTION( pArgRecurse, OptionLong, m_constStrArgNamedRecurse );
	CMICMDBASE_GETOPTION( pArgThreadGroup, ThreadGrp, m_constStrArgNamedThreadGroup );
	
	// Got some options so "threads"
	if( pArgAvailable->GetFound() )
	{
		if( pArgRecurse->GetFound() )
		{
			m_bHaveArgRecurse = true;
			return MIstatus::success;
		}

		m_bHaveArgOption = true;
		return MIstatus::success;
	}
	// "i1" as first argument (pos 0 of possible arg)
	if( !pArgThreadGroup->GetFound() )
		return MIstatus::success;
	m_bIsI1 = true;

	CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
	lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
	
	// Note do not check for rProcess is IsValid(), continue
		
	m_vecMIValueTuple.clear();
	const MIuint nThreads = rProcess.GetNumThreads();
	for( MIuint i = 0; i < nThreads; i++ )
	{
		//	GetThreadAtIndex() uses a base 0 index
		//	GetThreadByIndexID() uses a base 1 index
		lldb::SBThread thread = rProcess.GetThreadAtIndex( i );

		if( thread.IsValid() )
		{
			CMICmnMIValueTuple miTuple;
			if( !rSessionInfo.MIResponseFormThreadInfo( m_cmdData, thread, miTuple ) )
				return MIstatus::failure;

			m_vecMIValueTuple.push_back( miTuple );
		}
	}

	return MIstatus::success;
}
예제 #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.
//          Synopsis: -target-attach file
//          Ref: http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmdCmdTargetAttach::Execute()
{
    CMICMDBASE_GETOPTION(pArgPid, Number, m_constStrArgPid);
    CMICMDBASE_GETOPTION(pArgFile, OptionShort, m_constStrArgNamedFile);
    CMICMDBASE_GETOPTION(pArgWaitFor, OptionLong, m_constStrArgWaitFor);
    
    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
    
    // If the current target is invalid, create one
    lldb::SBTarget target = rSessionInfo.GetTarget();
    if (!target.IsValid())
    {
        target = rSessionInfo.GetDebugger().CreateTarget(NULL);
        if (!target.IsValid())
        {
            SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT), m_cmdData.strMiCmd.c_str()));
            return MIstatus::failure;
        }
    }

    lldb::SBError error;
    lldb::SBListener listener;
    if (pArgPid->GetFound() && pArgPid->GetValid())
    {
        lldb::pid_t pid;
        pid = pArgPid->GetValue();
        target.AttachToProcessWithID(listener, pid, error);
    }
    else if (pArgFile->GetFound() && pArgFile->GetValid())
    {
        bool bWaitFor = (pArgWaitFor->GetFound());
        CMIUtilString file;
        pArgFile->GetExpectedOption<CMICmdArgValString>(file);
        target.AttachToProcessWithName(listener, file.c_str(), bWaitFor, error);
    }
    else
    {
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_ATTACH_BAD_ARGS), m_cmdData.strMiCmd.c_str()));
        return MIstatus::failure;
    }

    lldb::SBStream errMsg;
    if (error.Fail())
    {
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_ATTACH_FAILED), m_cmdData.strMiCmd.c_str(), errMsg.GetData()));
        return MIstatus::failure;
    }
    
    return MIstatus::success;
}
예제 #7
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;
}
예제 #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
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->GetFound() && !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
    {
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str()));
        return MIstatus::failure;
    }

    // Frame low and high options are not mandatory
    MIuint nFrameHigh = pArgFrameHigh->GetFound() ? pArgFrameHigh->GetValue() : UINT32_MAX;
    const MIuint nFrameLow = pArgFrameLow->GetFound() ? pArgFrameLow->GetValue() : 0;

    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
    lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
    lldb::SBThread thread = (nThreadId != UINT64_MAX) ? sbProcess.GetThreadByIndexID(nThreadId) : sbProcess.GetSelectedThread();
    MIuint nThreadFrames = thread.GetNumFrames();

    // Adjust nThreadFrames for the nFrameHigh argument as we use nFrameHigh+1 in the min calc as the arg
    // is not an index, but a frame id value.
    if (nFrameHigh < UINT32_MAX)
    {
        nFrameHigh++;
        nThreadFrames = (nFrameHigh < nThreadFrames) ? nFrameHigh : nThreadFrames;
    }

    m_nThreadFrames = nThreadFrames;
    if (nThreadFrames == 0)
        return MIstatus::success;

    m_vecMIValueResult.clear();
    for (MIuint nLevel = nFrameLow; nLevel < nThreadFrames; nLevel++)
    {
        CMICmnMIValueTuple miValueTuple;
        if (!rSessionInfo.MIResponseFormFrameInfo(thread, nLevel, miValueTuple))
            return MIstatus::failure;

        const CMICmnMIValueResult miValueResult8("frame", miValueTuple);
        m_vecMIValueResult.push_back(miValueResult8);
    }

    return MIstatus::success;
}
예제 #9
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 CMICmdCmdInterpreterExec::Execute( void )
{
	CMICMDBASE_GETOPTION( pArgInterpreter, String, m_constStrArgNamedInterpreter );
	CMICMDBASE_GETOPTION( pArgCommand, String, m_constStrArgNamedCommand );

	// Handle the interpreter parameter by do nothing on purpose (set to 'handled' in 
	// the arg definition above) 
	const CMIUtilString & rStrInterpreter( pArgInterpreter->GetValue() ); MIunused( rStrInterpreter );

	const CMIUtilString & rStrCommand( pArgCommand->GetValue() );
	CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
	const lldb::ReturnStatus rtn = rSessionInfo.m_rLldbDebugger.GetCommandInterpreter().HandleCommand( rStrCommand.c_str(), m_lldbResult, true ); MIunused( rtn );
	
	return MIstatus::success;
}
예제 #10
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 CMICmdCmdBreakDelete::Execute() {
  CMICMDBASE_GETOPTION(pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt);

  // ATM we only handle one break point ID
  MIuint64 nBrk = UINT64_MAX;
  if (!pArgBrkPt->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nBrk)) {
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
                                   m_cmdData.strMiCmd.c_str(),
                                   m_constStrArgNamedBrkPt.c_str()));
    return MIstatus::failure;
  }

  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  const bool bBrkPt = rSessionInfo.GetTarget().BreakpointDelete(
      static_cast<lldb::break_id_t>(nBrk));
  if (!bBrkPt) {
    const CMIUtilString strBrkNum(CMIUtilString::Format("%d", nBrk));
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID),
                                   m_cmdData.strMiCmd.c_str(),
                                   strBrkNum.c_str()));
    return MIstatus::failure;
  }

  return MIstatus::success;
}
예제 #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 - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool
CMICmdCmdExecArguments::Execute()
{
    CMICMDBASE_GETOPTION(pArgArguments, ListOfN, m_constStrArgArguments);

    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
    lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
    if (!sbTarget.IsValid())
    {
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT), m_cmdData.strMiCmd.c_str()));
        return MIstatus::failure;
    }

    lldb::SBLaunchInfo sbLaunchInfo = sbTarget.GetLaunchInfo();
    sbLaunchInfo.SetArguments(NULL, false);

    CMIUtilString strArg;
    size_t nArgIndex = 0;
    while (pArgArguments->GetExpectedOption<CMICmdArgValString, CMIUtilString>(strArg, nArgIndex))
    {
        const char *argv[2] = { strArg.c_str(), NULL };
        sbLaunchInfo.SetArguments(argv, true);
        ++nArgIndex;
    }

    sbTarget.SetLaunchInfo(sbLaunchInfo);

    return MIstatus::success;
}
예제 #12
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 CMICmdCmdEnvironmentCd::Execute() {
  CMICMDBASE_GETOPTION(pArgPathDir, File, m_constStrArgNamePathDir);
  const CMIUtilString &strWkDir(pArgPathDir->GetValue());
  CMICmnLLDBDebugger &rDbg(CMICmnLLDBDebugger::Instance());
  lldb::SBDebugger &rLldbDbg = rDbg.GetTheDebugger();
  bool bOk = rLldbDbg.SetCurrentPlatformSDKRoot(strWkDir.c_str());
  if (bOk) {
    const CMIUtilString &rStrKeyWkDir(
        m_rLLDBDebugSessionInfo.m_constStrSharedDataKeyWkDir);
    if (!m_rLLDBDebugSessionInfo.SharedDataAdd<CMIUtilString>(rStrKeyWkDir,
                                                              strWkDir)) {
      SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD),
                                     m_cmdData.strMiCmd.c_str(),
                                     rStrKeyWkDir.c_str()));
      bOk = MIstatus::failure;
    }
  } else
    SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FNFAILED),
                                   m_cmdData.strMiCmd.c_str(),
                                   "SetCurrentPlatformSDKRoot()"));

  lldb::SBTarget sbTarget = m_rLLDBDebugSessionInfo.GetTarget();
  if (sbTarget.IsValid()) {
    lldb::SBLaunchInfo sbLaunchInfo = sbTarget.GetLaunchInfo();
    sbLaunchInfo.SetWorkingDirectory(strWkDir.c_str());
    sbTarget.SetLaunchInfo(sbLaunchInfo);
  }

  return bOk;
}
예제 #13
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
CMICmdCmdExecRun::Execute()
{
    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
    lldb::SBError error;
    lldb::SBStream errMsg;
    lldb::SBLaunchInfo launchInfo = rSessionInfo.GetTarget().GetLaunchInfo();
    launchInfo.SetListener(rSessionInfo.GetListener());

    // Run to first instruction or main() requested?
    CMICMDBASE_GETOPTION(pArgStart, OptionLong, m_constStrArgStart);
    if (pArgStart->GetFound())
    {
        launchInfo.SetLaunchFlags(launchInfo.GetLaunchFlags() | lldb::eLaunchFlagStopAtEntry);
    }

    lldb::SBProcess process = rSessionInfo.GetTarget().Launch(launchInfo, error);
    if ((!process.IsValid()) || (error.Fail()))
    {
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS), m_cmdData.strMiCmd.c_str(), errMsg.GetData()));
        return MIstatus::failure;
    }

    if (!CMIDriver::Instance().SetDriverStateRunningDebugging())
    {
        const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription());
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_SET_NEW_DRIVER_STATE), m_cmdData.strMiCmd.c_str(), rErrMsg.c_str()));
        return MIstatus::failure;
    }
    return MIstatus::success;
}
예제 #14
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 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;
}
예제 #15
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;
}
예제 #16
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 CMICmdCmdThreadInfo::Execute() {
  CMICMDBASE_GETOPTION(pArgThreadId, Number, m_constStrArgNamedThreadId);
  MIuint nThreadId = 0;
  if (pArgThreadId->GetFound() && pArgThreadId->GetValid()) {
    m_bSingleThread = true;
    nThreadId = static_cast<MIuint>(pArgThreadId->GetValue());
  }

  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
  lldb::SBThread thread = sbProcess.GetSelectedThread();

  if (m_bSingleThread) {
    thread = sbProcess.GetThreadByIndexID(nThreadId);
    m_bThreadInvalid = !thread.IsValid();
    if (m_bThreadInvalid)
      return MIstatus::success;

    CMICmnMIValueTuple miTuple;
    if (!rSessionInfo.MIResponseFormThreadInfo(
            m_cmdData, thread,
            CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_AllFrames, miTuple))
      return MIstatus::failure;

    m_miValueTupleThread = miTuple;

    return MIstatus::success;
  }

  // Multiple threads
  m_vecMIValueTuple.clear();
  const MIuint nThreads = sbProcess.GetNumThreads();
  for (MIuint i = 0; i < nThreads; i++) {
    lldb::SBThread thread = sbProcess.GetThreadAtIndex(i);
    if (thread.IsValid()) {
      CMICmnMIValueTuple miTuple;
      if (!rSessionInfo.MIResponseFormThreadInfo(
              m_cmdData, thread,
              CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_AllFrames, miTuple))
        return MIstatus::failure;

      m_vecMIValueTuple.push_back(miTuple);
    }
  }

  // -thread-info with multiple threads ends with the current thread id if any
  if (thread.IsValid()) {
    const CMIUtilString strId(CMIUtilString::Format("%d", thread.GetIndexID()));
    CMICmnMIValueConst miValueCurrThreadId(strId);
    m_miValueCurrThreadId = miValueCurrThreadId;
    m_bHasCurrentThread = true;
  }

  return MIstatus::success;
}
예제 #17
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 CMICmdCmdSupportInfoMiCmdQuery::Execute( void )
{
	CMICMDBASE_GETOPTION( pArgNamedCmdName, String, m_constStrArgCmdName );
	const CMIUtilString & rCmdToQuery( pArgNamedCmdName->GetValue() );
	const MIuint nLen = rCmdToQuery.length();
	const CMICmdFactory & rCmdFactory = CMICmdFactory::Instance();
	if( (nLen > 1) && (rCmdToQuery[ 0 ] == '-') )
		m_bCmdFound = rCmdFactory.CmdExist( rCmdToQuery.substr( 1, nLen - 1 ).c_str() );
	else
		m_bCmdFound = rCmdFactory.CmdExist( rCmdToQuery );
	
	return MIstatus::success;
}
예제 #18
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
CMICmdCmdThreadInfo::Execute(void)
{
    CMICMDBASE_GETOPTION(pArgThreadId, Number, m_constStrArgNamedThreadId);
    MIuint nThreadId = 0;
    if (pArgThreadId->GetFound() && pArgThreadId->GetValid())
    {
        m_bSingleThread = true;
        nThreadId = static_cast<MIuint>(pArgThreadId->GetValue());
    }

    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
    lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
    lldb::SBThread thread = sbProcess.GetSelectedThread();

    if (m_bSingleThread)
    {
        thread = sbProcess.GetThreadByIndexID(nThreadId);
        m_bThreadInvalid = !thread.IsValid();
        if (m_bThreadInvalid)
            return MIstatus::success;

        CMICmnMIValueTuple miTuple;
        if (!rSessionInfo.MIResponseFormThreadInfo3(m_cmdData, thread, miTuple))
            return MIstatus::failure;

        m_miValueTupleThread = miTuple;

        return MIstatus::success;
    }

    // Multiple threads
    m_vecMIValueTuple.clear();
    const MIuint nThreads = sbProcess.GetNumThreads();
    for (MIuint i = 0; i < nThreads; i++)
    {
        lldb::SBThread thread = sbProcess.GetThreadAtIndex(i);
        if (thread.IsValid())
        {
            CMICmnMIValueTuple miTuple;
            if (!rSessionInfo.MIResponseFormThreadInfo3(m_cmdData, thread, miTuple))
                return MIstatus::failure;

            m_vecMIValueTuple.push_back(miTuple);
        }
    }

    return MIstatus::success;
}
예제 #19
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 - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool
CMICmdCmdStackSelectFrame::Execute(void)
{
    CMICMDBASE_GETOPTION(pArgFrame, Number, m_constStrArgFrame);

    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
    lldb::SBThread sbThread = rSessionInfo.GetProcess().GetSelectedThread();

    const MIuint nFrameId = pArgFrame->GetValue();
    m_bFrameInvalid = (nFrameId >= sbThread.GetNumFrames());
    if (m_bFrameInvalid)
        return MIstatus::success;

    lldb::SBFrame sbFrame = sbThread.SetSelectedFrame(nFrameId);
    m_bFrameInvalid = !sbFrame.IsValid();

    return MIstatus::success;
}
예제 #20
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
CMICmdCmdGdbInfo::Execute(void)
{
    CMICMDBASE_GETOPTION(pArgPrint, String, m_constStrArgNamedPrint);
    const CMIUtilString &rPrintRequest(pArgPrint->GetValue());

    FnPrintPtr pPrintRequestFn = nullptr;
    if (!GetPrintFn(rPrintRequest, pPrintRequestFn))
    {
        m_strPrintFnName = rPrintRequest;
        m_bPrintFnRecognised = false;
        return MIstatus::success;
    }

    m_bPrintFnSuccessful = (this->*(pPrintRequestFn))();

    return MIstatus::success;
}
예제 #21
0
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command is executed in this function.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool
CMICmdCmdGdbShow::Execute()
{
    CMICMDBASE_GETOPTION(pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption);
    const CMICmdArgValListBase::VecArgObjPtr_t &rVecWords(pArgGdbOption->GetExpectedOptions());

    // Get the gdb-show option to carry out. This option will be used as an action
    // which should be done. Further arguments will be used as parameters for it.
    CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecWords.begin();
    const CMICmdArgValString *pOption = static_cast<const CMICmdArgValString *>(*it);
    const CMIUtilString strOption(pOption->GetValue());
    ++it;

    // Retrieve the parameter(s) for the option
    CMIUtilString::VecString_t vecWords;
    while (it != rVecWords.end())
    {
        const CMICmdArgValString *pWord = static_cast<const CMICmdArgValString *>(*it);
        vecWords.push_back(pWord->GetValue());

        // Next
        ++it;
    }

    FnGdbOptionPtr pPrintRequestFn = nullptr;
    if (!GetOptionFn(strOption, pPrintRequestFn))
    {
        // For unimplemented option handlers, fallback to a generic handler
        // ToDo: Remove this when ALL options have been implemented
        if (!GetOptionFn("fallback", pPrintRequestFn))
        {
            m_bGdbOptionRecognised = false;
            m_strGdbOptionName = "fallback"; // This would be the strOption name
            return MIstatus::success;
        }
    }

    m_bGdbOptionFnSuccessful = (this->*(pPrintRequestFn))(vecWords);
    if (!m_bGdbOptionFnSuccessful && !m_bGbbOptionFnHasError)
        return MIstatus::failure;

    return MIstatus::success;
}
예제 #22
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
CMICmdCmdExecFinish::Execute()
{
    CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);

    // Retrieve the --thread option's thread ID (only 1)
    MIuint64 nThreadId = UINT64_MAX;
    if (pArgThread->GetFound() && !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
    {
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str()));
        return MIstatus::failure;
    }

    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
    lldb::SBDebugger &rDebugger = rSessionInfo.GetDebugger();
    CMIUtilString strCmd("thread step-out");
    if (nThreadId != UINT64_MAX)
        strCmd += CMIUtilString::Format(" %llu", nThreadId);
    rDebugger.GetCommandInterpreter().HandleCommand(strCmd.c_str(), m_lldbResult, false);

    return MIstatus::success;
}
예제 #23
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 CMICmdCmdBreakEnable::Execute( void )
{
	CMICMDBASE_GETOPTION( pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt );

	// ATM we only handle one break point ID
	MIuint64 nBrk = UINT64_MAX;
	if( !pArgBrkPt->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nBrk ) )
	{
		SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str() ) );
		return MIstatus::failure;
	}

	CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
	lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( nBrk ) );
	if( brkPt.IsValid() )
	{
		m_bBrkPtEnabledOk = true;
		brkPt.SetEnabled( false );
		m_nBrkPtId = nBrk;
	}

	return MIstatus::success;
}
예제 #24
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
CMICmdCmdBreakInsert::Execute()
{
    CMICMDBASE_GETOPTION(pArgTempBrkPt, OptionShort, m_constStrArgNamedTempBrkPt);
    CMICMDBASE_GETOPTION(pArgThreadGroup, OptionLong, m_constStrArgNamedThreadGroup);
    CMICMDBASE_GETOPTION(pArgLocation, String, m_constStrArgNamedLocation);
    CMICMDBASE_GETOPTION(pArgIgnoreCnt, OptionShort, m_constStrArgNamedInoreCnt);
    CMICMDBASE_GETOPTION(pArgPendingBrkPt, OptionShort, m_constStrArgNamedPendinfBrkPt);
    CMICMDBASE_GETOPTION(pArgDisableBrkPt, OptionShort, m_constStrArgNamedDisableBrkPt);
    CMICMDBASE_GETOPTION(pArgConditionalBrkPt, OptionShort, m_constStrArgNamedConditionalBrkPt);
    CMICMDBASE_GETOPTION(pArgRestrictBrkPtToThreadId, OptionShort, m_constStrArgNamedRestrictBrkPtToThreadId);

    m_bBrkPtEnabled = !pArgDisableBrkPt->GetFound();
    m_bBrkPtIsTemp = pArgTempBrkPt->GetFound();
    m_bHaveArgOptionThreadGrp = pArgThreadGroup->GetFound();
    if (m_bHaveArgOptionThreadGrp)
    {
        MIuint nThreadGrp = 0;
        pArgThreadGroup->GetExpectedOption<CMICmdArgValThreadGrp, MIuint>(nThreadGrp);
        m_strArgOptionThreadGrp = CMIUtilString::Format("i%d", nThreadGrp);
    }
    m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
    if (pArgLocation->GetFound())
        m_brkName = pArgLocation->GetValue();
    else if (m_bBrkPtIsPending)
    {
        pArgPendingBrkPt->GetExpectedOption<CMICmdArgValString, CMIUtilString>(m_brkName);
    }
    if (pArgIgnoreCnt->GetFound())
    {
        pArgIgnoreCnt->GetExpectedOption<CMICmdArgValNumber, MIuint>(m_nBrkPtIgnoreCount);
    }
    m_bBrkPtCondition = pArgConditionalBrkPt->GetFound();
    if (m_bBrkPtCondition)
    {
        pArgConditionalBrkPt->GetExpectedOption<CMICmdArgValString, CMIUtilString>(m_brkPtCondition);
    }
    m_bBrkPtThreadId = pArgRestrictBrkPtToThreadId->GetFound();
    if (m_bBrkPtCondition)
    {
        pArgRestrictBrkPtToThreadId->GetExpectedOption<CMICmdArgValNumber, MIuint>(m_nBrkPtThreadId);
    }

    // Determine if break on a file line or at a function
    BreakPoint_e eBrkPtType = eBreakPoint_NotDefineYet;
    CMIUtilString fileName;
    MIuint nFileLine = 0;
    CMIUtilString strFileFn;
    CMIUtilString rStrLineOrFn;
    // Is the string in the form 'file:func' or 'file:line'?
    // If so, find the position of the ':' separator.
    const size_t nPosColon = findFileSeparatorPos(m_brkName);
    if (nPosColon != std::string::npos)
    {
        // Extract file name and line number from it
        fileName = m_brkName.substr(0, nPosColon);
        rStrLineOrFn = m_brkName.substr(nPosColon + 1, m_brkName.size() - nPosColon - 1);

        if (rStrLineOrFn.empty())
            eBrkPtType = eBreakPoint_ByName;
        else
        {
            MIint64 nValue = 0;
            if (rStrLineOrFn.ExtractNumber(nValue))
            {
                nFileLine = static_cast<MIuint>(nValue);
                eBrkPtType = eBreakPoint_ByFileLine;
            }
            else
            {
                strFileFn = rStrLineOrFn;
                eBrkPtType = eBreakPoint_ByFileFn;
            }
        }
    }

    // Determine if break defined as an address
    lldb::addr_t nAddress = 0;
    if (eBrkPtType == eBreakPoint_NotDefineYet)
    {
        MIint64 nValue = 0;
        if (m_brkName.ExtractNumber(nValue))
        {
            nAddress = static_cast<lldb::addr_t>(nValue);
            eBrkPtType = eBreakPoint_ByAddress;
        }
    }

    // Break defined as an function
    if (eBrkPtType == eBreakPoint_NotDefineYet)
    {
        eBrkPtType = eBreakPoint_ByName;
    }

    // Ask LLDB to create a breakpoint
    bool bOk = MIstatus::success;
    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
    lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
    switch (eBrkPtType)
    {
        case eBreakPoint_ByAddress:
            m_brkPt = sbTarget.BreakpointCreateByAddress(nAddress);
            break;
        case eBreakPoint_ByFileFn:
        {
            lldb::SBFileSpecList module;    // search in all modules
            lldb::SBFileSpecList compUnit;
            compUnit.Append (lldb::SBFileSpec(fileName.c_str()));
            m_brkPt = sbTarget.BreakpointCreateByName(strFileFn.c_str(), module, compUnit);
            break;
        }
        case eBreakPoint_ByFileLine:
            m_brkPt = sbTarget.BreakpointCreateByLocation(fileName.c_str(), nFileLine);
            break;
        case eBreakPoint_ByName:
            m_brkPt = sbTarget.BreakpointCreateByName(m_brkName.c_str(), nullptr);
            break;
        case eBreakPoint_count:
        case eBreakPoint_NotDefineYet:
        case eBreakPoint_Invalid:
            bOk = MIstatus::failure;
            break;
    }

    if (bOk)
    {
        if (!m_bBrkPtIsPending && (m_brkPt.GetNumLocations() == 0))
        {
            sbTarget.BreakpointDelete(m_brkPt.GetID());
            SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_LOCATION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_brkName.c_str()));
            return MIstatus::failure;
        }

        m_brkPt.SetEnabled(m_bBrkPtEnabled);
        m_brkPt.SetIgnoreCount(m_nBrkPtIgnoreCount);
        if (m_bBrkPtCondition)
            m_brkPt.SetCondition(m_brkPtCondition.c_str());
        if (m_bBrkPtThreadId)
            m_brkPt.SetThreadID(m_nBrkPtThreadId);
    }

    // CODETAG_LLDB_BREAKPOINT_CREATION
    // This is in the main thread
    // Record break point information to be by LLDB event handler function
    CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
    if (!rSessionInfo.GetBrkPtInfo(m_brkPt, sBrkPtInfo))
        return MIstatus::failure;
    sBrkPtInfo.m_id = m_brkPt.GetID();
    sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;
    sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
    sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp;
    sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;
    sBrkPtInfo.m_nTimes = m_brkPt.GetHitCount();
    sBrkPtInfo.m_strOrigLoc = m_brkName;
    sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
    sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
    sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
    sBrkPtInfo.m_strCondition = m_brkPtCondition;
    sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
    sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;

    bOk = bOk && rSessionInfo.RecordBrkPtInfo(m_brkPt.GetID(), sBrkPtInfo);
    if (!bOk)
    {
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), m_brkName.c_str()));
        return MIstatus::failure;
    }

    // CODETAG_LLDB_BRKPT_ID_MAX
    if (m_brkPt.GetID() > (lldb::break_id_t)rSessionInfo.m_nBrkPointCntMax)
    {
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_CNT_EXCEEDED), m_cmdData.strMiCmd.c_str(), rSessionInfo.m_nBrkPointCntMax,
                                       m_brkName.c_str()));
        return MIstatus::failure;
    }

    return MIstatus::success;
}
예제 #25
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 CMICmdCmdBreakInsert::Execute( void )
{
	CMICMDBASE_GETOPTION( pArgTempBrkPt, OptionShort, m_constStrArgNamedTempBrkPt );
	CMICMDBASE_GETOPTION( pArgThreadGroup, OptionLong, m_constStrArgNamedThreadGroup );
	CMICMDBASE_GETOPTION( pArgLocation, String, m_constStrArgNamedLocation );
	CMICMDBASE_GETOPTION( pArgIgnoreCnt, OptionShort, m_constStrArgNamedInoreCnt );
	CMICMDBASE_GETOPTION( pArgPendingBrkPt, OptionShort, m_constStrArgNamedPendinfBrkPt );
	CMICMDBASE_GETOPTION( pArgDisableBrkPt, OptionShort, m_constStrArgNamedDisableBrkPt );
	CMICMDBASE_GETOPTION( pArgConditionalBrkPt, OptionShort, m_constStrArgNamedConditionalBrkPt );
	CMICMDBASE_GETOPTION( pArgRestrictBrkPtToThreadId, OptionShort, m_constStrArgNamedRestrictBrkPtToThreadId );
	
	m_bBrkPtEnabled = !pArgDisableBrkPt->GetFound();
	m_bBrkPtIsTemp = pArgTempBrkPt->GetFound();
	m_bHaveArgOptionThreadGrp = pArgThreadGroup->GetFound();
	if( m_bHaveArgOptionThreadGrp )
	{
		MIuint nThreadGrp = 0;
		pArgThreadGroup->GetExpectedOption< CMICmdArgValThreadGrp, MIuint >( nThreadGrp ); 
		m_strArgOptionThreadGrp = CMIUtilString::Format( "i%d", nThreadGrp );
	}
	m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
	if( pArgLocation->GetFound() )
		m_brkName = pArgLocation->GetValue();
	else if( m_bBrkPtIsPending )
	{
		pArgPendingBrkPt->GetExpectedOption< CMICmdArgValString, CMIUtilString >( m_brkName );
	}
	if( pArgIgnoreCnt->GetFound() )
	{
		pArgIgnoreCnt->GetExpectedOption< CMICmdArgValNumber, MIuint >( m_nBrkPtIgnoreCount );
	}
	m_bBrkPtCondition = pArgConditionalBrkPt->GetFound();
	if( m_bBrkPtCondition )
	{
		pArgConditionalBrkPt->GetExpectedOption< CMICmdArgValString, CMIUtilString >( m_brkPtCondition );
	}
	m_bBrkPtThreadId = pArgRestrictBrkPtToThreadId->GetFound();
	if( m_bBrkPtCondition )
	{
		pArgRestrictBrkPtToThreadId->GetExpectedOption< CMICmdArgValNumber, MIuint >( m_nBrkPtThreadId );
	}
	
	// Determine if break on a file line or at a function
	BreakPoint_e eBrkPtType = eBreakPoint_NotDefineYet;
	const CMIUtilString cColon = ":";
	CMIUtilString fileName;
	MIuint nFileLine = 0;
	CMIUtilString strFileFn;
	const MIint nPosColon = m_brkName.find( cColon );
	if( nPosColon != (MIint) std::string::npos )
	{
		CMIUtilString::VecString_t vecFileAndLocation;
		const MIuint nSplits = m_brkName.Split( cColon, vecFileAndLocation ); MIunused( nSplits );
		if( vecFileAndLocation.size() != 2 )
		{
			SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_LOCATION_FORMAT ), m_cmdData.strMiCmd.c_str(), m_brkName.c_str() ) );
			return MIstatus::failure;
		}
		fileName = vecFileAndLocation.at( 0 );
		const CMIUtilString & rStrLineOrFn( vecFileAndLocation.at( 1 ) );
		if( rStrLineOrFn.empty() )
			eBrkPtType = eBreakPoint_ByName;
		else
		{
			MIint64 nValue = 0;
			if( rStrLineOrFn.ExtractNumber( nValue ) )
			{
				nFileLine = static_cast< MIuint >( nValue );
				eBrkPtType = eBreakPoint_ByFileLine;
			}
			else
			{
				strFileFn = rStrLineOrFn;
				eBrkPtType = eBreakPoint_ByFileFn;
			}
		}
	}

	// Determine if break defined as an address
	lldb::addr_t nAddress = 0;
	if( eBrkPtType == eBreakPoint_NotDefineYet ) 
	{
		MIint64 nValue = 0;
		if( m_brkName.ExtractNumber( nValue ) )
		{
			nAddress = static_cast< lldb::addr_t >( nValue );
			eBrkPtType = eBreakPoint_ByAddress;
		}
	}
	
	// Break defined as an function
	if( eBrkPtType == eBreakPoint_NotDefineYet ) 
	{
		eBrkPtType = eBreakPoint_ByName;
	}

	// Ask LLDB to create a breakpoint
	bool bOk = MIstatus::success;
	CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
	lldb::SBTarget & rTarget = rSessionInfo.m_lldbTarget;
	switch( eBrkPtType ) 
	{
	case eBreakPoint_ByAddress:
		m_brkPt = rTarget.BreakpointCreateByAddress( nAddress );
		break;
	case eBreakPoint_ByFileFn:
		m_brkPt = rTarget.BreakpointCreateByName( strFileFn.c_str(), fileName.c_str() );
		break;
	case eBreakPoint_ByFileLine:
		m_brkPt = rTarget.BreakpointCreateByLocation( fileName.c_str(), nFileLine );
		break;
	case eBreakPoint_ByName:
		m_brkPt = rTarget.BreakpointCreateByName( m_brkName.c_str(), rTarget.GetExecutable().GetFilename() );
		break;
	case eBreakPoint_count:
	case eBreakPoint_NotDefineYet:
	case eBreakPoint_Invalid:
		bOk = MIstatus::failure;
		break;
	}
	
	if( bOk )
	{
		m_brkPt.SetEnabled( m_bBrkPtEnabled );
		m_brkPt.SetIgnoreCount( m_nBrkPtIgnoreCount );
		if( m_bBrkPtCondition )
			m_brkPt.SetCondition( m_brkPtCondition.c_str() );
		if( m_bBrkPtThreadId )
			m_brkPt.SetThreadID( m_nBrkPtThreadId );
		if( !m_brkPt.IsValid() )
			m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
	}

	// CODETAG_LLDB_BREAKPOINT_CREATION
	// This is in the main thread
	// Record break point information to be by LLDB event handler function
	CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
	sBrkPtInfo.m_id = m_brkPt.GetID();
	sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;		
	sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
	sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp; 
	sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;	
	sBrkPtInfo.m_strOrigLoc = m_brkName;					
	sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
	sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
	sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
	sBrkPtInfo.m_strCondition = m_brkPtCondition;
	sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
	sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;
	bOk = bOk && rSessionInfo.RecordBrkPtInfo( m_brkPt.GetID(), sBrkPtInfo );
	
	if( !bOk )
	{
		SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_brkName.c_str() ) );
		return MIstatus::failure;
	}
	if( m_brkPt.GetID() > (lldb::break_id_t) rSessionInfo.m_nBrkPointCntMax )
	{
		SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_CNT_EXCEEDED ), m_cmdData.strMiCmd.c_str(), rSessionInfo.m_nBrkPointCntMax, m_brkName.c_str() ) );
		return MIstatus::failure;
	}

	return MIstatus::success;
}
예제 #26
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.
//          Synopsis: -file-exec-and-symbols file
//          Ref: http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-File-Commands.html#GDB_002fMI-File-Commands
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmdCmdFileExecAndSymbols::Execute(void)
{
    CMICMDBASE_GETOPTION(pArgNamedFile, File, m_constStrArgNameFile);
    CMICMDBASE_GETOPTION(pArgPlatformName, OptionShort, m_constStrArgNamedPlatformName);
    CMICMDBASE_GETOPTION(pArgRemotePath, OptionShort, m_constStrArgNamedRemotePath);
    CMICmdArgValFile *pArgFile = static_cast<CMICmdArgValFile *>(pArgNamedFile);
    const CMIUtilString &strExeFilePath(pArgFile->GetValue());
    bool bPlatformName = pArgPlatformName->GetFound();
    CMIUtilString platformName;
    if (bPlatformName)
    {
        pArgPlatformName->GetExpectedOption<CMICmdArgValString, CMIUtilString>(platformName);
    }
    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
    lldb::SBDebugger &rDbgr = rSessionInfo.GetDebugger();
    lldb::SBError error;
    const char *pTargetTriple = nullptr; // Let LLDB discover the triple required
    const char *pTargetPlatformName = platformName.c_str();
    const bool bAddDepModules = false;
    lldb::SBTarget target = rDbgr.CreateTarget(strExeFilePath.c_str(), pTargetTriple, pTargetPlatformName, bAddDepModules, error);
    CMIUtilString strWkDir;
    const CMIUtilString &rStrKeyWkDir(rSessionInfo.m_constStrSharedDataKeyWkDir);
    if (!rSessionInfo.SharedDataRetrieve<CMIUtilString>(rStrKeyWkDir, strWkDir))
    {
        strWkDir = CMIUtilFileStd::StripOffFileName(strExeFilePath);
        if (!rSessionInfo.SharedDataAdd<CMIUtilString>(rStrKeyWkDir, strWkDir))
        {
            SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD), m_cmdData.strMiCmd.c_str(), rStrKeyWkDir.c_str()));
            return MIstatus::failure;
        }
    }
    if (!rDbgr.SetCurrentPlatformSDKRoot(strWkDir.c_str()))
    {

        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FNFAILED), m_cmdData.strMiCmd.c_str(), "SetCurrentPlatformSDKRoot()"));
        return MIstatus::failure;
    }
    if (pArgRemotePath->GetFound())
    {
        CMIUtilString remotePath;
        pArgRemotePath->GetExpectedOption<CMICmdArgValString, CMIUtilString>(remotePath);
        lldb::SBModule module = target.FindModule(target.GetExecutable());
        if (module.IsValid())
        {
            module.SetPlatformFileSpec(lldb::SBFileSpec(remotePath.c_str()));
        }
    }
    lldb::SBStream err;
    if (error.Fail())
    {
        const bool bOk = error.GetDescription(err);
        MIunused(bOk);
    }
    if (!target.IsValid())
    {
        SetError(
            CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET), m_cmdData.strMiCmd.c_str(), strExeFilePath.c_str(), err.GetData()));
        return MIstatus::failure;
    }
    if (error.Fail())
    {
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_CREATE_TARGET), m_cmdData.strMiCmd.c_str(), err.GetData()));
        return MIstatus::failure;
    }

    return MIstatus::success;
}
예제 #27
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;
}
예제 #28
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.
//			Synopis: -list-thread-groups [ --available ] [ --recurse 1 ] [ group ... ]
//			This command does not follow the MI documentation exactly. Has an extra
//			argument "i1" to handle. 
//			Ref: http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Miscellaneous-Commands.html#GDB_002fMI-Miscellaneous-Commands
// Type:	Overridden.
// Args:	None.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmdCmdListThreadGroups::Execute( void )
{
	if( m_setCmdArgs.IsArgContextEmpty() )
		// No options so "top level thread groups"
		return MIstatus::success;

	CMICMDBASE_GETOPTION( pArgAvailable, OptionLong, m_constStrArgNamedAvailable );
	CMICMDBASE_GETOPTION( pArgRecurse, OptionLong, m_constStrArgNamedRecurse );
	CMICMDBASE_GETOPTION( pArgGroup, ListOfN, m_constStrArgNamedGroup );
	CMICMDBASE_GETOPTION( pArgThreadGroup, ThreadGrp, m_constStrArgNamedThreadGroup );
	
	// Demo of how to get the value of long argument --recurse's option of 1 "--recurse 1"
	const CMICmdArgValOptionLong::VecArgObjPtr_t & rVecOptions( pArgRecurse->GetExpectedOptions() );
	const CMICmdArgValNumber * pRecurseDepthOption = (rVecOptions.size() > 0) ? static_cast< CMICmdArgValNumber * >( rVecOptions[ 1 ] ) : nullptr;
	const MIuint nRecurseDepth = (pRecurseDepthOption != nullptr) ? pRecurseDepthOption->GetValue() : 0;
	
	// Demo of how to get List of N numbers (the Group argument not implement for this command (yet))
	const CMICmdArgValListOfN::VecArgObjPtr_t & rVecGroupId( pArgGroup->GetValue() );
	CMICmdArgValListOfN::VecArgObjPtr_t::const_iterator it = rVecGroupId.begin();
	while( it != rVecGroupId.end() )
	{
		const CMICmdArgValNumber * pOption = static_cast< CMICmdArgValNumber * >( *it );
		const MIuint nGrpId = pOption->GetValue();

		// Next
		++it;
	}

	// Got some options so "threads"
	if( pArgAvailable->GetFound() )
	{
		if( pArgRecurse->GetFound() )
		{
			m_bHaveArgRecurse = true;
			return MIstatus::success;
		}

		m_bHaveArgOption = true;
		return MIstatus::success;
	}
	// "i1" as first argument (pos 0 of possible arg)
	if( !pArgThreadGroup->GetFound() )
		return MIstatus::success;
	m_bIsI1 = true;

	CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
	lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
	
	// Note do not check for rProcess is IsValid(), continue
		
	m_vecMIValueTuple.clear();
	const MIuint nThreads = rProcess.GetNumThreads();
	for( MIuint i = 0; i < nThreads; i++ )
	{
		//	GetThreadAtIndex() uses a base 0 index
		//	GetThreadByIndexID() uses a base 1 index
		lldb::SBThread thread = rProcess.GetThreadAtIndex( i );

		if( thread.IsValid() )
		{
			CMICmnMIValueTuple miTuple;
			if( !rSessionInfo.MIResponseFormThreadInfo( m_cmdData, thread, miTuple ) )
				return MIstatus::failure;

			m_vecMIValueTuple.push_back( miTuple );
		}
	}

	return MIstatus::success;
}
예제 #29
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.
//          Synopsis: -target-select type parameters ...
//          Ref: http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmdCmdTargetSelect::Execute(void)
{
    CMICMDBASE_GETOPTION(pArgType, String, m_constStrArgNamedType);
    CMICMDBASE_GETOPTION(pArgParameters, String, m_constStrArgNamedParameters);

    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());

    // Check we have a valid target
    // Note: target created via 'file-exec-and-symbols' command
    if (!rSessionInfo.GetTarget().IsValid())
    {
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT), m_cmdData.strMiCmd.c_str()));
        return MIstatus::failure;
    }

    // Verify that we are executing remotely
    const CMIUtilString &rRemoteType(pArgType->GetValue());
    if (rRemoteType != "remote")
    {
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_TYPE), m_cmdData.strMiCmd.c_str(), rRemoteType.c_str()));
        return MIstatus::failure;
    }

    // Create a URL pointing to the remote gdb stub
    const CMIUtilString strUrl = CMIUtilString::Format("connect://%s", pArgParameters->GetValue().c_str());

    // Ask LLDB to collect to the target port
    const MIchar *pPlugin("gdb-remote");
    lldb::SBError error;
    lldb::SBProcess process = rSessionInfo.GetTarget().ConnectRemote(rSessionInfo.GetListener(), strUrl.c_str(), pPlugin, error);

    // Verify that we have managed to connect successfully
    lldb::SBStream errMsg;
    if (!process.IsValid())
    {
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_PLUGIN), m_cmdData.strMiCmd.c_str(), errMsg.GetData()));
        return MIstatus::failure;
    }
    if (error.Fail())
    {
        SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_CONNECT_TO_TARGET), m_cmdData.strMiCmd.c_str(), errMsg.GetData()));
        return MIstatus::failure;
    }

    // Set the environment path if we were given one
    CMIUtilString strWkDir;
    if (rSessionInfo.SharedDataRetrieve<CMIUtilString>(rSessionInfo.m_constStrSharedDataKeyWkDir, strWkDir))
    {
        lldb::SBDebugger &rDbgr = rSessionInfo.GetDebugger();
        if (!rDbgr.SetCurrentPlatformSDKRoot(strWkDir.c_str()))
        {
            SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FNFAILED), m_cmdData.strMiCmd.c_str(), "target-select"));
            return MIstatus::failure;
        }
    }

    // Set the shared object path if we were given one
    CMIUtilString strSolibPath;
    if (rSessionInfo.SharedDataRetrieve<CMIUtilString>(rSessionInfo.m_constStrSharedDataSolibPath, strSolibPath))
    {
        lldb::SBDebugger &rDbgr = rSessionInfo.GetDebugger();
        lldb::SBCommandInterpreter cmdIterpreter = rDbgr.GetCommandInterpreter();

        CMIUtilString strCmdString = CMIUtilString::Format("target modules search-paths add . %s", strSolibPath.c_str());

        lldb::SBCommandReturnObject retObj;
        cmdIterpreter.HandleCommand(strCmdString.c_str(), retObj, false);

        if (!retObj.Succeeded())
        {
            SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FNFAILED), m_cmdData.strMiCmd.c_str(), "target-select"));
            return MIstatus::failure;
        }
    }

    return MIstatus::success;
}