//++
//------------------------------------------------------------------------------------
// Details: Carry out work to complete the GDB set option 'target-async' to
// prepare
//          and send back information asked for.
// Type:    Method.
// Args:    vrWords - (R) List of additional parameters used by this option.
// Return:  MIstatus::success - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool CMICmdCmdGdbSet::OptionFnTargetAsync(
    const CMIUtilString::VecString_t &vrWords) {
  bool bAsyncMode = false;
  bool bOk = true;

  if (vrWords.size() > 1)
    // Too many arguments.
    bOk = false;
  else if (vrWords.size() == 0)
    // If no arguments, default is "on".
    bAsyncMode = true;
  else if (CMIUtilString::Compare(vrWords[0], "on"))
    bAsyncMode = true;
  else if (CMIUtilString::Compare(vrWords[0], "off"))
    bAsyncMode = false;
  else
    // Unrecognized argument.
    bOk = false;

  if (!bOk) {
    // Report error.
    m_bGbbOptionFnHasError = true;
    m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_TARGETASYNC);
    return MIstatus::failure;
  }

  // Turn async mode on/off.
  CMICmnLLDBDebugSessionInfo &rSessionInfo(
      CMICmnLLDBDebugSessionInfo::Instance());
  rSessionInfo.GetDebugger().SetAsync(bAsyncMode);

  return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
