//++ ------------------------------------------------------------------------------------
// 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;
}
Exemple #2
0
//++ ------------------------------------------------------------------------------------
// 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 CMICmdCmdStackListArguments::Acknowledge( void )
{
	if( m_bThreadInvalid )
	{
		// MI print "%s^done,stack-args=[]"
		const CMICmnMIValueList miValueList( true );
		const CMICmnMIValueResult miValueResult( "stack-args", miValueList );
		const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
		m_miResultRecord = miRecordResult;
		return MIstatus::success;
	}

	// MI print "%s^done,stack-args=[frame={level=\"0\",args=[%s]}]"
	const CMICmnMIValueConst miValueConst( "0" );
	const CMICmnMIValueResult miValueResult( "level", miValueConst );
	CMICmnMIValueTuple miValueTuple( miValueResult );
	const CMICmnMIValueResult miValueResult2( "args", m_miValueList );
	miValueTuple.Add( miValueResult2 );
	const CMICmnMIValueResult miValueResult3( "frame", miValueTuple );
	const CMICmnMIValueList miValueList( miValueResult3 );
	const CMICmnMIValueResult miValueResult4( "stack-args", miValueList );
	const CMICmnMIResultRecord miRecordResult( m_cmdData.nMiCmdNumber, CMICmnMIResultRecord::eResultClass_Done, miValueResult4 );
	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:	vrFrame			- (R)	LLDB thread object.
//			vMaskVarTypes	- (R)	0x1000 = arguments, 
//									0x0100 = locals,
//									0x0010 = statics,
//									0x0001 = in scope only.
//			vwrMIValueList	- (W)	MI value list object.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo( const lldb::SBFrame & vrFrame, const MIuint vMaskVarTypes, CMICmnMIValueList & vwrMiValueList )
{
	bool bOk = MIstatus::success;
	lldb::SBFrame & rFrame = const_cast< lldb::SBFrame & >( vrFrame );
	
	const bool bArg = (vMaskVarTypes & 0x1000);
	const bool bLocals = (vMaskVarTypes & 0x0100);
	const bool bStatics = (vMaskVarTypes & 0x0010);
	const bool bInScopeOnly = (vMaskVarTypes & 0x0001);
	const MIchar * pUnkwn = "??";
	lldb::SBValueList listArg = rFrame.GetVariables( bArg, bLocals, bStatics, bInScopeOnly );
	const MIuint nArgs = listArg.GetSize();
	for( MIuint i = 0; bOk && (i < nArgs); i++ )
	{
		lldb::SBValue val = listArg.GetValueAtIndex( i );
		const char * pValue = val.GetValue();
		pValue = (pValue != nullptr) ? pValue : pUnkwn;
		const char * pName = val.GetName();
		pName = (pName != nullptr) ? pName : pUnkwn;
		const CMICmnMIValueConst miValueConst( pName );
		const CMICmnMIValueResult miValueResult( "name", miValueConst );
		CMICmnMIValueTuple miValueTuple( miValueResult );
		const CMICmnMIValueConst miValueConst2( pValue );
		const CMICmnMIValueResult miValueResult2( "value", miValueConst2 );
		miValueTuple.Add( miValueResult2 );
		bOk = vwrMiValueList.Add( miValueTuple );
	}

	return bOk;
}
Exemple #4
0
//++ ------------------------------------------------------------------------------------
// 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 CMICmdCmdBreakEnable::Acknowledge( void )
{
	if( m_bBrkPtEnabledOk )
	{
		const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", m_nBrkPtId ) );
		const CMICmnMIValueResult miValueResult( "number", miValueConst );
		CMICmnMIValueTuple miValueTuple( miValueResult );
		const CMICmnMIValueConst miValueConst2( "y" );
		const CMICmnMIValueResult miValueResult2( "enabled", miValueConst2 );
		bool bOk = miValueTuple.Add( miValueResult2 );
		const CMICmnMIValueResult miValueResult3( "bkpt", miValueTuple );
		const CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3 );
		bOk = bOk && CMICmnStreamStdout::TextToStdout( miOutOfBandRecord.GetString() );
		
		const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
		m_miResultRecord = miRecordResult;
		return bOk;
	}

	const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
	const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), strBrkPtId.c_str() ) );
	const CMICmnMIValueResult miValueResult( "msg", miValueConst );
	const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
	m_miResultRecord = miRecordResult;

	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;
}
Exemple #6
0
//++ ------------------------------------------------------------------------------------
// Details:	The invoker requires this function. The command does work in this function.
//			The command is likely to communicate with the LLDB SBDebugger in here.
// 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:	Form MI partial response by appending more MI value type objects to the 
//			tuple type object past in.
// Type:	Method.
// Args:	vId							- (R) Break point ID.
//			vStrType					- (R) Break point type. 
//			vbDisp						- (R) True = "del", false = "keep".
//			vbEnabled					- (R) True = enabled, false = disabled break point.
//			vPc							- (R) Address number.
//			vFnName						- (R) Function name.
//			vFileName					- (R) File name text.
//			vPath						- (R) Full file name and path text.
//			vnLine						- (R) File line number.
//			vbHaveArgOptionThreadGrp	- (R) True = include MI field, false = do not include "thread-groups".
//			vStrOptThrdGrp				- (R) Thread group number.
//			vnTimes						- (R) The count of the breakpoint existence.
//			vStrOrigLoc					- (R) The name of the break point.
//			vwrMIValueTuple	- (W) MI value tuple object.
// Return:	MIstatus::success - Functional succeeded.
//			MIstatus::failure - Functional failed.
// Throws:	None.
//--
bool CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtInfo( const lldb::break_id_t vId, const CMIUtilString & vStrType, const bool vbDisp, const bool vbEnabled, const lldb::addr_t vPc, const CMIUtilString & vFnName, const CMIUtilString & vFileName, const CMIUtilString & vPath, const MIuint vnLine, const bool vbHaveArgOptionThreadGrp, const CMIUtilString & vStrOptThrdGrp, const MIuint & vnTimes, const CMIUtilString & vStrOrigLoc, CMICmnMIValueTuple & vwrMiValueTuple )
{
	// MI print "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%08x\", func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
	
	// "number="
	const CMIUtilString strN = CMIUtilString::Format( "%d", vId );
	const CMICmnMIValueConst miValueConst( strN );
	const CMICmnMIValueResult miValueResult( "number", miValueConst );
	CMICmnMIValueTuple miValueTuple( miValueResult );
	// "type="
	const CMICmnMIValueConst miValueConst2( vStrType );
	const CMICmnMIValueResult miValueResult2( "type", miValueConst2 );
	bool bOk = miValueTuple.Add( miValueResult2 );
	// "disp="
	const CMICmnMIValueConst miValueConst3( vbDisp ? "del" : "keep" );
	const CMICmnMIValueResult miValueResult3( "disp", miValueConst3 );
	bOk = bOk && miValueTuple.Add( miValueResult3 );
	// "enabled="
	const CMICmnMIValueConst miValueConst4( vbEnabled ? "y" : "n" );
	const CMICmnMIValueResult miValueResult4( "enabled", miValueConst4 );
	bOk = bOk && miValueTuple.Add( miValueResult4 );
	// "addr="
	// "func="
	// "file="
	// "fullname="
	// "line="
	bOk = bOk && CMICmnLLDBDebugSessionInfo::Instance().MIResponseFormBrkPtFrameInfo( vPc, vFnName, vFileName, vPath, vnLine, miValueTuple );
	if( vbHaveArgOptionThreadGrp )
	{
		const CMICmnMIValueConst miValueConst( vStrOptThrdGrp );
		const CMICmnMIValueList miValueList( miValueConst );
		const CMICmnMIValueResult miValueResult( "thread-groups", miValueList );
		bOk = bOk && miValueTuple.Add( miValueResult );
	}
	// "times="
	const CMIUtilString strN4 = CMIUtilString::Format( "%d", vnTimes );
	const CMICmnMIValueConst miValueConstB( strN4 );
	const CMICmnMIValueResult miValueResultB( "times", miValueConstB );
	bOk = bOk && miValueTuple.Add( miValueResultB );
	// "original-location="
	const CMICmnMIValueConst miValueConstC( vStrOrigLoc );
	const CMICmnMIValueResult miValueResultC( "original-location", miValueConstC );
	bOk = bOk && miValueTuple.Add( miValueResultC );

	vwrMiValueTuple = miValueTuple;

	return MIstatus::success;
}
Exemple #8
0
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command does work in this function.
//          The command is likely to communicate with the LLDB SBDebugger in here.
// Type:    Overridden.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
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;
}
//++ ------------------------------------------------------------------------------------
// Details: Form MI partial response by appending more MI value type objects to the
//          tuple type object past in.
// Type:    Method.
// Args:    vrBrkPtInfo     - (R) Break point information object.
//          vwrMIValueTuple - (W) MI value tuple object.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtInfo(const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple)
{
    // MI print "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016" PRIx64 "\",
    // func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"

    // "number="
    const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", vrBrkPtInfo.m_id));
    const CMICmnMIValueResult miValueResult("number", miValueConst);
    CMICmnMIValueTuple miValueTuple(miValueResult);
    // "type="
    const CMICmnMIValueConst miValueConst2(vrBrkPtInfo.m_strType);
    const CMICmnMIValueResult miValueResult2("type", miValueConst2);
    miValueTuple.Add(miValueResult2);
    // "disp="
    const CMICmnMIValueConst miValueConst3(vrBrkPtInfo.m_bDisp ? "del" : "keep");
    const CMICmnMIValueResult miValueResult3("disp", miValueConst3);
    miValueTuple.Add(miValueResult3);
    // "enabled="
    const CMICmnMIValueConst miValueConst4(vrBrkPtInfo.m_bEnabled ? "y" : "n");
    const CMICmnMIValueResult miValueResult4("enabled", miValueConst4);
    miValueTuple.Add(miValueResult4);
    // "addr="
    // "func="
    // "file="
    // "fullname="
    // "line="
    MIResponseFormBrkPtFrameInfo(vrBrkPtInfo, miValueTuple);
    // "pending="
    if (vrBrkPtInfo.m_bPending)
    {
        const CMICmnMIValueConst miValueConst(vrBrkPtInfo.m_strOrigLoc);
        const CMICmnMIValueList miValueList(miValueConst);
        const CMICmnMIValueResult miValueResult("pending", miValueList);
        miValueTuple.Add(miValueResult);
    }
    if (vrBrkPtInfo.m_bHaveArgOptionThreadGrp)
    {
        const CMICmnMIValueConst miValueConst(vrBrkPtInfo.m_strOptThrdGrp);
        const CMICmnMIValueList miValueList(miValueConst);
        const CMICmnMIValueResult miValueResult("thread-groups", miValueList);
        miValueTuple.Add(miValueResult);
    }
    // "times="
    const CMICmnMIValueConst miValueConstB(CMIUtilString::Format("%d", vrBrkPtInfo.m_nTimes));
    const CMICmnMIValueResult miValueResultB("times", miValueConstB);
    miValueTuple.Add(miValueResultB);
    // "thread="
    if (vrBrkPtInfo.m_bBrkPtThreadId)
    {
        const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", vrBrkPtInfo.m_nBrkPtThreadId));
        const CMICmnMIValueResult miValueResult("thread", miValueConst);
        miValueTuple.Add(miValueResult);
    }
    // "cond="
    if (vrBrkPtInfo.m_bCondition)
    {
        const CMICmnMIValueConst miValueConst(vrBrkPtInfo.m_strCondition);
        const CMICmnMIValueResult miValueResult("cond", miValueConst);
        miValueTuple.Add(miValueResult);
    }
    // "ignore="
    if (vrBrkPtInfo.m_nIgnore != 0)
    {
        const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", vrBrkPtInfo.m_nIgnore));
        const CMICmnMIValueResult miValueResult("ignore", miValueConst);
        miValueTuple.Add(miValueResult);
    }
    // "original-location="
    const CMICmnMIValueConst miValueConstC(vrBrkPtInfo.m_strOrigLoc);
    const CMICmnMIValueResult miValueResultC("original-location", miValueConstC);
    miValueTuple.Add(miValueResultC);

    vwrMiValueTuple = miValueTuple;

    return MIstatus::success;
}