//++ ------------------------------------------------------------------------------------ // Details: Form MI partial response by appending more MI value type objects to the // tuple type object past in. // Type: Method. // Args: vrThread - (R) LLDB thread object. // vwrMIValueTuple - (W) MI value tuple object. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo( const lldb::SBThread & vrThread, const MIuint vnLevel, CMICmnMIValueTuple & vwrMiValueTuple ) { lldb::SBThread & rThread = const_cast< lldb::SBThread & >( vrThread ); lldb::SBFrame frame = rThread.GetFrameAtIndex( vnLevel ); lldb::addr_t pc = 0; CMIUtilString fnName; CMIUtilString fileName; CMIUtilString path; MIuint nLine = 0; if( !GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) ) return MIstatus::failure; CMICmnMIValueList miValueList( true ); const MIuint vMaskVarTypes = 0x1000; if( !MIResponseFormVariableInfo( frame, vMaskVarTypes, miValueList ) ) return MIstatus::failure; // MI print "{level=\"0\",addr=\"0x%08llx\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"}" const CMIUtilString strLevel( CMIUtilString::Format( "%d", vnLevel ) ); const CMICmnMIValueConst miValueConst( strLevel ); const CMICmnMIValueResult miValueResult( "level", miValueConst ); CMICmnMIValueTuple miValueTuple( miValueResult ); if( !MIResponseFormFrameInfo( pc, fnName, miValueList.GetString(), fileName, path, nLine, miValueTuple ) ) return MIstatus::failure; vwrMiValueTuple = miValueTuple; return MIstatus::success; }
//++ //------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command prepares a MI Record // Result // for the work carried out in the Execute(). // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdThreadInfo::Acknowledge() { if (m_bSingleThread) { if (m_bThreadInvalid) { const CMICmnMIValueConst miValueConst("invalid thread id"); const CMICmnMIValueResult miValueResult("msg", miValueConst); const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult); m_miResultRecord = miRecordResult; return MIstatus::success; } // MI print // "%s^done,threads=[{id=\"%d\",target-id=\"%s\",frame={},state=\"%s\"}] const CMICmnMIValueList miValueList(m_miValueTupleThread); const CMICmnMIValueResult miValueResult("threads", miValueList); const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult); m_miResultRecord = miRecordResult; return MIstatus::success; } // Build up a list of thread information from tuples VecMIValueTuple_t::const_iterator it = m_vecMIValueTuple.begin(); if (it == m_vecMIValueTuple.end()) { const CMICmnMIValueConst miValueConst("[]"); const CMICmnMIValueResult miValueResult("threads", miValueConst); const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult); m_miResultRecord = miRecordResult; return MIstatus::success; } CMICmnMIValueList miValueList(*it); ++it; while (it != m_vecMIValueTuple.end()) { const CMICmnMIValueTuple &rTuple(*it); miValueList.Add(rTuple); // Next ++it; } CMICmnMIValueResult miValueResult("threads", miValueList); if (m_bHasCurrentThread) { CMIUtilString strCurrThreadId = "current-thread-id"; miValueResult.Add(strCurrThreadId, m_miValueCurrThreadId); } const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult); m_miResultRecord = miRecordResult; return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: Form MI partial response by appending more MI value type objects to the // tuple type object past in. // Type: Method. // Args: vrThread - (R) LLDB thread object. // vwrMIValueTuple - (W) MI value tuple object. // vArgInfo - (R) Args information in MI response form. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo(const lldb::SBThread &vrThread, const MIuint vnLevel, const FrameInfoFormat_e veFrameInfoFormat, CMICmnMIValueTuple &vwrMiValueTuple) { lldb::SBThread &rThread = const_cast<lldb::SBThread &>(vrThread); lldb::SBFrame frame = rThread.GetFrameAtIndex(vnLevel); lldb::addr_t pc = 0; CMIUtilString fnName; CMIUtilString fileName; CMIUtilString path; MIuint nLine = 0; if (!GetFrameInfo(frame, pc, fnName, fileName, path, nLine)) return MIstatus::failure; // MI print "{level=\"0\",addr=\"0x%016" PRIx64 "\",func=\"%s\",file=\"%s\",fullname=\"%s\",line=\"%d\"}" const CMIUtilString strLevel(CMIUtilString::Format("%d", vnLevel)); const CMICmnMIValueConst miValueConst(strLevel); const CMICmnMIValueResult miValueResult("level", miValueConst); vwrMiValueTuple.Add(miValueResult); const CMIUtilString strAddr(CMIUtilString::Format("0x%016" PRIx64, pc)); const CMICmnMIValueConst miValueConst2(strAddr); const CMICmnMIValueResult miValueResult2("addr", miValueConst2); vwrMiValueTuple.Add(miValueResult2); const CMICmnMIValueConst miValueConst3(fnName); const CMICmnMIValueResult miValueResult3("func", miValueConst3); vwrMiValueTuple.Add(miValueResult3); if (veFrameInfoFormat != eFrameInfoFormat_NoArguments) { CMICmnMIValueList miValueList(true); const MIuint maskVarTypes = eVariableType_Arguments; if (veFrameInfoFormat == eFrameInfoFormat_AllArgumentsInSimpleForm) { if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList, 0)) return MIstatus::failure; } else if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList)) return MIstatus::failure; const CMICmnMIValueResult miValueResult4("args", miValueList); vwrMiValueTuple.Add(miValueResult4); } const CMICmnMIValueConst miValueConst5(fileName); const CMICmnMIValueResult miValueResult5("file", miValueConst5); vwrMiValueTuple.Add(miValueResult5); const CMICmnMIValueConst miValueConst6(path); const CMICmnMIValueResult miValueResult6("fullname", miValueConst6); vwrMiValueTuple.Add(miValueResult6); const CMIUtilString strLine(CMIUtilString::Format("%d", nLine)); const CMICmnMIValueConst miValueConst7(strLine); const CMICmnMIValueResult miValueResult7("line", miValueConst7); vwrMiValueTuple.Add(miValueResult7); return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdStackListLocals::Execute() { CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread); CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame); CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues); // Retrieve the --thread option's thread ID (only 1) MIuint64 nThreadId = UINT64_MAX; if (pArgThread->GetFound()) { if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str())); return MIstatus::failure; } } MIuint64 nFrame = UINT64_MAX; if (pArgFrame->GetFound()) { if (!pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame)) { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgFrame.c_str())); return MIstatus::failure; } } const CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(pArgPrintValues->GetValue()); CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); lldb::SBProcess sbProcess = rSessionInfo.GetProcess(); lldb::SBThread thread = (nThreadId != UINT64_MAX) ? sbProcess.GetThreadByIndexID(nThreadId) : sbProcess.GetSelectedThread(); m_bThreadInvalid = !thread.IsValid(); if (m_bThreadInvalid) return MIstatus::success; const lldb::StopReason eStopReason = thread.GetStopReason(); if ((eStopReason == lldb::eStopReasonNone) || (eStopReason == lldb::eStopReasonInvalid)) { m_bThreadInvalid = true; return MIstatus::success; } lldb::SBFrame frame = (nFrame != UINT64_MAX) ? thread.GetFrameAtIndex(nFrame) : thread.GetSelectedFrame(); CMICmnMIValueList miValueList(true); const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Locals; if (!rSessionInfo.MIResponseFormVariableInfo(frame, maskVarTypes, eVarInfoFormat, miValueList)) return MIstatus::failure; m_miValueList = miValueList; return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: Retrieve the specified thread's frame information. // Type: Method. // Args: vCmdData - (R) A command's information. // vThreadIdx - (R) Thread index. // vwrThreadFrames - (W) Frame data. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLLDBDebugSessionInfo::GetThreadFrames( const SMICmdData & vCmdData, const MIuint vThreadIdx, CMICmnMIValueTuple & vwrThreadFrames ) { lldb::SBThread thread = m_lldbProcess.GetThreadByIndexID( vThreadIdx ); const uint32_t nFrames = thread.GetNumFrames(); if( nFrames == 0 ) { vwrThreadFrames = CMICmnMIValueTuple(); return MIstatus::success; } CMICmnMIValueTuple miValueTupleAll; for( MIuint nLevel = 0; nLevel < nFrames; nLevel++ ) { lldb::SBFrame frame = thread.GetFrameAtIndex( nLevel ); lldb::addr_t pc = 0; CMIUtilString fnName; CMIUtilString fileName; CMIUtilString path; MIuint nLine = 0; if( !GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) ) return MIstatus::failure; // Function args CMICmnMIValueList miValueList( true ); const MIuint vMaskVarTypes = 0x1000; if( !MIResponseFormVariableInfo( frame, vMaskVarTypes, miValueList ) ) return MIstatus::failure; const MIchar * pUnknown = "??"; if( fnName != pUnknown ) { std::replace( fnName.begin(), fnName.end(), ')', ' ' ); std::replace( fnName.begin(), fnName.end(), '(', ' ' ); std::replace( fnName.begin(), fnName.end(), '\'', ' ' ); } const CMIUtilString strLevel( CMIUtilString::Format( "%d", nLevel ) ); const CMICmnMIValueConst miValueConst( strLevel ); const CMICmnMIValueResult miValueResult( "level", miValueConst ); miValueTupleAll.Add( miValueResult ); CMICmnMIValueTuple miValueTuple( miValueResult ); if( !MIResponseFormFrameInfo( pc, fnName, miValueList.GetString(), fileName, path, nLine, miValueTuple ) ) return MIstatus::failure; } vwrThreadFrames = miValueTupleAll; return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdStackListArguments::Execute( void ) { CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread ); CMICMDBASE_GETOPTION( pArgPrintValues, Number, m_constStrArgPrintValues ); // Retrieve the --thread option's thread ID (only 1) MIuint64 nThreadId = UINT64_MAX; if( pArgThread->GetFound() ) { if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) ) { SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) ); return MIstatus::failure; } } CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess; lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID( nThreadId ) : rProcess.GetSelectedThread(); m_bThreadInvalid = !thread.IsValid(); if( m_bThreadInvalid ) return MIstatus::success; const lldb::StopReason eStopReason = thread.GetStopReason(); if( (eStopReason == lldb::eStopReasonNone) || (eStopReason == lldb::eStopReasonInvalid) ) { m_bThreadInvalid = true; return MIstatus::success; } const MIuint nFrames = thread.GetNumFrames(); for( MIuint i = 0; i < nFrames; i++ ) { lldb::SBFrame frame = thread.GetFrameAtIndex( i ); CMICmnMIValueList miValueList( true ); const MIuint maskVarTypes = 0x1000; if( !rSessionInfo.MIResponseFormVariableInfo3( frame, maskVarTypes, miValueList ) ) return MIstatus::failure; const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", i ) ); const CMICmnMIValueResult miValueResult( "level", miValueConst ); CMICmnMIValueTuple miValueTuple( miValueResult ); const CMICmnMIValueResult miValueResult2( "args", miValueList ); miValueTuple.Add( miValueResult2 ); const CMICmnMIValueResult miValueResult3( "frame", miValueTuple ); m_miValueList.Add( miValueResult3 ); } return MIstatus::success; }
//++ //------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command prepares a MI Record // Result // for the work carried out in the Execute(). // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdSupportListFeatures::Acknowledge() { // Declare supported features here const CMICmnMIValueConst miValueConst1("data-read-memory-bytes"); const CMICmnMIValueConst miValueConst2("exec-run-start-option"); // Some features may depend on host and/or target, decide what to add below CMICmnMIValueList miValueList(true); miValueList.Add(miValueConst1); miValueList.Add(miValueConst2); const CMICmnMIValueResult miValueResult("features", miValueList); const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult); m_miResultRecord = miRecordResult; return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdStackListLocals::Execute( void ) { CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread ); CMICMDBASE_GETOPTION( pArgPrintValues, Number, m_constStrArgPrintValues ); // Retrieve the --thread option's thread ID (only 1) MIuint64 nThreadId = UINT64_MAX; if( pArgThread->GetFound() ) { if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) ) { SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) ); return MIstatus::failure; } } CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess; lldb::SBThread thread; if( nThreadId == UINT64_MAX ) thread = rProcess.GetSelectedThread(); else thread = rProcess.GetThreadByIndexID( nThreadId ); m_bThreadInvalid = !thread.IsValid(); if( m_bThreadInvalid ) return MIstatus::success; const lldb::StopReason eStopReason = thread.GetStopReason(); if( (eStopReason == lldb::eStopReasonNone) || (eStopReason == lldb::eStopReasonInvalid) ) { m_bThreadInvalid = true; return MIstatus::success; } lldb::SBFrame frame = thread.GetFrameAtIndex( 0 ); CMICmnMIValueList miValueList( true ); const MIuint vMaskVarTypes = 0x0100; if( !rSessionInfo.MIResponseFormVariableInfo( frame, vMaskVarTypes, miValueList ) ) return MIstatus::failure; m_miValueList = miValueList; return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command prepares a MI Record Result // for the work carried out in the Execute(). // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdStackListFrames::Acknowledge(void) { if (m_nThreadFrames == 0) { // MI print "3^done,stack=[{}]" const CMICmnMIValueTuple miValueTuple; const CMICmnMIValueList miValueList(miValueTuple); const CMICmnMIValueResult miValueResult("stack", miValueList); const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult); m_miResultRecord = miRecordResult; return MIstatus::success; } // Build up a list of thread information from tuples VecMIValueResult_t::const_iterator it = m_vecMIValueResult.begin(); if (it == m_vecMIValueResult.end()) { // MI print "3^done,stack=[{}]" const CMICmnMIValueTuple miValueTuple; const CMICmnMIValueList miValueList(miValueTuple); const CMICmnMIValueResult miValueResult("stack", miValueList); const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult); m_miResultRecord = miRecordResult; return MIstatus::success; } CMICmnMIValueList miValueList(*it); ++it; while (it != m_vecMIValueResult.end()) { const CMICmnMIValueResult &rTuple(*it); miValueList.Add(rTuple); // Next ++it; } const CMICmnMIValueResult miValueResult("stack", miValueList); const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult); m_miResultRecord = miRecordResult; return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command prepares a MI Record Result // for the work carried out in the Execute(). // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdListThreadGroups::Acknowledge( void ) { if( m_bHaveArgOption ) { if( m_bHaveArgRecurse ) { const CMICmnMIValueConst miValueConst( MIRSRC( IDS_WORD_NOT_IMPLEMENTED_BRKTS ) ); const CMICmnMIValueResult miValueResult( "msg", miValueConst ); const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult ); m_miResultRecord = miRecordResult; return MIstatus::success; } const CMICmnMIValueConst miValueConst1( "i1" ); const CMICmnMIValueResult miValueResult1( "id", miValueConst1 ); CMICmnMIValueTuple miTuple( miValueResult1 ); const CMICmnMIValueConst miValueConst2( "process" ); const CMICmnMIValueResult miValueResult2( "type", miValueConst2 ); miTuple.Add( miValueResult2 ); CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); const lldb::pid_t pid = rSessionInfo.m_lldbProcess.GetProcessID(); const CMIUtilString strPid( CMIUtilString::Format( "%lld", pid ) ); const CMICmnMIValueConst miValueConst3( strPid ); const CMICmnMIValueResult miValueResult3( "pid", miValueConst3 ); miTuple.Add( miValueResult3 ); const CMICmnMIValueConst miValueConst4( MIRSRC( IDS_WORD_NOT_IMPLEMENTED_BRKTS ) ); const CMICmnMIValueResult miValueResult4( "num_children", miValueConst4 ); miTuple.Add( miValueResult4 ); const CMICmnMIValueConst miValueConst5( MIRSRC( IDS_WORD_NOT_IMPLEMENTED_BRKTS ) ); const CMICmnMIValueResult miValueResult5( "cores", miValueConst5 ); miTuple.Add( miValueResult5 ); const CMICmnMIValueList miValueList( miTuple ); const CMICmnMIValueResult miValueResult6( "groups", miValueList ); const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6 ); m_miResultRecord = miRecordResult; return MIstatus::success; } if( !m_bIsI1 ) { const CMICmnMIValueConst miValueConst1( "i1" ); const CMICmnMIValueResult miValueResult1( "id", miValueConst1 ); CMICmnMIValueTuple miTuple( miValueResult1 ); const CMICmnMIValueConst miValueConst2( "process" ); const CMICmnMIValueResult miValueResult2( "type", miValueConst2 ); miTuple.Add( miValueResult2 ); CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); const lldb::pid_t pid = rSessionInfo.m_lldbProcess.GetProcessID(); const CMIUtilString strPid( CMIUtilString::Format( "%lld", pid ) ); const CMICmnMIValueConst miValueConst3( strPid ); const CMICmnMIValueResult miValueResult3( "pid", miValueConst3 ); miTuple.Add( miValueResult3 ); lldb::SBTarget & rTrgt = rSessionInfo.m_lldbTarget; const MIchar * pDir = rTrgt.GetExecutable().GetDirectory(); const MIchar * pFileName = rTrgt.GetExecutable().GetFilename(); const CMIUtilString strFile( CMIUtilString::Format( "%s/%s", pDir, pFileName ) ); const CMICmnMIValueConst miValueConst4( strFile ); const CMICmnMIValueResult miValueResult4( "executable", miValueConst4 ); miTuple.Add( miValueResult4 ); const CMICmnMIValueList miValueList( miTuple ); const CMICmnMIValueResult miValueResult5( "groups", miValueList ); const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult5 ); m_miResultRecord = miRecordResult; return MIstatus::success; } // Build up a list of thread information from tuples VecMIValueTuple_t::const_iterator it = m_vecMIValueTuple.begin(); if( it == m_vecMIValueTuple.end() ) { const CMICmnMIValueConst miValueConst( "[]" ); const CMICmnMIValueResult miValueResult( "threads", miValueConst ); const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult ); m_miResultRecord = miRecordResult; return MIstatus::success; } CMICmnMIValueList miValueList( *it ); ++it; while( it != m_vecMIValueTuple.end() ) { const CMICmnMIValueTuple & rTuple( *it ); miValueList.Add( rTuple ); // Next ++it; } const CMICmnMIValueResult miValueResult( "threads", miValueList ); const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult ); m_miResultRecord = miRecordResult; return MIstatus::success; }
//++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdStackListArguments::Execute() { CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread); CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues); CMICMDBASE_GETOPTION(pArgFrameLow, Number, m_constStrArgFrameLow); CMICMDBASE_GETOPTION(pArgFrameHigh, Number, m_constStrArgFrameHigh); // Retrieve the --thread option's thread ID (only 1) MIuint64 nThreadId = UINT64_MAX; if (pArgThread->GetFound()) { if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str())); return MIstatus::failure; } } const CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(pArgPrintValues->GetValue()); MIuint nFrameLow = 0; MIuint nFrameHigh = UINT32_MAX; if (pArgFrameLow->GetFound() && pArgFrameHigh->GetFound()) { nFrameLow = pArgFrameLow->GetValue(); nFrameHigh = pArgFrameHigh->GetValue() + 1; } else if (pArgFrameLow->GetFound() || pArgFrameHigh->GetFound()) { // Only low-frame or high-frame was specified but both are required SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_FRAME_RANGE_INVALID), m_cmdData.strMiCmd.c_str())); return MIstatus::failure; } CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); lldb::SBProcess sbProcess = rSessionInfo.GetProcess(); lldb::SBThread thread = (nThreadId != UINT64_MAX) ? sbProcess.GetThreadByIndexID(nThreadId) : sbProcess.GetSelectedThread(); m_bThreadInvalid = !thread.IsValid(); if (m_bThreadInvalid) return MIstatus::success; const lldb::StopReason eStopReason = thread.GetStopReason(); if ((eStopReason == lldb::eStopReasonNone) || (eStopReason == lldb::eStopReasonInvalid)) { m_bThreadInvalid = true; return MIstatus::success; } const MIuint nFrames = thread.GetNumFrames(); if (nFrameLow >= nFrames) { // The low-frame is larger than the actual number of frames SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_FRAME_RANGE_INVALID), m_cmdData.strMiCmd.c_str())); return MIstatus::failure; } nFrameHigh = std::min(nFrameHigh, nFrames); for (MIuint i = nFrameLow; i < nFrameHigh; i++) { lldb::SBFrame frame = thread.GetFrameAtIndex(i); CMICmnMIValueList miValueList(true); const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Arguments; if (!rSessionInfo.MIResponseFormVariableInfo(frame, maskVarTypes, eVarInfoFormat, miValueList)) return MIstatus::failure; const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", i)); const CMICmnMIValueResult miValueResult("level", miValueConst); CMICmnMIValueTuple miValueTuple(miValueResult); const CMICmnMIValueResult miValueResult2("args", miValueList); miValueTuple.Add(miValueResult2); const CMICmnMIValueResult miValueResult3("frame", miValueTuple); m_miValueList.Add(miValueResult3); } return MIstatus::success; }