//++ //------------------------------------------------------------------------------------ // 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; }
//++ ------------------------------------------------------------------------------------ // Details: Get the current driver to validate executable command line arguments. // Type: Method. // Args: argc - (R) An integer that contains the count of arguments that follow in // argv. The argc parameter is always greater than or equal to 1. // argv - (R) An array of null-terminated strings representing command-line // arguments entered by the user of the program. By convention, // argv[0] is the command with which the program is invoked. // vpStdOut - (R) Point to a standard output stream. // vwbExiting - (W) True = *this want to exit, false = continue to work. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMIDriverMgr::DriverParseArgs( const int argc, const char * argv[], FILE * vpStdOut, bool & vwbExiting ) { if( m_pDriverCurrent == nullptr ) { const CMIUtilString errMsg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_CURRENT_NOT_SET ) ) ); CMICmnStreamStdout::Instance().Write( errMsg, true ); return MIstatus::failure; } const lldb::SBError error( m_pDriverCurrent->DoParseArgs( argc, argv, vpStdOut, vwbExiting ) ); bool bOk = !error.Fail(); if( !bOk ) { CMIUtilString errMsg; const MIchar * pErrorCstr = error.GetCString(); if( pErrorCstr != nullptr ) errMsg = CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_PARSE_ARGS ), m_pDriverCurrent->GetName().c_str(), pErrorCstr ); else errMsg = CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_PARSE_ARGS_UNKNOWN ), m_pDriverCurrent->GetName().c_str() ); bOk = CMICmnStreamStdout::Instance().Write( errMsg, true ); } return bOk; }
//++ ------------------------------------------------------------------------------------ // 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 CMICmdCmdGdbInfo::Acknowledge(void) { if (!m_bPrintFnRecognised) { const CMICmnMIValueConst miValueConst(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND), m_strPrintFnName.c_str())); const CMICmnMIValueResult miValueResult("msg", miValueConst); const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult); m_miResultRecord = miRecordResult; return MIstatus::success; } if (m_bPrintFnSuccessful) { const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done); m_miResultRecord = miRecordResult; return MIstatus::success; } const CMICmnMIValueConst miValueConst(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strPrintFnError.c_str())); const CMICmnMIValueResult miValueResult("msg", miValueConst); const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult); m_miResultRecord = miRecordResult; return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // 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; }
//++ ------------------------------------------------------------------------------------ // Details: Determine and form the medium file's directory path and name. // Type: Method. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLogMediumFile::FileFormFileNamePath() { ClrErrorDescription(); m_fileNamePath = MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH); if (m_strMediumFileDirectory.compare(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)) != 0) { CMIUtilDateTimeStd date; m_strMediumFileName = CMIUtilString::Format(m_constMediumFileNameFormat.c_str(), date.GetDateTimeLogFilename().c_str()); #if defined(_MSC_VER) m_fileNamePath = CMIUtilString::Format("%s\\%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str()); #else m_fileNamePath = CMIUtilString::Format("%s/%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str()); #endif // defined ( _MSC_VER ) return MIstatus::success; } SetErrorDescription(MIRSRC(IDE_MEDIUMFILE_ERR_GET_FILE_PATHNAME_SYS)); return MIstatus::failure; }
//++ ------------------------------------------------------------------------------------ // Details: Register a command's creator function with the command identifier the MI // command name i.e. 'file-exec-and-symbols'. // Type: Method. // Args: vMiCmd - (R) Command's name, the MI command. // vCmdCreateFn - (R) Command's creator function pointer. // Return: MIstatus::success - Functionality succeeded. // MIstatus::failure - Functionality failed. // Throws: None. //-- bool CMICmdFactory::CmdRegister(const CMIUtilString &vMiCmd, CmdCreatorFnPtr vCmdCreateFn) { if (!IsValid(vMiCmd)) { SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_CMDFACTORY_ERR_INVALID_CMD_NAME), vMiCmd.c_str())); return MIstatus::failure; } if (vCmdCreateFn == nullptr) { SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_CMDFACTORY_ERR_INVALID_CMD_CR8FN), vMiCmd.c_str())); return MIstatus::failure; } if (HaveAlready(vMiCmd)) { SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_CMDFACTORY_ERR_CMD_ALREADY_REGED), vMiCmd.c_str())); return MIstatus::failure; } MapPairMiCmdToCmdCreatorFn_t pr(vMiCmd, vCmdCreateFn); m_mapMiCmdToCmdCreatorFn.insert(pr); return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: Determine and form the medium file's directory path and name. // Type: Method. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLogMediumFile::FileFormFileNamePath( void ) { ClrErrorDescription(); m_fileNamePath = MIRSRC( IDS_MEDIUMFILE_ERR_INVALID_PATH ); CMIUtilString strPathName; if( CMIUtilSystem().GetLogFilesPath( strPathName ) ) { const CMIUtilString strPath = CMIUtilFileStd().StripOffFileName( strPathName ); // ToDo: Review this LINUX log file quick fix so not hidden // AD: // Linux was creating a log file here called '.\log.txt'. The '.' on linux // signifies that this file is 'hidden' and not normally visible. A quick fix // is to remove the path component all together. Linux also normally uses '/' // as directory separators, again leading to the problem of the hidden log. #if defined ( _MSC_VER ) m_fileNamePath = CMIUtilString::Format( "%s\\%s", strPath.c_str(), m_constMediumFileName.c_str() ); #else m_fileNamePath = CMIUtilString::Format( "%s", m_constMediumFileName.c_str() ); #endif // defined ( _MSC_VER ) return MIstatus::success; } SetErrorDescription( MIRSRC( IDE_MEDIUMFILE_ERR_GET_FILE_PATHNAME_SYS ) ); return MIstatus::failure; }
//++ //------------------------------------------------------------------------------------ // 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; }
//++ ------------------------------------------------------------------------------------ // Details: Register with the debugger, the SBListener, the type of events you are interested // in. Others, like commands, may have already set the mask. // Type: Method. // Args: vClientName - (R) ID of the client who wants these events set. // vBroadcaster - (R) An SBBroadcaster's derived class. // vEventMask - (R) The mask of events to listen for. // Return: MIstatus::success - Functionality succeeded. // MIstatus::failure - Functionality failed. // Throws: None. //-- bool CMICmnLLDBDebugger::RegisterForEvent(const CMIUtilString &vClientName, const lldb::SBBroadcaster &vBroadcaster, const MIuint vEventMask) { const char *pBroadcasterName = vBroadcaster.GetName(); if (pBroadcasterName == nullptr) { SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_BROADCASTER_NAME), MIRSRC(IDS_WORD_INVALIDNULLPTR))); return MIstatus::failure; } CMIUtilString broadcasterName(pBroadcasterName); if (broadcasterName.length() == 0) { SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_BROADCASTER_NAME), MIRSRC(IDS_WORD_INVALIDEMPTY))); return MIstatus::failure; } MIuint existingMask = 0; if (!BroadcasterGetMask(broadcasterName, existingMask)) return MIstatus::failure; if (!ClientSaveMask(vClientName, broadcasterName, vEventMask)) return MIstatus::failure; MIuint eventMask = vEventMask; eventMask += existingMask; const MIuint result = m_lldbListener.StartListeningForEvents(vBroadcaster, eventMask); if (result == 0) { SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_STARTLISTENER), pBroadcasterName)); return MIstatus::failure; } return BroadcasterSaveMask(broadcasterName, eventMask); }
//++ ------------------------------------------------------------------------------------ // Details: Create a command given the specified MI command name. The command data object // contains the options for the command. // Type: Method. // Args: vMiCmd - (R) Command's name, the MI command. // vCmdData - (RW) Command's metadata status/information/result object. // vpNewCmd - (W) New command instance. // Return: MIstatus::success - Functionality succeeded. // MIstatus::failure - Functionality failed. // Throws: None. //-- bool CMICmdFactory::CmdCreate( const CMIUtilString & vMiCmd, const SMICmdData & vCmdData, CMICmdBase *& vpNewCmd ) { bool bOk = MIstatus::success; vpNewCmd = nullptr; if( !IsValid( vMiCmd ) ) { SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CMDFACTORY_ERR_INVALID_CMD_NAME ), vMiCmd.c_str() ) ); return MIstatus::failure; } if( !HaveAlready( vMiCmd ) ) { SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CMDFACTORY_ERR_CMD_NOT_REGISTERED ), vMiCmd.c_str() ) ); return MIstatus::failure; } const MapMiCmdToCmdCreatorFn_t::const_iterator it = m_mapMiCmdToCmdCreatorFn.find( vMiCmd ); const CMIUtilString & rMiCmd( (*it).first ); MIunused( rMiCmd ); CmdCreatorFnPtr pFn = (*it).second; CMICmdBase * pCmd = (*pFn)(); SMICmdData cmdData( vCmdData ); cmdData.id = pCmd->GetGUID(); bOk = pCmd->SetCmdData( cmdData ); if( bOk ) vpNewCmd = pCmd; return bOk; }
//++ ------------------------------------------------------------------------------------ // Details: Retrieve the resource text data for the given resource ID. If a resource ID // cannot be found and error is given returning the ID of the resource that // cannot be located. // Type: Method. // Args: vResourceId - (R) MI resource ID. // vrwResourceString - (W) Text. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnResources::GetStringFromResource(const MIuint vResourceId, CMIUtilString &vrwResourceString) const { MapRscrIdToTextData_t::const_iterator it = m_mapRscrIdToTextData.find(vResourceId); if (it == m_mapRscrIdToTextData.end()) { // Check this is a static variable init that needs this before we are ready if (!m_bInitialized) { (const_cast<CMICmnResources *>(this))->Initialize(); it = m_mapRscrIdToTextData.find(vResourceId); if (it == m_mapRscrIdToTextData.end()) { vrwResourceString = MIRSRC(IDS_RESOURCES_ERR_STRING_TABLE_INVALID); return MIstatus::failure; } } if (it == m_mapRscrIdToTextData.end()) { vrwResourceString = CMIUtilString::Format(MIRSRC(IDS_RESOURCES_ERR_STRING_NOT_FOUND), vResourceId); return MIstatus::failure; } } const MIuint nRsrcId((*it).first); MIunused(nRsrcId); const MIchar *pRsrcData((*it).second); // Return result vrwResourceString = pRsrcData; return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: Write data to existing opened file. // Type: Method. // Args: vData - (R) Text data. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMIUtilFileStd::Write( const CMIUtilString & vData ) { if( vData.size() == 0 ) return MIstatus::success; if( m_bFileError ) return MIstatus::failure; if( m_pFileHandle == nullptr ) { m_bFileError = true; SetErrorDescriptionn( MIRSRC( IDE_UTIL_FILE_ERR_WRITING_NOTOPEN ), m_fileNamePath.c_str() ); return MIstatus::failure; } // Get the string size MIuint size = vData.size(); if( ::fwrite( vData.c_str(), 1, size, m_pFileHandle ) == size ) { // Flush the data to the file ::fflush( m_pFileHandle ); return MIstatus::success; } // Not all of the data has been transferred m_bFileError = true; SetErrorDescriptionn( MIRSRC( IDE_UTIL_FILE_ERR_WRITING_FILE ), m_fileNamePath.c_str() ); return MIstatus::failure; }
//++ ------------------------------------------------------------------------------------ // Details: Write data to existing opened file. // Type: Method. // Args: vData - (R) Text data. // vCharCnt - (R) Text data length. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMIUtilFileStd::Write( const MIchar * vpData, const MIuint vCharCnt ) { if( vCharCnt == 0 ) return MIstatus::success; if( m_bFileError ) return MIstatus::failure; if( m_pFileHandle == nullptr ) { m_bFileError = true; SetErrorDescriptionn( MIRSRC( IDE_UTIL_FILE_ERR_WRITING_NOTOPEN ), m_fileNamePath.c_str() ); return MIstatus::failure; } if( ::fwrite( vpData, 1, vCharCnt, m_pFileHandle ) == vCharCnt ) { // Flush the data to the file ::fflush( m_pFileHandle ); return MIstatus::success; } // Not all of the data has been transferred m_bFileError = true; SetErrorDescriptionn( MIRSRC( IDE_UTIL_FILE_ERR_WRITING_FILE ), m_fileNamePath.c_str() ); return MIstatus::failure; }
//++ ------------------------------------------------------------------------------------ // 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; }
//++ ------------------------------------------------------------------------------------ // Details: Having previously had the potential command validated and found valid now // get the command executed. // If the Functionalityity returns MIstatus::failure call GetErrorDescription(). // This function is used by the application's main thread. // Type: Method. // Args: vCmdData - (RW) Command meta data. // Return: MIstatus::success - Functionality succeeded. // MIstatus::failure - Functionality failed. // Throws: None. //-- bool CMICmdMgr::CmdExecute(const SMICmdData &vCmdData) { bool bOk = MIstatus::success; // Pass the command's meta data structure to the command // so it can update it if required. (Need to copy it out of the // command before the command is deleted) CMICmdBase *pCmd = nullptr; bOk = m_factory.CmdCreate(vCmdData.strMiCmd, vCmdData, pCmd); if (!bOk) { const CMIUtilString errMsg( CMIUtilString::Format(MIRSRC(IDS_CMDMGR_ERR_CMD_FAILED_CREATE), m_factory.GetErrorDescription().c_str())); SetErrorDescription(errMsg); return MIstatus::failure; } bOk = m_invoker.CmdExecute(*pCmd); if (!bOk) { const CMIUtilString errMsg(CMIUtilString::Format(MIRSRC(IDS_CMDMGR_ERR_CMD_INVOKER), m_invoker.GetErrorDescription().c_str())); SetErrorDescription(errMsg); return MIstatus::failure; } return bOk; }
//++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool 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; }
//++ //------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command prepares a MI Record // Result // for the work carried out in the Execute() method. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdGdbSet::Acknowledge() { // Print error if option isn't recognized: // ^error,msg="The request '%s' was not recognized, not implemented" if (!m_bGdbOptionRecognised) { const CMICmnMIValueConst miValueConst( CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND), m_strGdbOptionName.c_str())); const CMICmnMIValueResult miValueResult("msg", miValueConst); const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult); m_miResultRecord = miRecordResult; return MIstatus::success; } // ^done,value="%s" if (m_bGdbOptionFnSuccessful) { const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done); m_miResultRecord = miRecordResult; return MIstatus::success; } // Print error if request failed: // ^error,msg="The request '%s' failed. const CMICmnMIValueConst miValueConst(CMIUtilString::Format( MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strGdbOptionFnError.c_str())); const CMICmnMIValueResult miValueResult("msg", miValueConst); const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult); m_miResultRecord = miRecordResult; return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: Interpret the text data and match against current commands to see if there // is a match. If a match then the command is issued and actioned on. If a // command cannot be found to match then vwbCmdYesValid is set to false and // nothing else is done here. // This function is used by the application's main thread. // Type: Method. // Args: vTextLine - (R) Text data representing a possible command. // vwbCmdYesValid - (W) True = Command invalid, false = command acted on. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMIDriver::InterpretCommandThisDriver( const CMIUtilString & vTextLine, bool & vwbCmdYesValid ) { vwbCmdYesValid = false; bool bCmdNotInCmdFactor = false; SMICmdData cmdData; CMICmdMgr & rCmdMgr = CMICmdMgr::Instance(); if( !rCmdMgr.CmdInterpret( vTextLine, vwbCmdYesValid, bCmdNotInCmdFactor, cmdData ) ) return MIstatus::failure; if( vwbCmdYesValid ) { // For debugging only //m_pLog->WriteLog( cmdData.strMiCmdAll.c_str() ); return ExecuteCommand( cmdData ); } // Write to the Log that a 'command' was not valid. // Report back to the MI client via MI result record. CMIUtilString strNotInCmdFactory; if( bCmdNotInCmdFactor ) strNotInCmdFactory = CMIUtilString::Format( MIRSRC( IDS_DRIVER_CMD_NOT_IN_FACTORY ), cmdData.strMiCmd.c_str() ); const CMIUtilString strNot( CMIUtilString::Format( "%s ", MIRSRC( IDS_WORD_NOT ) ) ); const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_CMD_RECEIVED ), vTextLine.c_str(), strNot.c_str(), strNotInCmdFactory.c_str() ) ); const CMICmnMIValueConst vconst = CMICmnMIValueConst( msg ); const CMICmnMIValueResult valueResult( "msg", vconst ); const CMICmnMIResultRecord miResultRecord( cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, valueResult ); m_rStdOut.WriteMIResponse( miResultRecord.GetString() ); // Proceed to wait for or execute next command return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: Start worker threads for the driver. // Type: Method. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMIDriver::StartWorkerThreads( void ) { bool bOk = MIstatus::success; // Grab the thread manager CMICmnThreadMgrStd & rThreadMgr = CMICmnThreadMgrStd::Instance(); // Start the stdin thread bOk &= m_rStdin.SetVisitor( *this ); if( bOk && !rThreadMgr.ThreadStart< CMICmnStreamStdin >( m_rStdin )) { const CMIUtilString errMsg = CMIUtilString::Format( MIRSRC( IDS_THREADMGR_ERR_THREAD_FAIL_CREATE ), CMICmnThreadMgrStd::Instance().GetErrorDescription().c_str() ); SetErrorDescriptionn( errMsg ); return MIstatus::failure; } // Start the event polling thread if( bOk && !rThreadMgr.ThreadStart< CMICmnLLDBDebugger >( m_rLldbDebugger ) ) { const CMIUtilString errMsg = CMIUtilString::Format( MIRSRC( IDS_THREADMGR_ERR_THREAD_FAIL_CREATE ), CMICmnThreadMgrStd::Instance().GetErrorDescription().c_str() ); SetErrorDescriptionn( errMsg ); return MIstatus::failure; } return bOk; }
//++ //------------------------------------------------------------------------------------ // Details: CMICmnLogMediumFile constructor. // Type: Method. // Args: None. // Return: None. // Throws: None. //-- CMICmnLogMediumFile::CMICmnLogMediumFile() : m_constThisMediumName(MIRSRC(IDS_MEDIUMFILE_NAME)), m_constMediumFileNameFormat("lldb-mi-%s.log"), m_strMediumFileName(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)), m_strMediumFileDirectory("."), m_fileNamePath(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)), m_eVerbosityType(CMICmnLog::eLogVerbosity_Log), m_strDate(CMIUtilDateTimeStd().GetDate()), m_fileHeaderTxt(MIRSRC(IDS_MEDIUMFILE_ERR_FILE_HEADER)) {}
//++ ------------------------------------------------------------------------------------ // Details: Initialize setup *this driver ready for use. // Type: Method. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMIDriver::Initialize( void ) { m_eCurrentDriverState = eDriverState_Initialising; m_clientUsageRefCnt++; ClrErrorDescription(); if( m_bInitialized ) return MIstatus::success; bool bOk = MIstatus::success; CMIUtilString errMsg; // Initialize all of the modules we depend on MI::ModuleInit< CMICmnLog > ( IDS_MI_INIT_ERR_LOG , bOk, errMsg ); MI::ModuleInit< CMICmnStreamStdout >( IDS_MI_INIT_ERR_STREAMSTDOUT , bOk, errMsg ); MI::ModuleInit< CMICmnStreamStderr >( IDS_MI_INIT_ERR_STREAMSTDERR , bOk, errMsg ); MI::ModuleInit< CMICmnResources > ( IDS_MI_INIT_ERR_RESOURCES , bOk, errMsg ); MI::ModuleInit< CMICmnThreadMgrStd >( IDS_MI_INIT_ERR_THREADMANAGER, bOk, errMsg ); MI::ModuleInit< CMICmnStreamStdin > ( IDS_MI_INIT_ERR_STREAMSTDIN , bOk, errMsg ); MI::ModuleInit< CMICmdMgr > ( IDS_MI_INIT_ERR_CMDMGR , bOk, errMsg ); bOk &= m_rLldbDebugger.SetDriver( *this ); MI::ModuleInit< CMICmnLLDBDebugger >( IDS_MI_INIT_ERR_LLDBDEBUGGER , bOk, errMsg ); #if MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER CMIDriverMgr & rDrvMgr = CMIDriverMgr::Instance(); bOk = bOk && rDrvMgr.RegisterDriver( *g_driver, "LLDB driver" ); // Will be pass thru driver if( bOk ) { bOk = SetEnableFallThru( false ); // This is intentional at this time - yet to be fully implemented bOk = bOk && SetDriverToFallThruTo( *g_driver ); CMIUtilString strOtherDrvErrMsg; if( bOk && GetEnableFallThru() && !g_driver->MISetup( strOtherDrvErrMsg ) ) { bOk = false; errMsg = CMIUtilString::Format( MIRSRC( IDS_MI_INIT_ERR_FALLTHRUDRIVER ), strOtherDrvErrMsg.c_str() ); } } #endif // MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER m_bExitApp = false; bOk = bOk && InitClientIDEToMIDriver(); // Init Eclipse IDE m_bInitialized = bOk; if( !bOk ) { const CMIUtilString msg = CMIUtilString::Format( MIRSRC( IDS_MI_INIT_ERR_DRIVER ), errMsg.c_str() ); SetErrorDescription( msg ); return MIstatus::failure; } m_eCurrentDriverState = eDriverState_RunningNotDebugging; return bOk; }
//++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdStackListLocals::Execute() { 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: Initialize resources for *this debugger object. // Type: Method. // Args: None. // Return: MIstatus::success - Functionality succeeded. // MIstatus::failure - Functionality failed. // Throws: None. //-- bool CMICmnLLDBDebugger::Initialize() { m_clientUsageRefCnt++; if (m_bInitialized) return MIstatus::success; bool bOk = MIstatus::success; CMIUtilString errMsg; ClrErrorDescription(); if (m_pClientDriver == nullptr) { bOk = false; errMsg = MIRSRC(IDS_LLDBDEBUGGER_ERR_CLIENTDRIVER); } // Note initialization order is important here as some resources depend on previous MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg); MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg); MI::ModuleInit<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMGR, bOk, errMsg); MI::ModuleInit<CMICmnLLDBDebuggerHandleEvents>(IDS_MI_INIT_ERR_OUTOFBANDHANDLER, bOk, errMsg); MI::ModuleInit<CMICmnLLDBDebugSessionInfo>(IDS_MI_INIT_ERR_DEBUGSESSIONINFO, bOk, errMsg); // Note order is important here! if (bOk) lldb::SBDebugger::Initialize(); if (bOk && !InitSBDebugger()) { bOk = false; if (!errMsg.empty()) errMsg += ", "; errMsg += GetErrorDescription().c_str(); } if (bOk && !InitSBListener()) { bOk = false; if (!errMsg.empty()) errMsg += ", "; errMsg += GetErrorDescription().c_str(); } bOk = bOk && InitStdStreams(); bOk = bOk && RegisterMISummaryProviders(); m_bInitialized = bOk; if (!bOk && !HaveErrorDescription()) { CMIUtilString strInitError(CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_LLDBDEBUGGER), errMsg.c_str())); SetErrorDescription(strInitError); } return bOk; }
//++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // 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; }
//++ ------------------------------------------------------------------------------------ // Details: Interpret the text data and match against current commands to see if there // is a match. If a match then the command is issued and actioned on. If a // command cannot be found to match then vwbCmdYesValid is set to false and // nothing else is done here. // This function is used by the application's main thread. // Type: Method. // Args: vTextLine - (R) Text data representing a possible command. // vwbCmdYesValid - (W) True = Command valid, false = command not handled. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMIDriver::InterpretCommandThisDriver(const CMIUtilString &vTextLine, bool &vwbCmdYesValid) { // Convert any CLI commands into MI commands const CMIUtilString vMITextLine(WrapCLICommandIntoMICommand(vTextLine)); vwbCmdYesValid = false; bool bCmdNotInCmdFactor = false; SMICmdData cmdData; CMICmdMgr &rCmdMgr = CMICmdMgr::Instance(); if (!rCmdMgr.CmdInterpret(vMITextLine, vwbCmdYesValid, bCmdNotInCmdFactor, cmdData)) return MIstatus::failure; if (vwbCmdYesValid) { // For debugging only // m_pLog->WriteLog( cmdData.strMiCmdAll.c_str() ); return ExecuteCommand(cmdData); } // Check for escape character, may be cursor control characters // This code is not necessary for application operation, just want to keep tabs on what // has been given to the driver to try and interpret. if (vMITextLine.at(0) == 27) { CMIUtilString logInput(MIRSRC(IDS_STDIN_INPUT_CTRL_CHARS)); for (MIuint i = 0; i < vMITextLine.length(); i++) { logInput += CMIUtilString::Format("%d ", vMITextLine.at(i)); } m_pLog->WriteLog(logInput); return MIstatus::success; } // Write to the Log that a 'command' was not valid. // Report back to the MI client via MI result record. CMIUtilString strNotInCmdFactory; if (bCmdNotInCmdFactor) strNotInCmdFactory = CMIUtilString::Format(MIRSRC(IDS_DRIVER_CMD_NOT_IN_FACTORY), cmdData.strMiCmd.c_str()); const CMIUtilString strNot(CMIUtilString::Format("%s ", MIRSRC(IDS_WORD_NOT))); const CMIUtilString msg( CMIUtilString::Format(MIRSRC(IDS_DRIVER_CMD_RECEIVED), vMITextLine.c_str(), strNot.c_str(), strNotInCmdFactory.c_str())); const CMICmnMIValueConst vconst = CMICmnMIValueConst(msg); const CMICmnMIValueResult valueResult("msg", vconst); const CMICmnMIResultRecord miResultRecord(cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, valueResult); const bool bOk = m_rStdOut.WriteMIResponse(miResultRecord.GetString()); // Proceed to wait for or execute next command return bOk; }
//++ ------------------------------------------------------------------------------------ // Details: Retrieve if possible the OS last error description. // Type: Method. // Args: None. // Return: CMIUtilString - Error description. // Throws: None. //-- CMIUtilString CMIUtilSystemWindows::GetOSLastError( void ) const { CMIUtilString errorMsg; const DWORD dwLastError = ::GetLastError(); if( dwLastError != 0 ) { if( !GetOSErrorMsg( dwLastError, errorMsg ) ) errorMsg = MIRSRC( IDE_OS_ERR_RETRIEVING ); } else errorMsg = MIRSRC( IDE_OS_ERR_UNKNOWN ); return errorMsg; }
//++ ------------------------------------------------------------------------------------ // Details: Release resources for *this Command Manager. // Type: Method. // Args: None. // Return: MIstatus::success - Functionality succeeded. // MIstatus::failure - Functionality failed. // Throws: None. //-- bool CMICmdMgr::Shutdown(void) { if (--m_clientUsageRefCnt > 0) return MIstatus::success; if (!m_bInitialized) return MIstatus::success; m_bInitialized = false; ClrErrorDescription(); bool bOk = MIstatus::success; CMIUtilString errMsg; // Tidy up m_setCmdDeleteCallback.clear(); // Note shutdown order is important here if (!m_invoker.Shutdown()) { bOk = false; errMsg += CMIUtilString::Format(MIRSRC(IDS_MI_SHTDWN_ERR_CMDINVOKER), m_invoker.GetErrorDescription().c_str()); } if (!m_factory.Shutdown()) { bOk = false; if (!errMsg.empty()) errMsg += ", "; errMsg += CMIUtilString::Format(MIRSRC(IDS_MI_SHTDWN_ERR_CMDFACTORY), m_factory.GetErrorDescription().c_str()); } if (!m_interpretor.Shutdown()) { bOk = false; if (!errMsg.empty()) errMsg += ", "; errMsg += CMIUtilString::Format(MIRSRC(IDS_MI_SHTDWN_ERR_CMDINTERPRETER), m_interpretor.GetErrorDescription().c_str()); } MI::ModuleShutdown<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg); MI::ModuleShutdown<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg); if (!bOk) { SetErrorDescriptionn(MIRSRC(IDS_MI_SHUTDOWN_ERR), errMsg.c_str()); } return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: Initialize resources for *this Stdin stream. // Type: Method. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnStreamStdin::Initialize(void) { m_clientUsageRefCnt++; if (m_bInitialized) return MIstatus::success; bool bOk = MIstatus::success; CMIUtilString errMsg; // Note initialisation order is important here as some resources depend on previous MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg); MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg); MI::ModuleInit<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMGR, bOk, errMsg); #ifdef _MSC_VER MI::ModuleInit<CMICmnStreamStdinWindows>(IDS_MI_INIT_ERR_OS_STDIN_HANDLER, bOk, errMsg); bOk = bOk && SetOSStdinHandler(CMICmnStreamStdinWindows::Instance()); #else MI::ModuleInit<CMICmnStreamStdinLinux>(IDS_MI_INIT_ERR_OS_STDIN_HANDLER, bOk, errMsg); bOk = bOk && SetOSStdinHandler(CMICmnStreamStdinLinux::Instance()); #endif // ( _MSC_VER ) // The OS specific stdin stream handler must be set before *this class initialises if (bOk && m_pStdinReadHandler == nullptr) { CMIUtilString strInitError(CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_STREAMSTDIN_OSHANDLER), errMsg.c_str())); SetErrorDescription(strInitError); return MIstatus::failure; } // Other resources required if (bOk) { m_bKeyCtrlCHit = false; // Reset } m_bInitialized = bOk; if (!bOk) { CMIUtilString strInitError(CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_STREAMSTDIN), errMsg.c_str())); SetErrorDescription(strInitError); return MIstatus::failure; } return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: The callee client uses this function to write to the Logger. The data to be // written is given out to all the mediums registered. The verbosity type parameter // indicates to the medium(s) the type of data or message given to it. The medium has // modes of verbosity and depending on the verbosity set determines which writes // go in to the logger. // The logger must be initialized successfully before a write to any registered // can be carried out. // Type: Method. // Args: vData - (R) The data to write to the logger. // veType - (R) Verbosity type. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLog::Write(const CMIUtilString &vData, const ELogVerbosity veType) { if (!m_bInitialized && !m_bInitializingATM) return MIstatus::success; if (m_bRecursiveDive) return MIstatus::success; if (!m_bEnabled) return MIstatus::success; m_bRecursiveDive = true; MIuint cnt = 0; MIuint cntErr = 0; { MapMediumToName_t::const_iterator it = m_mapMediumToName.begin(); while (it != m_mapMediumToName.end()) { IMedium *pMedium = (*it).first; const CMIUtilString &rNameMedium = (*it).second; MIunused(rNameMedium); if (pMedium->Write(vData, veType)) cnt++; else cntErr++; // Next ++it; } } bool bOk = MIstatus::success; const MIuint mediumCnt = m_mapMediumToName.size(); if ((cnt == 0) && (mediumCnt > 0)) { SetErrorDescription(MIRSRC(IDS_LOG_MEDIUM_ERR_WRITE_ANY)); bOk = MIstatus::failure; } if (bOk && (cntErr != 0)) { SetErrorDescription(MIRSRC(IDS_LOG_MEDIUM_ERR_WRITE_MEDIUMFAIL)); bOk = MIstatus::failure; } m_bRecursiveDive = false; return bOk; }
//++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecContinue::Execute() { const char *pCmd = "continue"; CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); const lldb::ReturnStatus rtn = rSessionInfo.GetDebugger().GetCommandInterpreter().HandleCommand(pCmd, m_lldbResult); MIunused(rtn); if (m_lldbResult.GetErrorSize() == 0) { // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM 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; } } else { // ToDo: Re-evaluate if this is required when application near finished as this is parsing LLDB error message // which seems a hack and is code brittle const char *pLldbErr = m_lldbResult.GetError(); const CMIUtilString strLldbMsg(CMIUtilString(pLldbErr).StripCREndOfLine()); if (strLldbMsg == "error: Process must be launched.") { CMIDriver::Instance().SetExitApplicationFlag(true); } } return MIstatus::success; }