//++ ------------------------------------------------------------------------------------ // Details: Parse the command's argument options string and try to extract the value *this // argument is looking for. // Type: Overridden. // Args: vwArgContext - (R) The command's argument options string. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdArgValConsume::Validate(CMICmdArgContext &vwArgContext) { if (vwArgContext.IsEmpty()) return MIstatus::success; // Consume the optional file, line, linenum arguments till the mode '--' argument const CMIUtilString::VecString_t vecOptions(vwArgContext.GetArgs()); CMIUtilString::VecString_t::const_iterator it = vecOptions.begin(); while (it != vecOptions.end()) { const CMIUtilString & rTxt( *it ); if ( rTxt.compare( "--" ) == 0 ) { m_bFound = true; m_bValid = true; return MIstatus::success; } if ( !vwArgContext.RemoveArg( rTxt ) ) return MIstatus::failure; // Next ++it; } return MIstatus::failure; }
//++ ------------------------------------------------------------------------------------ // Details: Examine the string and determine if it is a valid string type argument. // Type: Method. // Args: vrTxt - (R) Some text. // Return: bool - True = yes valid arg, false = no. // Throws: None. //-- bool CMICmdArgValListOfN::IsListOfN(const CMIUtilString &vrTxt) const { CMIUtilString::VecString_t vecOptions; if ((m_eArgType == eArgValType_StringQuoted) || (m_eArgType == eArgValType_StringQuotedNumber) || (m_eArgType == eArgValType_StringQuotedNumberPath) || (m_eArgType == eArgValType_StringAnything)) { if (vrTxt.SplitConsiderQuotes(" ", vecOptions) == 0) return false; } else if (vrTxt.Split(" ", vecOptions) == 0) return false; CMIUtilString::VecString_t::const_iterator it = vecOptions.begin(); while (it != vecOptions.end()) { const CMIUtilString &rOption = *it; if (!IsExpectedCorrectType(rOption, m_eArgType)) break; // Next ++it; } return true; }
//++ //------------------------------------------------------------------------------------ // 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: Create list of argument objects each holding a value extract from the command // options line. // Type: Method. // Args: vrTxt - (R) Some options text. // Return: bool - True = yes valid arg, false = no. // Throws: None. //-- bool CMICmdArgValListOfN::CreateList(const CMIUtilString &vrTxt) { CMIUtilString::VecString_t vecOptions; if ((m_eArgType == eArgValType_StringQuoted) || (m_eArgType == eArgValType_StringQuotedNumber) || (m_eArgType == eArgValType_StringQuotedNumberPath) || (m_eArgType == eArgValType_StringAnything)) { if (vrTxt.SplitConsiderQuotes(" ", vecOptions) == 0) return MIstatus::failure; } else if (vrTxt.Split(" ", vecOptions) == 0) return MIstatus::failure; CMIUtilString::VecString_t::const_iterator it = vecOptions.begin(); while (it != vecOptions.end()) { const CMIUtilString &rOption = *it; CMICmdArgValBase *pOption = CreationObj(rOption, m_eArgType); if (pOption != nullptr) m_argValue.push_back(pOption); else return MIstatus::failure; // Next ++it; } return MIstatus::success; }
//++ // Details: Parse the command's argument options string and try to extract the // long // argument *this argument type is looking for. // Type: Overridden. // Args: vwArgContext - (RW) The command's argument options string. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdArgValOptionLong::Validate(CMICmdArgContext &vwArgContext) { if (vwArgContext.IsEmpty()) return m_bMandatory ? MIstatus::failure : MIstatus::success; if (vwArgContext.GetNumberArgsPresent() == 1) { const CMIUtilString &rArg(vwArgContext.GetArgsLeftToParse()); if (IsArgLongOption(rArg) && ArgNameMatch(rArg)) { m_bFound = true; if (!vwArgContext.RemoveArg(rArg)) return MIstatus::failure; if (m_nExpectingNOptions == 0) { m_bValid = true; return MIstatus::success; } m_bIsMissingOptions = true; return MIstatus::failure; } else return MIstatus::failure; } // More than one option... MIuint nArgIndex = 0; const CMIUtilString::VecString_t vecOptions(vwArgContext.GetArgs()); CMIUtilString::VecString_t::const_iterator it = vecOptions.begin(); while (it != vecOptions.end()) { const CMIUtilString &rArg(*it); if (IsArgOptionCorrect(rArg) && ArgNameMatch(rArg)) { m_bFound = true; if (!vwArgContext.RemoveArg(rArg)) return MIstatus::failure; if (m_nExpectingNOptions != 0) { if (ExtractExpectedOptions(vwArgContext, nArgIndex)) { m_bValid = true; return MIstatus::success; } m_bIsMissingOptions = true; return MIstatus::failure; } else { m_bValid = true; return MIstatus::success; } } // Next ++it; ++nArgIndex; } return MIstatus::failure; }
//++ ------------------------------------------------------------------------------------ // 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; MIuint nOptionsPresent = 0; if( (m_eExpectingOptionType != eArgValType_StringQuoted) && (m_eExpectingOptionType != eArgValType_StringQuotedNumber) && (m_eExpectingOptionType != eArgValType_StringQuotedNumberPath) ) nOptionsPresent = vrwTxt.GetArgsLeftToParse().Split( " ", vecOptions ); else nOptionsPresent = vrwTxt.GetArgsLeftToParse().SplitConsiderQuotes( " ", vecOptions ); if( nOptionsPresent == 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; }
//++ ------------------------------------------------------------------------------------ // Details: Parse the command's argument options string and try to extract the value *this // argument is looking for. // Type: Overridden. // Args: vwArgContext - (R) The command's argument options string. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdArgValFile::Validate(CMICmdArgContext &vwArgContext) { if (vwArgContext.IsEmpty()) return m_bMandatory ? MIstatus::failure : MIstatus::success; // The GDB/MI spec suggests there is only parameter if (vwArgContext.GetNumberArgsPresent() == 1) { const CMIUtilString &rFile(vwArgContext.GetArgsLeftToParse()); if (IsFilePath(rFile)) { m_bFound = true; m_bValid = true; m_argValue = rFile.Trim('"'); vwArgContext.RemoveArg(rFile); return MIstatus::success; } else return MIstatus::failure; } // In reality there are more than one option, if so the file option // is the last one (don't handle that here - find the best looking one) const CMIUtilString::VecString_t vecOptions(vwArgContext.GetArgs()); CMIUtilString::VecString_t::const_iterator it = vecOptions.begin(); while (it != vecOptions.end()) { const CMIUtilString &rTxt(*it); if (IsFilePath(rTxt)) { m_bFound = true; if (vwArgContext.RemoveArg(rTxt)) { m_bValid = true; m_argValue = rTxt.Trim('"'); return MIstatus::success; } else return MIstatus::success; } // Next ++it; } return MIstatus::failure; }
//++ ------------------------------------------------------------------------------------ // Details: Parse the command's argument options string and try to extract the value *this // argument is looking for. // Type: Overridden. // Args: vwArgContext - (RW) The command's argument options string. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdArgValThreadGrp::Validate(CMICmdArgContext &vwArgContext) { if (vwArgContext.IsEmpty()) return m_bMandatory ? MIstatus::failure : MIstatus::success; if (vwArgContext.GetNumberArgsPresent() == 1) { const CMIUtilString &rArg(vwArgContext.GetArgsLeftToParse()); if (IsArgThreadGrp(rArg) && ExtractNumber(rArg)) { m_bFound = true; m_bValid = true; m_argValue = GetNumber(); vwArgContext.RemoveArg(rArg); return MIstatus::success; } else return MIstatus::failure; } // More than one option... const CMIUtilString::VecString_t vecOptions(vwArgContext.GetArgs()); CMIUtilString::VecString_t::const_iterator it = vecOptions.begin(); while (it != vecOptions.end()) { const CMIUtilString &rArg(*it); if (IsArgThreadGrp(rArg) && ExtractNumber(rArg)) { m_bFound = true; if (vwArgContext.RemoveArg(rArg)) { m_bValid = true; m_argValue = GetNumber(); return MIstatus::success; } else return MIstatus::failure; } // Next ++it; } return MIstatus::failure; }
//++ ------------------------------------------------------------------------------------ // Details: Parse the command's argument options string and try to extract only the next // word delimited by the next space. // Type: Method. // Args: vrwArgContext - (RW) The command's argument options string. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdArgValString::ValidateSingleText( CMICmdArgContext & vrwArgContext ) { if( vrwArgContext.GetNumberArgsPresent() == 1 ) { const CMIUtilString & rArg( vrwArgContext.GetArgsLeftToParse() ); if( IsStringArg( rArg ) ) { m_bFound = true; m_bValid = true; m_argValue = rArg; vrwArgContext.RemoveArg( rArg ); return MIstatus::success; } else return MIstatus::failure; } // More than one option... const CMIUtilString::VecString_t vecOptions( vrwArgContext.GetArgs() ); CMIUtilString::VecString_t::const_iterator it = vecOptions.begin(); while( it != vecOptions.end() ) { const CMIUtilString & rArg( *it ); if( IsStringArg( rArg ) ) { m_bFound = true; if( vrwArgContext.RemoveArg( rArg ) ) { m_bValid = true; m_argValue = rArg; return MIstatus::success; } else return MIstatus::failure; } // Next ++it; } return MIstatus::failure; }
//++ ------------------------------------------------------------------------------------ // 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; }
//++ ------------------------------------------------------------------------------------ // 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: 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 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; }
//++ //------------------------------------------------------------------------------------ // 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; }
//++ ------------------------------------------------------------------------------------ // 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; }
//++ ------------------------------------------------------------------------------------ // 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; }