// Details: Return the resolved file's path for the given file.
// Type:    Method.
// Args:    vstrUnknown     - (R)   String assigned to path when resolved path is empty.
//          vwrResolvedPath - (RW)  The original path overwritten with resolved path.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnLLDBDebugSessionInfo::ResolvePath(const CMIUtilString &vstrUnknown, CMIUtilString &vwrResolvedPath)
{
    if (vwrResolvedPath.size() < 1)
    {
        vwrResolvedPath = vstrUnknown;
        return MIstatus::success;
    }

    bool bOk = MIstatus::success;

    CMIUtilString::VecString_t vecPathFolders;
    const MIuint nSplits = vwrResolvedPath.Split("/", vecPathFolders);
    MIunused(nSplits);
    MIuint nFoldersBack = 1; // 1 is just the file (last element of vector)
    while (bOk && (vecPathFolders.size() >= nFoldersBack))
    {
        CMIUtilString strTestPath;
        MIuint nFoldersToAdd = nFoldersBack;
        while (nFoldersToAdd > 0)
        {
            strTestPath += "/";
            strTestPath += vecPathFolders[vecPathFolders.size() - nFoldersToAdd];
            nFoldersToAdd--;
        }
        bool bYesAccessible = false;
        bOk = AccessPath(strTestPath, bYesAccessible);
        if (bYesAccessible)
        {
            vwrResolvedPath = strTestPath;
            return MIstatus::success;
        }
        else
            nFoldersBack++;
    }

    // No files exist in the union of working directory and debuginfo path
    // Simply use the debuginfo path and let the IDE handle it.

    return bOk;
}
//++
// Details: Parse the text following *this argument and extract the options the
// values of
//          CMICmdArgValListBase::m_eArgType forming argument objects for each
//          of those
//          options extracted.
// Type:    Method.
// Args:    vrwTxt      - (RW)  The command's argument options string.
//          nArgIndex   - (R)   The Nth arg position in argument context from
//          the left.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdArgValOptionLong::ExtractExpectedOptions(CMICmdArgContext &vrwTxt,
                                                    const MIuint nArgIndex) {
  CMIUtilString::VecString_t vecOptions = vrwTxt.GetArgs();
  if (vecOptions.size() == 0)
    return MIstatus::failure;

  MIuint nArgIndexCnt = 0;
  MIuint nTypeCnt = 0;
  MIuint nTypeCnt2 = 0;
  MIuint nFoundNOptionsCnt = 0;
  CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
  while (it != vecOptions.end()) {
    // Move to the Nth argument position from left before do validation/checking
    if (nArgIndexCnt++ == nArgIndex) {
      nTypeCnt++;
      const CMIUtilString &rOption(*it);
      if (IsExpectedCorrectType(rOption, m_eExpectingOptionType)) {
        nTypeCnt2++;
        CMICmdArgValBase *pOptionObj =
            CreationObj(rOption, m_eExpectingOptionType);
        if ((pOptionObj != nullptr) &&
            vrwTxt.RemoveArgAtPos(rOption, nArgIndex)) {
          nFoundNOptionsCnt++;
          m_vecArgsExpected.push_back(pOptionObj);
        }
      }

      // Is the sequence 'options' of same type broken. Expecting the same type
      // until the
      // next argument.
      if (nTypeCnt != nTypeCnt2)
        return MIstatus::failure;

      if (nFoundNOptionsCnt == m_nExpectingNOptions)
        return MIstatus::success;
    }

    // Next
    ++it;
  }
  if (nFoundNOptionsCnt != m_nExpectingNOptions)
    return MIstatus::failure;

  return MIstatus::success;
}
Beispiel #4
0
//++ ------------------------------------------------------------------------------------
// Details: Carry out work to complete the GDB set option 'output-radix' to prepare
//          and send back information asked for.
// Type:    Method.
// Args:    vrWords - (R) List of additional parameters used by this option.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmdCmdGdbSet::OptionFnOutputRadix(const CMIUtilString::VecString_t &vrWords)
{
    // Check we have at least one argument
    if (vrWords.size() < 1)
    {
        m_bGbbOptionFnHasError = true;
        m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH);
        return MIstatus::failure;
    }
    const CMIUtilString &rStrValOutputRadix(vrWords[0]);
    
    CMICmnLLDBDebugSessionInfoVarObj::varFormat_e  format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid;
    MIint64 radix;
    if (rStrValOutputRadix.ExtractNumber(radix))
    {
        switch (radix)
        {
        case 8:
            format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Octal;
            break;
        case 10:
            format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural;
            break;
        case 16:
            format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Hex;
            break;
        default:
            format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid;
            break;
        }
    }
    if (format == CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid)
    {
        m_bGbbOptionFnHasError = false;
        SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD), m_cmdData.strMiCmd.c_str(), "Output Radix"));
        return MIstatus::failure;
    }
    CMICmnLLDBDebugSessionInfoVarObj::VarObjSetFormat(format);
    
    return MIstatus::success;
}
//++
//------------------------------------------------------------------------------------
// Details: Carry out work to complete the GDB set option 'disassembly-flavor'
// to prepare
//          and send back information asked for.
// Type:    Method.
// Args:    vrWords - (R) List of additional parameters used by this option.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool CMICmdCmdGdbSet::OptionFnDisassemblyFlavor(
    const CMIUtilString::VecString_t &vrWords) {
  // Check we have at least one argument
  if (vrWords.size() < 1) {
    m_bGbbOptionFnHasError = true;
    // m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH);
    return MIstatus::failure;
  }
  const CMIUtilString &rStrValDisasmFlavor(vrWords[0]);

  lldb::SBDebugger &rDbgr = m_rLLDBDebugSessionInfo.GetDebugger();
  lldb::SBError error = lldb::SBDebugger::SetInternalVariable(
      "target.x86-disassembly-flavor", rStrValDisasmFlavor.c_str(),
      rDbgr.GetInstanceName());
  if (error.Fail()) {
    m_strGdbOptionFnError = error.GetCString();
    return MIstatus::failure;
  }

  return MIstatus::success;
}
//++
//------------------------------------------------------------------------------------
// Details: Carry out work to complete the GDB set option
// 'print-char-array-as-string' to
//          prepare and send back information asked for.
// Type:    Method.
// Args:    vrWords - (R) List of additional parameters used by this option.
// Return:  MIstatus::success - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool CMICmdCmdGdbSet::OptionFnPrint(const CMIUtilString::VecString_t &vrWords) {
  const bool bAllArgs(vrWords.size() == 2);
  const bool bArgOn(bAllArgs && (CMIUtilString::Compare(vrWords[1], "on") ||
                                 CMIUtilString::Compare(vrWords[1], "1")));
  const bool bArgOff(bAllArgs && (CMIUtilString::Compare(vrWords[1], "off") ||
                                  CMIUtilString::Compare(vrWords[1], "0")));
  if (!bAllArgs || (!bArgOn && !bArgOff)) {
    m_bGbbOptionFnHasError = true;
    m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_PRINT_BAD_ARGS);
    return MIstatus::failure;
  }

  const CMIUtilString strOption(vrWords[0]);
  CMIUtilString strOptionKey;
  if (CMIUtilString::Compare(strOption, "char-array-as-string"))
    strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintCharArrayAsString;
  else if (CMIUtilString::Compare(strOption, "expand-aggregates"))
    strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintExpandAggregates;
  else if (CMIUtilString::Compare(strOption, "aggregate-field-names"))
    strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintAggregateFieldNames;
  else {
    m_bGbbOptionFnHasError = true;
    m_strGdbOptionFnError = CMIUtilString::Format(
        MIRSRC(IDS_CMD_ERR_GDBSET_OPT_PRINT_UNKNOWN_OPTION), strOption.c_str());
    return MIstatus::failure;
  }

  const bool bOptionValue(bArgOn);
  if (!m_rLLDBDebugSessionInfo.SharedDataAdd<bool>(strOptionKey,
                                                   bOptionValue)) {
    m_bGbbOptionFnHasError = false;
    SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD),
                                   m_cmdData.strMiCmd.c_str(),
                                   strOptionKey.c_str()));
    return MIstatus::failure;
  }

  return MIstatus::success;
}
Beispiel #7
0
//++
//------------------------------------------------------------------------------------
// Details: Carry out work to complete the GDB show option 'print' to prepare
// and send
//          back the requested information.
// Type:    Method.
// Args:    vrWords - (R) List of additional parameters used by this option.
// Return:  MIstatus::success - Function succeeded.
//          MIstatus::failure - Function failed.
// Throws:  None.
//--
bool CMICmdCmdGdbShow::OptionFnPrint(
    const CMIUtilString::VecString_t &vrWords) {
  const bool bAllArgs(vrWords.size() == 1);
  if (!bAllArgs) {
    m_bGbbOptionFnHasError = true;
    m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_BAD_ARGS);
    return MIstatus::failure;
  }

  const CMIUtilString strOption(vrWords[0]);
  CMIUtilString strOptionKey;
  bool bOptionValueDefault = false;
  if (CMIUtilString::Compare(strOption, "char-array-as-string"))
    strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintCharArrayAsString;
  else if (CMIUtilString::Compare(strOption, "expand-aggregates"))
    strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintExpandAggregates;
  else if (CMIUtilString::Compare(strOption, "aggregate-field-names")) {
    strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintAggregateFieldNames;
    bOptionValueDefault = true;
  } else {
    m_bGbbOptionFnHasError = true;
    m_strGdbOptionFnError = CMIUtilString::Format(
        MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_UNKNOWN_OPTION),
        strOption.c_str());
    return MIstatus::failure;
  }

  bool bOptionValue = false;
  bOptionValue = bOptionValueDefault
                     ? !m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(
                           strOptionKey, bOptionValue) ||
                           bOptionValue
                     : m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(
                           strOptionKey, bOptionValue) &&
                           bOptionValue;

  m_strValue = bOptionValue ? "on" : "off";
  return MIstatus::success;
}
Beispiel #8
0
//++ ------------------------------------------------------------------------------------
// Details:	Carry out work to complete the GDB set option 'solib-search-path' to prepare 
//			and send back information asked for.
// Type:	Method.
// Args:	vrWords	- (R) List of additional parameters used by this option.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmdCmdGdbSet::OptionFnSolibSearchPath( const CMIUtilString::VecString_t & vrWords )
{
	// Check we have at least one argument
	if( vrWords.size() < 1 )
	{
		m_bGbbOptionFnHasError = true;
		m_strGdbOptionFnError = MIRSRC( IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH );
		return MIstatus::failure;
	}
	const CMIUtilString & rStrValSolibPath( vrWords[ 0 ] );

	// Add 'solib-search-path' to the shared data list
	const CMIUtilString & rStrKeySolibPath( m_rLLDBDebugSessionInfo.m_constStrSharedDataSolibPath );
	if( !m_rLLDBDebugSessionInfo.SharedDataAdd< CMIUtilString >( rStrKeySolibPath, rStrValSolibPath ) )
	{
		m_bGbbOptionFnHasError = false;
		SetError( CMIUtilString::Format( MIRSRC( IDS_DBGSESSION_ERR_SHARED_DATA_ADD ), m_cmdData.strMiCmd.c_str(), rStrKeySolibPath.c_str() ) );
		return MIstatus::failure;
	}	

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