1 //===-- MICmdCmdStack.cpp ---------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 // File: MICmdCmdStack.cpp
13 // Overview: CMICmdCmdStackInfoDepth implementation.
14 // CMICmdCmdStackListFrames implementation.
15 // CMICmdCmdStackListArguments implementation.
16 // CMICmdCmdStackListLocals implementation.
18 // Environment: Compilers: Visual C++ 12.
19 // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
20 // Libraries: See MIReadmetxt.
25 // Third Party Headers:
26 #include <lldb/API/SBThread.h>
29 #include "MICmdCmdStack.h"
30 #include "MICmnMIResultRecord.h"
31 #include "MICmnMIValueConst.h"
32 #include "MICmnMIOutOfBandRecord.h"
33 #include "MICmnLLDBDebugger.h"
34 #include "MICmnLLDBDebugSessionInfo.h"
35 #include "MICmdArgValNumber.h"
36 #include "MICmdArgValString.h"
37 #include "MICmdArgValThreadGrp.h"
38 #include "MICmdArgValOptionLong.h"
39 #include "MICmdArgValOptionShort.h"
40 #include "MICmdArgValListOfN.h"
42 //++ ------------------------------------------------------------------------------------
43 // Details: CMICmdCmdStackInfoDepth constructor.
49 CMICmdCmdStackInfoDepth::CMICmdCmdStackInfoDepth( void )
50 : m_nThreadFrames( 0 )
51 , m_constStrArgThread( "thread" )
52 , m_constStrArgMaxDepth( "max-depth" )
54 // Command factory matches this name with that received from the stdin stream
55 m_strMiCmd = "stack-info-depth";
57 // Required by the CMICmdFactory when registering *this command
58 m_pSelfCreatorFn = &CMICmdCmdStackInfoDepth::CreateSelf;
61 //++ ------------------------------------------------------------------------------------
62 // Details: CMICmdCmdStackInfoDepth destructor.
63 // Type: Overrideable.
68 CMICmdCmdStackInfoDepth::~CMICmdCmdStackInfoDepth( void )
72 //++ ------------------------------------------------------------------------------------
73 // Details: The invoker requires this function. The parses the command line options
74 // arguments to extract values for each of those arguments.
77 // Return: MIstatus::success - Functional succeeded.
78 // MIstatus::failure - Functional failed.
81 bool CMICmdCmdStackInfoDepth::ParseArgs( void )
83 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
84 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgMaxDepth, false, false ) ) );
85 return (bOk && ParseValidateCmdOptions() );
88 //++ ------------------------------------------------------------------------------------
89 // Details: The invoker requires this function. The command does work in this function.
90 // The command is likely to communicate with the LLDB SBDebugger in here.
93 // Return: MIstatus::success - Functional succeeded.
94 // MIstatus::failure - Functional failed.
97 bool CMICmdCmdStackInfoDepth::Execute( void )
99 CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread );
100 CMICMDBASE_GETOPTION( pArgMaxDepth, Number, m_constStrArgMaxDepth );
102 // Retrieve the --thread option's thread ID (only 1)
103 MIuint64 nThreadId = UINT64_MAX;
104 if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
106 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
107 return MIstatus::failure;
110 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
111 lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
112 lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID( nThreadId ) : rProcess.GetSelectedThread();
113 m_nThreadFrames = thread.GetNumFrames();
115 return MIstatus::success;
118 //++ ------------------------------------------------------------------------------------
119 // Details: The invoker requires this function. The command prepares a MI Record Result
120 // for the work carried out in the Execute().
123 // Return: MIstatus::success - Functional succeeded.
124 // MIstatus::failure - Functional failed.
127 bool CMICmdCmdStackInfoDepth::Acknowledge( void )
129 const CMIUtilString strDepth( CMIUtilString::Format( "%d", m_nThreadFrames ) );
130 const CMICmnMIValueConst miValueConst( strDepth );
131 const CMICmnMIValueResult miValueResult( "depth", miValueConst );
132 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
133 m_miResultRecord = miRecordResult;
135 return MIstatus::success;
138 //++ ------------------------------------------------------------------------------------
139 // Details: Required by the CMICmdFactory when registering *this command. The factory
140 // calls this function to create an instance of *this command.
141 // Type: Static method.
143 // Return: CMICmdBase * - Pointer to a new command.
146 CMICmdBase * CMICmdCmdStackInfoDepth::CreateSelf( void )
148 return new CMICmdCmdStackInfoDepth();
151 //---------------------------------------------------------------------------------------
152 //---------------------------------------------------------------------------------------
153 //---------------------------------------------------------------------------------------
155 //++ ------------------------------------------------------------------------------------
156 // Details: CMICmdCmdStackListFrames constructor.
162 CMICmdCmdStackListFrames::CMICmdCmdStackListFrames( void )
163 : m_nThreadFrames( 0 )
164 , m_constStrArgThread( "thread" )
165 , m_constStrArgFrameLow( "low-frame" )
166 , m_constStrArgFrameHigh( "high-frame" )
168 // Command factory matches this name with that received from the stdin stream
169 m_strMiCmd = "stack-list-frames";
171 // Required by the CMICmdFactory when registering *this command
172 m_pSelfCreatorFn = &CMICmdCmdStackListFrames::CreateSelf;
175 //++ ------------------------------------------------------------------------------------
176 // Details: CMICmdCmdStackListFrames destructor.
177 // Type: Overrideable.
182 CMICmdCmdStackListFrames::~CMICmdCmdStackListFrames( void )
184 m_vecMIValueResult.clear();
187 //++ ------------------------------------------------------------------------------------
188 // Details: The invoker requires this function. The parses the command line options
189 // arguments to extract values for each of those arguments.
192 // Return: MIstatus::success - Functional succeeded.
193 // MIstatus::failure - Functional failed.
196 bool CMICmdCmdStackListFrames::ParseArgs( void )
198 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
199 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgFrameLow, false, true ) ) );
200 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgFrameHigh, false, true ) ) );
201 return (bOk && ParseValidateCmdOptions() );
204 //++ ------------------------------------------------------------------------------------
205 // Details: The invoker requires this function. The command does work in this function.
206 // The command is likely to communicate with the LLDB SBDebugger in here.
209 // Return: MIstatus::success - Functional succeeded.
210 // MIstatus::failure - Functional failed.
213 bool CMICmdCmdStackListFrames::Execute( void )
215 CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread );
216 CMICMDBASE_GETOPTION( pArgFrameLow, Number, m_constStrArgFrameLow );
217 CMICMDBASE_GETOPTION( pArgFrameHigh, Number, m_constStrArgFrameHigh );
219 // Retrieve the --thread option's thread ID (only 1)
220 MIuint64 nThreadId = UINT64_MAX;
221 if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
223 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
224 return MIstatus::failure;
227 // Frame low and high options are not mandatory
228 MIuint nFrameHigh = pArgFrameHigh->GetFound() ? pArgFrameHigh->GetValue() : UINT64_MAX;
229 const MIuint nFrameLow = pArgFrameLow->GetFound() ? pArgFrameLow->GetValue() : 0;
231 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
232 lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
233 lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID( nThreadId ) : rProcess.GetSelectedThread();
234 MIuint nThreadFrames = thread.GetNumFrames();
236 // Adjust nThreadFrames for the nFrameHigh argument as we use nFrameHigh+1 in the min calc as the arg
237 // is not an index, but a frame id value.
238 if( nFrameHigh < UINT32_MAX )
241 nThreadFrames = (nFrameHigh < nThreadFrames) ? nFrameHigh : nThreadFrames;
244 m_nThreadFrames = nThreadFrames;
245 if( nThreadFrames == 0 )
246 return MIstatus::success;
248 m_vecMIValueResult.clear();
249 for( MIuint nLevel = nFrameLow; nLevel < nThreadFrames; nLevel++ )
251 CMICmnMIValueTuple miValueTuple;
252 if( !rSessionInfo.MIResponseFormFrameInfo( thread, nLevel, miValueTuple ) )
253 return MIstatus::failure;
255 const CMICmnMIValueResult miValueResult8( "frame", miValueTuple );
256 m_vecMIValueResult.push_back( miValueResult8 );
259 return MIstatus::success;
262 //++ ------------------------------------------------------------------------------------
263 // Details: The invoker requires this function. The command prepares a MI Record Result
264 // for the work carried out in the Execute().
267 // Return: MIstatus::success - Functional succeeded.
268 // MIstatus::failure - Functional failed.
271 bool CMICmdCmdStackListFrames::Acknowledge( void )
273 if( m_nThreadFrames == 0 )
275 // MI print "3^done,stack=[{}]"
276 const CMICmnMIValueTuple miValueTuple;
277 const CMICmnMIValueList miValueList( miValueTuple );
278 const CMICmnMIValueResult miValueResult( "stack", miValueList );
279 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
280 m_miResultRecord = miRecordResult;
282 return MIstatus::success;
285 // Build up a list of thread information from tuples
286 VecMIValueResult_t::const_iterator it = m_vecMIValueResult.begin();
287 if( it == m_vecMIValueResult.end() )
289 // MI print "3^done,stack=[{}]"
290 const CMICmnMIValueTuple miValueTuple;
291 const CMICmnMIValueList miValueList( miValueTuple );
292 const CMICmnMIValueResult miValueResult( "stack", miValueList );
293 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
294 m_miResultRecord = miRecordResult;
295 return MIstatus::success;
297 CMICmnMIValueList miValueList( *it );
299 while( it != m_vecMIValueResult.end() )
301 const CMICmnMIValueResult & rTuple( *it );
302 miValueList.Add( rTuple );
307 const CMICmnMIValueResult miValueResult( "stack", miValueList );
308 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
309 m_miResultRecord = miRecordResult;
311 return MIstatus::success;
314 //++ ------------------------------------------------------------------------------------
315 // Details: Required by the CMICmdFactory when registering *this command. The factory
316 // calls this function to create an instance of *this command.
317 // Type: Static method.
319 // Return: CMICmdBase * - Pointer to a new command.
322 CMICmdBase * CMICmdCmdStackListFrames::CreateSelf( void )
324 return new CMICmdCmdStackListFrames();
327 //---------------------------------------------------------------------------------------
328 //---------------------------------------------------------------------------------------
329 //---------------------------------------------------------------------------------------
331 //++ ------------------------------------------------------------------------------------
332 // Details: CMICmdCmdStackListArguments constructor.
338 CMICmdCmdStackListArguments::CMICmdCmdStackListArguments( void )
339 : m_bThreadInvalid( false )
340 , m_miValueList( true )
341 , m_constStrArgThread( "thread" )
342 , m_constStrArgPrintValues( "print-values" )
344 // Command factory matches this name with that received from the stdin stream
345 m_strMiCmd = "stack-list-arguments";
347 // Required by the CMICmdFactory when registering *this command
348 m_pSelfCreatorFn = &CMICmdCmdStackListArguments::CreateSelf;
351 //++ ------------------------------------------------------------------------------------
352 // Details: CMICmdCmdStackListArguments destructor.
353 // Type: Overrideable.
358 CMICmdCmdStackListArguments::~CMICmdCmdStackListArguments( void )
362 //++ ------------------------------------------------------------------------------------
363 // Details: The invoker requires this function. The parses the command line options
364 // arguments to extract values for each of those arguments.
367 // Return: MIstatus::success - Functional succeeded.
368 // MIstatus::failure - Functional failed.
371 bool CMICmdCmdStackListArguments::ParseArgs( void )
373 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
374 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgPrintValues, true, false ) ) );
375 return (bOk && ParseValidateCmdOptions() );
378 //++ ------------------------------------------------------------------------------------
379 // Details: The invoker requires this function. The command does work in this function.
380 // The command is likely to communicate with the LLDB SBDebugger in here.
383 // Return: MIstatus::success - Functional succeeded.
384 // MIstatus::failure - Functional failed.
387 bool CMICmdCmdStackListArguments::Execute( void )
389 CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread );
390 CMICMDBASE_GETOPTION( pArgPrintValues, Number, m_constStrArgPrintValues );
392 // Retrieve the --thread option's thread ID (only 1)
393 MIuint64 nThreadId = UINT64_MAX;
394 if( pArgThread->GetFound() )
396 if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
398 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
399 return MIstatus::failure;
403 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
404 lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
405 lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID( nThreadId ) : rProcess.GetSelectedThread();
406 m_bThreadInvalid = !thread.IsValid();
407 if( m_bThreadInvalid )
408 return MIstatus::success;
410 const lldb::StopReason eStopReason = thread.GetStopReason();
411 if( (eStopReason == lldb::eStopReasonNone) || (eStopReason == lldb::eStopReasonInvalid) )
413 m_bThreadInvalid = true;
414 return MIstatus::success;
418 const MIuint nFrames = thread.GetNumFrames();
419 for( MIuint i = 0; i < nFrames; i++ )
421 lldb::SBFrame frame = thread.GetFrameAtIndex( i );
422 CMICmnMIValueList miValueList( true );
423 const MIuint maskVarTypes = 0x1000;
424 if( !rSessionInfo.MIResponseFormVariableInfo3( frame, maskVarTypes, miValueList ) )
425 return MIstatus::failure;
426 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", i ) );
427 const CMICmnMIValueResult miValueResult( "level", miValueConst );
428 CMICmnMIValueTuple miValueTuple( miValueResult );
429 const CMICmnMIValueResult miValueResult2( "args", miValueList );
430 miValueTuple.Add( miValueResult2 );
431 const CMICmnMIValueResult miValueResult3( "frame", miValueTuple );
432 m_miValueList.Add( miValueResult3 );
435 return MIstatus::success;
438 //++ ------------------------------------------------------------------------------------
439 // Details: The invoker requires this function. The command prepares a MI Record Result
440 // for the work carried out in the Execute().
443 // Return: MIstatus::success - Functional succeeded.
444 // MIstatus::failure - Functional failed.
447 bool CMICmdCmdStackListArguments::Acknowledge( void )
449 if( m_bThreadInvalid )
451 // MI print "%s^done,stack-args=[]"
452 const CMICmnMIValueList miValueList( true );
453 const CMICmnMIValueResult miValueResult( "stack-args", miValueList );
454 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
455 m_miResultRecord = miRecordResult;
456 return MIstatus::success;
459 // MI print "%s^done,stack-args=[frame={level=\"0\",args=[%s]},frame={level=\"1\",args=[%s]}]"
460 const CMICmnMIValueResult miValueResult4( "stack-args", m_miValueList );
461 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult4 );
462 m_miResultRecord = miRecordResult;
464 return MIstatus::success;
467 //++ ------------------------------------------------------------------------------------
468 // Details: Required by the CMICmdFactory when registering *this command. The factory
469 // calls this function to create an instance of *this command.
470 // Type: Static method.
472 // Return: CMICmdBase * - Pointer to a new command.
475 CMICmdBase * CMICmdCmdStackListArguments::CreateSelf( void )
477 return new CMICmdCmdStackListArguments();
480 //---------------------------------------------------------------------------------------
481 //---------------------------------------------------------------------------------------
482 //---------------------------------------------------------------------------------------
484 //++ ------------------------------------------------------------------------------------
485 // Details: CMICmdCmdStackListLocals constructor.
491 CMICmdCmdStackListLocals::CMICmdCmdStackListLocals( void )
492 : m_bThreadInvalid( false )
493 , m_miValueList( true )
494 , m_constStrArgThread( "thread" )
495 , m_constStrArgFrame( "frame" )
496 , m_constStrArgPrintValues( "print-values" )
498 // Command factory matches this name with that received from the stdin stream
499 m_strMiCmd = "stack-list-locals";
501 // Required by the CMICmdFactory when registering *this command
502 m_pSelfCreatorFn = &CMICmdCmdStackListLocals::CreateSelf;
505 //++ ------------------------------------------------------------------------------------
506 // Details: CMICmdCmdStackListLocals destructor.
507 // Type: Overrideable.
512 CMICmdCmdStackListLocals::~CMICmdCmdStackListLocals( void )
516 //++ ------------------------------------------------------------------------------------
517 // Details: The invoker requires this function. The parses the command line options
518 // arguments to extract values for each of those arguments.
521 // Return: MIstatus::success - Functional succeeded.
522 // MIstatus::failure - Functional failed.
525 bool CMICmdCmdStackListLocals::ParseArgs( void )
527 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
528 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgFrame, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
529 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgPrintValues, true, false ) ) );
530 return (bOk && ParseValidateCmdOptions() );
533 //++ ------------------------------------------------------------------------------------
534 // Details: The invoker requires this function. The command does work in this function.
535 // The command is likely to communicate with the LLDB SBDebugger in here.
538 // Return: MIstatus::success - Functional succeeded.
539 // MIstatus::failure - Functional failed.
542 bool CMICmdCmdStackListLocals::Execute( void )
544 CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread );
545 CMICMDBASE_GETOPTION( pArgFrame, OptionLong, m_constStrArgFrame );
547 // Retrieve the --thread option's thread ID (only 1)
548 MIuint64 nThreadId = UINT64_MAX;
549 if( pArgThread->GetFound() )
551 if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
553 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
554 return MIstatus::failure;
557 MIuint64 nFrame = UINT64_MAX;
558 if( pArgFrame->GetFound() )
560 if( !pArgFrame->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nFrame ) )
562 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_OPTION_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_constStrArgFrame.c_str() ) );
563 return MIstatus::failure;
567 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
568 lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
569 lldb::SBThread thread = (nThreadId != UINT64_MAX) ? rProcess.GetThreadByIndexID( nThreadId ) : rProcess.GetSelectedThread();
570 m_bThreadInvalid = !thread.IsValid();
571 if( m_bThreadInvalid )
572 return MIstatus::success;
574 const lldb::StopReason eStopReason = thread.GetStopReason();
575 if( (eStopReason == lldb::eStopReasonNone) || (eStopReason == lldb::eStopReasonInvalid) )
577 m_bThreadInvalid = true;
578 return MIstatus::success;
581 const MIuint nFrames = thread.GetNumFrames(); MIunused( nFrames );
582 lldb::SBFrame frame = (nFrame != UINT64_MAX) ? thread.GetFrameAtIndex( nFrame ) : thread.GetSelectedFrame();
583 CMICmnMIValueList miValueList( true );
584 const MIuint maskVarTypes = 0x0110;
585 if( !rSessionInfo.MIResponseFormVariableInfo( frame, maskVarTypes, miValueList ) )
586 return MIstatus::failure;
588 m_miValueList = miValueList;
590 return MIstatus::success;
593 //++ ------------------------------------------------------------------------------------
594 // Details: The invoker requires this function. The command prepares a MI Record Result
595 // for the work carried out in the Execute().
598 // Return: MIstatus::success - Functional succeeded.
599 // MIstatus::failure - Functional failed.
602 bool CMICmdCmdStackListLocals::Acknowledge( void )
604 if( m_bThreadInvalid )
606 // MI print "%s^done,locals=[]"
607 const CMICmnMIValueList miValueList( true );
608 const CMICmnMIValueResult miValueResult( "locals", miValueList );
609 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
610 m_miResultRecord = miRecordResult;
611 return MIstatus::success;
614 // MI print "%s^done,locals=[%s]"
615 const CMICmnMIValueResult miValueResult( "locals", m_miValueList );
616 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
617 m_miResultRecord = miRecordResult;
619 return MIstatus::success;
622 //++ ------------------------------------------------------------------------------------
623 // Details: Required by the CMICmdFactory when registering *this command. The factory
624 // calls this function to create an instance of *this command.
625 // Type: Static method.
627 // Return: CMICmdBase * - Pointer to a new command.
630 CMICmdBase * CMICmdCmdStackListLocals::CreateSelf( void )
632 return new CMICmdCmdStackListLocals();