]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmdCmdStack.cpp
Update OpenSSL to 1.1.1.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MICmdCmdStack.cpp
1 //===-- MICmdCmdStack.cpp ---------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // Overview:    CMICmdCmdStackInfoDepth         implementation.
11 //              CMICmdCmdStackInfoFrame         implementation.
12 //              CMICmdCmdStackListFrames        implementation.
13 //              CMICmdCmdStackListArguments     implementation.
14 //              CMICmdCmdStackListLocals        implementation.
15 //              CMICmdCmdStackSelectFrame       implementation.
16
17 // Third Party Headers:
18 #include "lldb/API/SBThread.h"
19
20 // In-house headers:
21 #include "MICmdArgValListOfN.h"
22 #include "MICmdArgValNumber.h"
23 #include "MICmdArgValOptionLong.h"
24 #include "MICmdArgValOptionShort.h"
25 #include "MICmdArgValPrintValues.h"
26 #include "MICmdArgValString.h"
27 #include "MICmdArgValThreadGrp.h"
28 #include "MICmdCmdStack.h"
29 #include "MICmnLLDBDebugSessionInfo.h"
30 #include "MICmnLLDBDebugger.h"
31 #include "MICmnMIOutOfBandRecord.h"
32 #include "MICmnMIResultRecord.h"
33 #include "MICmnMIValueConst.h"
34
35 #include <algorithm>
36
37 //++
38 //------------------------------------------------------------------------------------
39 // Details: CMICmdCmdStackInfoDepth constructor.
40 // Type:    Method.
41 // Args:    None.
42 // Return:  None.
43 // Throws:  None.
44 //--
45 CMICmdCmdStackInfoDepth::CMICmdCmdStackInfoDepth()
46     : m_nThreadFrames(0), m_constStrArgMaxDepth("max-depth") {
47   // Command factory matches this name with that received from the stdin stream
48   m_strMiCmd = "stack-info-depth";
49
50   // Required by the CMICmdFactory when registering *this command
51   m_pSelfCreatorFn = &CMICmdCmdStackInfoDepth::CreateSelf;
52 }
53
54 //++
55 //------------------------------------------------------------------------------------
56 // Details: CMICmdCmdStackInfoDepth destructor.
57 // Type:    Overrideable.
58 // Args:    None.
59 // Return:  None.
60 // Throws:  None.
61 //--
62 CMICmdCmdStackInfoDepth::~CMICmdCmdStackInfoDepth() {}
63
64 //++
65 //------------------------------------------------------------------------------------
66 // Details: The invoker requires this function. The parses the command line
67 // options
68 //          arguments to extract values for each of those arguments.
69 // Type:    Overridden.
70 // Args:    None.
71 // Return:  MIstatus::success - Functional succeeded.
72 //          MIstatus::failure - Functional failed.
73 // Throws:  None.
74 //--
75 bool CMICmdCmdStackInfoDepth::ParseArgs() {
76   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgMaxDepth, false, false));
77   return ParseValidateCmdOptions();
78 }
79
80 //++
81 //------------------------------------------------------------------------------------
82 // Details: The invoker requires this function. The command does work in this
83 // function.
84 //          The command is likely to communicate with the LLDB SBDebugger in
85 //          here.
86 // Type:    Overridden.
87 // Args:    None.
88 // Return:  MIstatus::success - Functional succeeded.
89 //          MIstatus::failure - Functional failed.
90 // Throws:  None.
91 //--
92 bool CMICmdCmdStackInfoDepth::Execute() {
93   CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
94   CMICMDBASE_GETOPTION(pArgMaxDepth, Number, m_constStrArgMaxDepth);
95
96   // Retrieve the --thread option's thread ID (only 1)
97   MIuint64 nThreadId = UINT64_MAX;
98   if (pArgThread->GetFound() &&
99       !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
100     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
101                                    m_cmdData.strMiCmd.c_str(),
102                                    m_constStrArgThread.c_str()));
103     return MIstatus::failure;
104   }
105
106   CMICmnLLDBDebugSessionInfo &rSessionInfo(
107       CMICmnLLDBDebugSessionInfo::Instance());
108   lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
109   lldb::SBThread thread = (nThreadId != UINT64_MAX)
110                               ? sbProcess.GetThreadByIndexID(nThreadId)
111                               : sbProcess.GetSelectedThread();
112   m_nThreadFrames = thread.GetNumFrames();
113
114   return MIstatus::success;
115 }
116
117 //++
118 //------------------------------------------------------------------------------------
119 // Details: The invoker requires this function. The command prepares a MI Record
120 // Result
121 //          for the work carried out in the Execute().
122 // Type:    Overridden.
123 // Args:    None.
124 // Return:  MIstatus::success - Functional succeeded.
125 //          MIstatus::failure - Functional failed.
126 // Throws:  None.
127 //--
128 bool CMICmdCmdStackInfoDepth::Acknowledge() {
129   const CMIUtilString strDepth(CMIUtilString::Format("%d", m_nThreadFrames));
130   const CMICmnMIValueConst miValueConst(strDepth);
131   const CMICmnMIValueResult miValueResult("depth", miValueConst);
132   const CMICmnMIResultRecord miRecordResult(
133       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
134       miValueResult);
135   m_miResultRecord = miRecordResult;
136
137   return MIstatus::success;
138 }
139
140 //++
141 //------------------------------------------------------------------------------------
142 // Details: Required by the CMICmdFactory when registering *this command. The
143 // factory
144 //          calls this function to create an instance of *this command.
145 // Type:    Static method.
146 // Args:    None.
147 // Return:  CMICmdBase * - Pointer to a new command.
148 // Throws:  None.
149 //--
150 CMICmdBase *CMICmdCmdStackInfoDepth::CreateSelf() {
151   return new CMICmdCmdStackInfoDepth();
152 }
153
154 //---------------------------------------------------------------------------------------
155 //---------------------------------------------------------------------------------------
156 //---------------------------------------------------------------------------------------
157
158 //++
159 //------------------------------------------------------------------------------------
160 // Details: CMICmdCmdStackInfoFrame constructor.
161 // Type:    Method.
162 // Args:    None.
163 // Return:  None.
164 // Throws:  None.
165 //--
166 CMICmdCmdStackInfoFrame::CMICmdCmdStackInfoFrame() {
167   // Command factory matches this name with that received from the stdin stream
168   m_strMiCmd = "stack-info-frame";
169
170   // Required by the CMICmdFactory when registering *this command
171   m_pSelfCreatorFn = &CMICmdCmdStackInfoFrame::CreateSelf;
172 }
173
174 //++
175 //------------------------------------------------------------------------------------
176 // Details: CMICmdCmdStackInfoFrame destructor.
177 // Type:    Overrideable.
178 // Args:    None.
179 // Return:  None.
180 // Throws:  None.
181 //--
182 CMICmdCmdStackInfoFrame::~CMICmdCmdStackInfoFrame() {}
183
184 //++
185 //------------------------------------------------------------------------------------
186 // Details: The invoker requires this function. The parses the command line
187 // options
188 //          arguments to extract values for each of those arguments.
189 // Type:    Overridden.
190 // Args:    None.
191 // Return:  MIstatus::success - Function succeeded.
192 //          MIstatus::failure - Function failed.
193 // Throws:  None.
194 //--
195 bool CMICmdCmdStackInfoFrame::ParseArgs() { return ParseValidateCmdOptions(); }
196
197 //++
198 //------------------------------------------------------------------------------------
199 // Details: The invoker requires this function. The command does work in this
200 // function.
201 //          The command is likely to communicate with the LLDB SBDebugger in
202 //          here.
203 // Type:    Overridden.
204 // Args:    None.
205 // Return:  MIstatus::success - Function succeeded.
206 //          MIstatus::failure - Function failed.
207 // Throws:  None.
208 //--
209 bool CMICmdCmdStackInfoFrame::Execute() {
210   CMICmnLLDBDebugSessionInfo &rSessionInfo(
211       CMICmnLLDBDebugSessionInfo::Instance());
212   lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
213   if (!sbProcess.IsValid()) {
214     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS),
215                                    m_cmdData.strMiCmd.c_str()));
216     return MIstatus::failure;
217   }
218
219   lldb::SBThread sbThread = sbProcess.GetSelectedThread();
220   MIuint nFrameId = sbThread.GetSelectedFrame().GetFrameID();
221   if (!rSessionInfo.MIResponseFormFrameInfo(
222           sbThread, nFrameId,
223           CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_NoArguments,
224           m_miValueTuple))
225     return MIstatus::failure;
226
227   return MIstatus::success;
228 }
229
230 //++
231 //------------------------------------------------------------------------------------
232 // Details: The invoker requires this function. The command prepares a MI Record
233 // Result
234 //          for the work carried out in the Execute().
235 // Type:    Overridden.
236 // Args:    None.
237 // Return:  MIstatus::success - Function succeeded.
238 //          MIstatus::failure - Function failed.
239 // Throws:  None.
240 //--
241 bool CMICmdCmdStackInfoFrame::Acknowledge() {
242   const CMICmnMIValueResult miValueResult("frame", m_miValueTuple);
243   const CMICmnMIResultRecord miRecordResult(
244       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
245       miValueResult);
246   m_miResultRecord = miRecordResult;
247
248   return MIstatus::success;
249 }
250
251 //++
252 //------------------------------------------------------------------------------------
253 // Details: Required by the CMICmdFactory when registering *this command. The
254 // factory
255 //          calls this function to create an instance of *this command.
256 // Type:    Static method.
257 // Args:    None.
258 // Return:  CMICmdBase * - Pointer to a new command.
259 // Throws:  None.
260 //--
261 CMICmdBase *CMICmdCmdStackInfoFrame::CreateSelf() {
262   return new CMICmdCmdStackInfoFrame();
263 }
264
265 //---------------------------------------------------------------------------------------
266 //---------------------------------------------------------------------------------------
267 //---------------------------------------------------------------------------------------
268
269 //++
270 //------------------------------------------------------------------------------------
271 // Details: CMICmdCmdStackListFrames constructor.
272 // Type:    Method.
273 // Args:    None.
274 // Return:  None.
275 // Throws:  None.
276 //--
277 CMICmdCmdStackListFrames::CMICmdCmdStackListFrames()
278     : m_nThreadFrames(0), m_constStrArgFrameLow("low-frame"),
279       m_constStrArgFrameHigh("high-frame") {
280   // Command factory matches this name with that received from the stdin stream
281   m_strMiCmd = "stack-list-frames";
282
283   // Required by the CMICmdFactory when registering *this command
284   m_pSelfCreatorFn = &CMICmdCmdStackListFrames::CreateSelf;
285 }
286
287 //++
288 //------------------------------------------------------------------------------------
289 // Details: CMICmdCmdStackListFrames destructor.
290 // Type:    Overrideable.
291 // Args:    None.
292 // Return:  None.
293 // Throws:  None.
294 //--
295 CMICmdCmdStackListFrames::~CMICmdCmdStackListFrames() {
296   m_vecMIValueResult.clear();
297 }
298
299 //++
300 //------------------------------------------------------------------------------------
301 // Details: The invoker requires this function. The parses the command line
302 // options
303 //          arguments to extract values for each of those arguments.
304 // Type:    Overridden.
305 // Args:    None.
306 // Return:  MIstatus::success - Functional succeeded.
307 //          MIstatus::failure - Functional failed.
308 // Throws:  None.
309 //--
310 bool CMICmdCmdStackListFrames::ParseArgs() {
311   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrameLow, false, true));
312   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrameHigh, false, true));
313   return ParseValidateCmdOptions();
314 }
315
316 //++
317 //------------------------------------------------------------------------------------
318 // Details: The invoker requires this function. The command does work in this
319 // function.
320 //          The command is likely to communicate with the LLDB SBDebugger in
321 //          here.
322 // Type:    Overridden.
323 // Args:    None.
324 // Return:  MIstatus::success - Functional succeeded.
325 //          MIstatus::failure - Functional failed.
326 // Throws:  None.
327 //--
328 bool CMICmdCmdStackListFrames::Execute() {
329   CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
330   CMICMDBASE_GETOPTION(pArgFrameLow, Number, m_constStrArgFrameLow);
331   CMICMDBASE_GETOPTION(pArgFrameHigh, Number, m_constStrArgFrameHigh);
332
333   // Retrieve the --thread option's thread ID (only 1)
334   MIuint64 nThreadId = UINT64_MAX;
335   if (pArgThread->GetFound() &&
336       !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
337     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
338                                    m_cmdData.strMiCmd.c_str(),
339                                    m_constStrArgThread.c_str()));
340     return MIstatus::failure;
341   }
342
343   // Frame low and high options are not mandatory
344   MIuint nFrameHigh =
345       pArgFrameHigh->GetFound() ? pArgFrameHigh->GetValue() : UINT32_MAX;
346   const MIuint nFrameLow =
347       pArgFrameLow->GetFound() ? pArgFrameLow->GetValue() : 0;
348
349   CMICmnLLDBDebugSessionInfo &rSessionInfo(
350       CMICmnLLDBDebugSessionInfo::Instance());
351   lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
352   lldb::SBThread thread = (nThreadId != UINT64_MAX)
353                               ? sbProcess.GetThreadByIndexID(nThreadId)
354                               : sbProcess.GetSelectedThread();
355   MIuint nThreadFrames = thread.GetNumFrames();
356
357   // Adjust nThreadFrames for the nFrameHigh argument as we use nFrameHigh+1 in
358   // the min calc as the arg
359   // is not an index, but a frame id value.
360   if (nFrameHigh < UINT32_MAX) {
361     nFrameHigh++;
362     nThreadFrames = (nFrameHigh < nThreadFrames) ? nFrameHigh : nThreadFrames;
363   }
364
365   m_nThreadFrames = nThreadFrames;
366   if (nThreadFrames == 0)
367     return MIstatus::success;
368
369   m_vecMIValueResult.clear();
370   for (MIuint nLevel = nFrameLow; nLevel < nThreadFrames; nLevel++) {
371     CMICmnMIValueTuple miValueTuple;
372     if (!rSessionInfo.MIResponseFormFrameInfo(
373             thread, nLevel,
374             CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_NoArguments,
375             miValueTuple))
376       return MIstatus::failure;
377
378     const CMICmnMIValueResult miValueResult8("frame", miValueTuple);
379     m_vecMIValueResult.push_back(miValueResult8);
380   }
381
382   return MIstatus::success;
383 }
384
385 //++
386 //------------------------------------------------------------------------------------
387 // Details: The invoker requires this function. The command prepares a MI Record
388 // Result
389 //          for the work carried out in the Execute().
390 // Type:    Overridden.
391 // Args:    None.
392 // Return:  MIstatus::success - Functional succeeded.
393 //          MIstatus::failure - Functional failed.
394 // Throws:  None.
395 //--
396 bool CMICmdCmdStackListFrames::Acknowledge() {
397   if (m_nThreadFrames == 0) {
398     // MI print "3^done,stack=[{}]"
399     const CMICmnMIValueTuple miValueTuple;
400     const CMICmnMIValueList miValueList(miValueTuple);
401     const CMICmnMIValueResult miValueResult("stack", miValueList);
402     const CMICmnMIResultRecord miRecordResult(
403         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
404         miValueResult);
405     m_miResultRecord = miRecordResult;
406
407     return MIstatus::success;
408   }
409
410   // Build up a list of thread information from tuples
411   VecMIValueResult_t::const_iterator it = m_vecMIValueResult.begin();
412   if (it == m_vecMIValueResult.end()) {
413     // MI print "3^done,stack=[{}]"
414     const CMICmnMIValueTuple miValueTuple;
415     const CMICmnMIValueList miValueList(miValueTuple);
416     const CMICmnMIValueResult miValueResult("stack", miValueList);
417     const CMICmnMIResultRecord miRecordResult(
418         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
419         miValueResult);
420     m_miResultRecord = miRecordResult;
421     return MIstatus::success;
422   }
423   CMICmnMIValueList miValueList(*it);
424   ++it;
425   while (it != m_vecMIValueResult.end()) {
426     const CMICmnMIValueResult &rTuple(*it);
427     miValueList.Add(rTuple);
428
429     // Next
430     ++it;
431   }
432   const CMICmnMIValueResult miValueResult("stack", miValueList);
433   const CMICmnMIResultRecord miRecordResult(
434       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
435       miValueResult);
436   m_miResultRecord = miRecordResult;
437
438   return MIstatus::success;
439 }
440
441 //++
442 //------------------------------------------------------------------------------------
443 // Details: Required by the CMICmdFactory when registering *this command. The
444 // factory
445 //          calls this function to create an instance of *this command.
446 // Type:    Static method.
447 // Args:    None.
448 // Return:  CMICmdBase * - Pointer to a new command.
449 // Throws:  None.
450 //--
451 CMICmdBase *CMICmdCmdStackListFrames::CreateSelf() {
452   return new CMICmdCmdStackListFrames();
453 }
454
455 //---------------------------------------------------------------------------------------
456 //---------------------------------------------------------------------------------------
457 //---------------------------------------------------------------------------------------
458
459 //++
460 //------------------------------------------------------------------------------------
461 // Details: CMICmdCmdStackListArguments constructor.
462 // Type:    Method.
463 // Args:    None.
464 // Return:  None.
465 // Throws:  None.
466 //--
467 CMICmdCmdStackListArguments::CMICmdCmdStackListArguments()
468     : m_bThreadInvalid(false), m_miValueList(true),
469       m_constStrArgPrintValues("print-values"),
470       m_constStrArgFrameLow("low-frame"), m_constStrArgFrameHigh("high-frame") {
471   // Command factory matches this name with that received from the stdin stream
472   m_strMiCmd = "stack-list-arguments";
473
474   // Required by the CMICmdFactory when registering *this command
475   m_pSelfCreatorFn = &CMICmdCmdStackListArguments::CreateSelf;
476 }
477
478 //++
479 //------------------------------------------------------------------------------------
480 // Details: CMICmdCmdStackListArguments destructor.
481 // Type:    Overrideable.
482 // Args:    None.
483 // Return:  None.
484 // Throws:  None.
485 //--
486 CMICmdCmdStackListArguments::~CMICmdCmdStackListArguments() {}
487
488 //++
489 //------------------------------------------------------------------------------------
490 // Details: The invoker requires this function. The parses the command line
491 // options
492 //          arguments to extract values for each of those arguments.
493 // Type:    Overridden.
494 // Args:    None.
495 // Return:  MIstatus::success - Functional succeeded.
496 //          MIstatus::failure - Functional failed.
497 // Throws:  None.
498 //--
499 bool CMICmdCmdStackListArguments::ParseArgs() {
500   m_setCmdArgs.Add(
501       new CMICmdArgValPrintValues(m_constStrArgPrintValues, true, true));
502   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrameLow, false, true));
503   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrameHigh, false, true));
504   return ParseValidateCmdOptions();
505 }
506
507 //++
508 //------------------------------------------------------------------------------------
509 // Details: The invoker requires this function. The command does work in this
510 // function.
511 //          The command is likely to communicate with the LLDB SBDebugger in
512 //          here.
513 // Type:    Overridden.
514 // Args:    None.
515 // Return:  MIstatus::success - Functional succeeded.
516 //          MIstatus::failure - Functional failed.
517 // Throws:  None.
518 //--
519 bool CMICmdCmdStackListArguments::Execute() {
520   CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
521   CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
522   CMICMDBASE_GETOPTION(pArgFrameLow, Number, m_constStrArgFrameLow);
523   CMICMDBASE_GETOPTION(pArgFrameHigh, Number, m_constStrArgFrameHigh);
524
525   // Retrieve the --thread option's thread ID (only 1)
526   MIuint64 nThreadId = UINT64_MAX;
527   if (pArgThread->GetFound()) {
528     if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(
529             nThreadId)) {
530       SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
531                                      m_cmdData.strMiCmd.c_str(),
532                                      m_constStrArgThread.c_str()));
533       return MIstatus::failure;
534     }
535   }
536
537   const CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
538       static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
539           pArgPrintValues->GetValue());
540
541   MIuint nFrameLow = 0;
542   MIuint nFrameHigh = UINT32_MAX;
543   if (pArgFrameLow->GetFound() && pArgFrameHigh->GetFound()) {
544     nFrameLow = pArgFrameLow->GetValue();
545     nFrameHigh = pArgFrameHigh->GetValue() + 1;
546   } else if (pArgFrameLow->GetFound() || pArgFrameHigh->GetFound()) {
547     // Only low-frame or high-frame was specified but both are required
548     SetError(
549         CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_FRAME_RANGE_INVALID),
550                               m_cmdData.strMiCmd.c_str()));
551     return MIstatus::failure;
552   }
553
554   CMICmnLLDBDebugSessionInfo &rSessionInfo(
555       CMICmnLLDBDebugSessionInfo::Instance());
556   lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
557   lldb::SBThread thread = (nThreadId != UINT64_MAX)
558                               ? sbProcess.GetThreadByIndexID(nThreadId)
559                               : sbProcess.GetSelectedThread();
560   m_bThreadInvalid = !thread.IsValid();
561   if (m_bThreadInvalid)
562     return MIstatus::success;
563
564   const lldb::StopReason eStopReason = thread.GetStopReason();
565   if ((eStopReason == lldb::eStopReasonNone) ||
566       (eStopReason == lldb::eStopReasonInvalid)) {
567     m_bThreadInvalid = true;
568     return MIstatus::success;
569   }
570
571   const MIuint nFrames = thread.GetNumFrames();
572   if (nFrameLow >= nFrames) {
573     // The low-frame is larger than the actual number of frames
574     SetError(
575         CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_FRAME_RANGE_INVALID),
576                               m_cmdData.strMiCmd.c_str()));
577     return MIstatus::failure;
578   }
579
580   nFrameHigh = std::min(nFrameHigh, nFrames);
581   for (MIuint i = nFrameLow; i < nFrameHigh; i++) {
582     lldb::SBFrame frame = thread.GetFrameAtIndex(i);
583     CMICmnMIValueList miValueList(true);
584     const MIuint maskVarTypes =
585         CMICmnLLDBDebugSessionInfo::eVariableType_Arguments;
586     if (!rSessionInfo.MIResponseFormVariableInfo(frame, maskVarTypes,
587                                                  eVarInfoFormat, miValueList))
588       return MIstatus::failure;
589     const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", i));
590     const CMICmnMIValueResult miValueResult("level", miValueConst);
591     CMICmnMIValueTuple miValueTuple(miValueResult);
592     const CMICmnMIValueResult miValueResult2("args", miValueList);
593     miValueTuple.Add(miValueResult2);
594     const CMICmnMIValueResult miValueResult3("frame", miValueTuple);
595     m_miValueList.Add(miValueResult3);
596   }
597
598   return MIstatus::success;
599 }
600
601 //++
602 //------------------------------------------------------------------------------------
603 // Details: The invoker requires this function. The command prepares a MI Record
604 // Result
605 //          for the work carried out in the Execute().
606 // Type:    Overridden.
607 // Args:    None.
608 // Return:  MIstatus::success - Functional succeeded.
609 //          MIstatus::failure - Functional failed.
610 // Throws:  None.
611 //--
612 bool CMICmdCmdStackListArguments::Acknowledge() {
613   if (m_bThreadInvalid) {
614     // MI print "%s^done,stack-args=[]"
615     const CMICmnMIValueList miValueList(true);
616     const CMICmnMIValueResult miValueResult("stack-args", miValueList);
617     const CMICmnMIResultRecord miRecordResult(
618         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
619         miValueResult);
620     m_miResultRecord = miRecordResult;
621     return MIstatus::success;
622   }
623
624   // MI print
625   // "%s^done,stack-args=[frame={level=\"0\",args=[%s]},frame={level=\"1\",args=[%s]}]"
626   const CMICmnMIValueResult miValueResult4("stack-args", m_miValueList);
627   const CMICmnMIResultRecord miRecordResult(
628       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
629       miValueResult4);
630   m_miResultRecord = miRecordResult;
631
632   return MIstatus::success;
633 }
634
635 //++
636 //------------------------------------------------------------------------------------
637 // Details: Required by the CMICmdFactory when registering *this command. The
638 // factory
639 //          calls this function to create an instance of *this command.
640 // Type:    Static method.
641 // Args:    None.
642 // Return:  CMICmdBase * - Pointer to a new command.
643 // Throws:  None.
644 //--
645 CMICmdBase *CMICmdCmdStackListArguments::CreateSelf() {
646   return new CMICmdCmdStackListArguments();
647 }
648
649 //---------------------------------------------------------------------------------------
650 //---------------------------------------------------------------------------------------
651 //---------------------------------------------------------------------------------------
652
653 //++
654 //------------------------------------------------------------------------------------
655 // Details: CMICmdCmdStackListLocals constructor.
656 // Type:    Method.
657 // Args:    None.
658 // Return:  None.
659 // Throws:  None.
660 //--
661 CMICmdCmdStackListLocals::CMICmdCmdStackListLocals()
662     : m_bThreadInvalid(false), m_miValueList(true),
663       m_constStrArgPrintValues("print-values") {
664   // Command factory matches this name with that received from the stdin stream
665   m_strMiCmd = "stack-list-locals";
666
667   // Required by the CMICmdFactory when registering *this command
668   m_pSelfCreatorFn = &CMICmdCmdStackListLocals::CreateSelf;
669 }
670
671 //++
672 //------------------------------------------------------------------------------------
673 // Details: CMICmdCmdStackListLocals destructor.
674 // Type:    Overrideable.
675 // Args:    None.
676 // Return:  None.
677 // Throws:  None.
678 //--
679 CMICmdCmdStackListLocals::~CMICmdCmdStackListLocals() {}
680
681 //++
682 //------------------------------------------------------------------------------------
683 // Details: The invoker requires this function. The parses the command line
684 // options
685 //          arguments to extract values for each of those arguments.
686 // Type:    Overridden.
687 // Args:    None.
688 // Return:  MIstatus::success - Functional succeeded.
689 //          MIstatus::failure - Functional failed.
690 // Throws:  None.
691 //--
692 bool CMICmdCmdStackListLocals::ParseArgs() {
693   m_setCmdArgs.Add(
694       new CMICmdArgValPrintValues(m_constStrArgPrintValues, true, true));
695   return ParseValidateCmdOptions();
696 }
697
698 //++
699 //------------------------------------------------------------------------------------
700 // Details: The invoker requires this function. The command does work in this
701 // function.
702 //          The command is likely to communicate with the LLDB SBDebugger in
703 //          here.
704 // Type:    Overridden.
705 // Args:    None.
706 // Return:  MIstatus::success - Functional succeeded.
707 //          MIstatus::failure - Functional failed.
708 // Throws:  None.
709 //--
710 bool CMICmdCmdStackListLocals::Execute() {
711   CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
712   CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
713   CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
714
715   // Retrieve the --thread option's thread ID (only 1)
716   MIuint64 nThreadId = UINT64_MAX;
717   if (pArgThread->GetFound()) {
718     if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(
719             nThreadId)) {
720       SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
721                                      m_cmdData.strMiCmd.c_str(),
722                                      m_constStrArgThread.c_str()));
723       return MIstatus::failure;
724     }
725   }
726
727   MIuint64 nFrame = UINT64_MAX;
728   if (pArgFrame->GetFound()) {
729     if (!pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame)) {
730       SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
731                                      m_cmdData.strMiCmd.c_str(),
732                                      m_constStrArgFrame.c_str()));
733       return MIstatus::failure;
734     }
735   }
736
737   const CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
738       static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
739           pArgPrintValues->GetValue());
740
741   CMICmnLLDBDebugSessionInfo &rSessionInfo(
742       CMICmnLLDBDebugSessionInfo::Instance());
743   lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
744   lldb::SBThread thread = (nThreadId != UINT64_MAX)
745                               ? sbProcess.GetThreadByIndexID(nThreadId)
746                               : sbProcess.GetSelectedThread();
747   m_bThreadInvalid = !thread.IsValid();
748   if (m_bThreadInvalid)
749     return MIstatus::success;
750
751   const lldb::StopReason eStopReason = thread.GetStopReason();
752   if ((eStopReason == lldb::eStopReasonNone) ||
753       (eStopReason == lldb::eStopReasonInvalid)) {
754     m_bThreadInvalid = true;
755     return MIstatus::success;
756   }
757
758   lldb::SBFrame frame = (nFrame != UINT64_MAX) ? thread.GetFrameAtIndex(nFrame)
759                                                : thread.GetSelectedFrame();
760
761   CMICmnMIValueList miValueList(true);
762   const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Locals |
763                               CMICmnLLDBDebugSessionInfo::eVariableType_InScope;
764   if (!rSessionInfo.MIResponseFormVariableInfo(frame, maskVarTypes,
765                                                eVarInfoFormat, miValueList))
766     return MIstatus::failure;
767
768   m_miValueList = miValueList;
769
770   return MIstatus::success;
771 }
772
773 //++
774 //------------------------------------------------------------------------------------
775 // Details: The invoker requires this function. The command prepares a MI Record
776 // Result
777 //          for the work carried out in the Execute().
778 // Type:    Overridden.
779 // Args:    None.
780 // Return:  MIstatus::success - Functional succeeded.
781 //          MIstatus::failure - Functional failed.
782 // Throws:  None.
783 //--
784 bool CMICmdCmdStackListLocals::Acknowledge() {
785   if (m_bThreadInvalid) {
786     // MI print "%s^done,locals=[]"
787     const CMICmnMIValueList miValueList(true);
788     const CMICmnMIValueResult miValueResult("locals", miValueList);
789     const CMICmnMIResultRecord miRecordResult(
790         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
791         miValueResult);
792     m_miResultRecord = miRecordResult;
793     return MIstatus::success;
794   }
795
796   // MI print "%s^done,locals=[%s]"
797   const CMICmnMIValueResult miValueResult("locals", m_miValueList);
798   const CMICmnMIResultRecord miRecordResult(
799       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
800       miValueResult);
801   m_miResultRecord = miRecordResult;
802
803   return MIstatus::success;
804 }
805
806 //++
807 //------------------------------------------------------------------------------------
808 // Details: Required by the CMICmdFactory when registering *this command. The
809 // factory
810 //          calls this function to create an instance of *this command.
811 // Type:    Static method.
812 // Args:    None.
813 // Return:  CMICmdBase * - Pointer to a new command.
814 // Throws:  None.
815 //--
816 CMICmdBase *CMICmdCmdStackListLocals::CreateSelf() {
817   return new CMICmdCmdStackListLocals();
818 }
819
820 //---------------------------------------------------------------------------------------
821 //---------------------------------------------------------------------------------------
822 //---------------------------------------------------------------------------------------
823
824 //++
825 //------------------------------------------------------------------------------------
826 // Details: CMICmdCmdStackListVariables constructor.
827 // Type:    Method.
828 // Args:    None.
829 // Return:  None.
830 // Throws:  None.
831 //--
832 CMICmdCmdStackListVariables::CMICmdCmdStackListVariables()
833     : m_bThreadInvalid(false), m_miValueList(true),
834       m_constStrArgPrintValues("print-values") {
835   // Command factory matches this name with that received from the stdin stream
836   m_strMiCmd = "stack-list-variables";
837
838   // Required by the CMICmdFactory when registering *this command
839   m_pSelfCreatorFn = &CMICmdCmdStackListVariables::CreateSelf;
840 }
841
842 //++
843 //------------------------------------------------------------------------------------
844 // Details: CMICmdCmdStackListVariables destructor.
845 // Type:    Overrideable.
846 // Args:    None.
847 // Return:  None.
848 // Throws:  None.
849 //--
850 CMICmdCmdStackListVariables::~CMICmdCmdStackListVariables() {}
851
852 //++
853 //------------------------------------------------------------------------------------
854 // Details: The invoker requires this function. The parses the command line
855 // options
856 //          arguments to extract values for each of those arguments.
857 // Type:    Overridden.
858 // Args:    None.
859 // Return:  MIstatus::success - Functional succeeded.
860 //          MIstatus::failure - Functional failed.
861 // Throws:  None.
862 //--
863 bool CMICmdCmdStackListVariables::ParseArgs() {
864   m_setCmdArgs.Add(
865       new CMICmdArgValPrintValues(m_constStrArgPrintValues, true, true));
866   return ParseValidateCmdOptions();
867 }
868
869 //++
870 //------------------------------------------------------------------------------------
871 // Details: The invoker requires this function. The command does work in this
872 // function.
873 //          The command is likely to communicate with the LLDB SBDebugger in
874 //          here.
875 // Type:    Overridden.
876 // Args:    None.
877 // Return:  MIstatus::success - Functional succeeded.
878 //          MIstatus::failure - Functional failed.
879 // Throws:  None.
880 //--
881 bool CMICmdCmdStackListVariables::Execute() {
882   CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
883   CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
884   CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
885
886   // Retrieve the --thread option's thread ID (only 1)
887   MIuint64 nThreadId = UINT64_MAX;
888   if (pArgThread->GetFound()) {
889     if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(
890             nThreadId)) {
891       SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
892                                      m_cmdData.strMiCmd.c_str(),
893                                      m_constStrArgThread.c_str()));
894       return MIstatus::failure;
895     }
896   }
897
898   MIuint64 nFrame = UINT64_MAX;
899   if (pArgFrame->GetFound()) {
900     if (!pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame)) {
901       SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
902                                      m_cmdData.strMiCmd.c_str(),
903                                      m_constStrArgFrame.c_str()));
904       return MIstatus::failure;
905     }
906   }
907
908   const CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat =
909       static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(
910           pArgPrintValues->GetValue());
911
912   CMICmnLLDBDebugSessionInfo &rSessionInfo(
913       CMICmnLLDBDebugSessionInfo::Instance());
914   lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
915   lldb::SBThread thread = (nThreadId != UINT64_MAX)
916                               ? sbProcess.GetThreadByIndexID(nThreadId)
917                               : sbProcess.GetSelectedThread();
918   m_bThreadInvalid = !thread.IsValid();
919   if (m_bThreadInvalid)
920     return MIstatus::success;
921
922   const lldb::StopReason eStopReason = thread.GetStopReason();
923   if ((eStopReason == lldb::eStopReasonNone) ||
924       (eStopReason == lldb::eStopReasonInvalid)) {
925     m_bThreadInvalid = true;
926     return MIstatus::success;
927   }
928
929   lldb::SBFrame frame = (nFrame != UINT64_MAX) ? thread.GetFrameAtIndex(nFrame)
930                                                : thread.GetSelectedFrame();
931
932   CMICmnMIValueList miValueList(true);
933   const MIuint maskVarTypes =
934       CMICmnLLDBDebugSessionInfo::eVariableType_Arguments |
935       CMICmnLLDBDebugSessionInfo::eVariableType_Locals |
936       CMICmnLLDBDebugSessionInfo::eVariableType_InScope;
937   if (!rSessionInfo.MIResponseFormVariableInfo(
938           frame, maskVarTypes, eVarInfoFormat, miValueList, 10, true))
939     return MIstatus::failure;
940   m_miValueList = miValueList;
941
942   return MIstatus::success;
943 }
944
945 //++
946 //------------------------------------------------------------------------------------
947 // Details: The invoker requires this function. The command prepares a MI Record
948 // Result
949 //          for the work carried out in the Execute().
950 // Type:    Overridden.
951 // Args:    None.
952 // Return:  MIstatus::success - Functional succeeded.
953 //          MIstatus::failure - Functional failed.
954 // Throws:  None.
955 //--
956 bool CMICmdCmdStackListVariables::Acknowledge() {
957   if (m_bThreadInvalid) {
958     // MI print "%s^done,variables=[]"
959     const CMICmnMIValueList miValueList(true);
960     const CMICmnMIValueResult miValueResult("variables", miValueList);
961     const CMICmnMIResultRecord miRecordResult(
962         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
963         miValueResult);
964     m_miResultRecord = miRecordResult;
965     return MIstatus::success;
966   }
967
968   // MI print "%s^done,variables=[%s]"
969   const CMICmnMIValueResult miValueResult("variables", m_miValueList);
970   const CMICmnMIResultRecord miRecordResult(
971       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
972       miValueResult);
973   m_miResultRecord = miRecordResult;
974
975   return MIstatus::success;
976 }
977
978 //++
979 //------------------------------------------------------------------------------------
980 // Details: Required by the CMICmdFactory when registering *this command. The
981 // factory
982 //          calls this function to create an instance of *this command.
983 // Type:    Static method.
984 // Args:    None.
985 // Return:  CMICmdBase * - Pointer to a new command.
986 // Throws:  None.
987 //--
988 CMICmdBase *CMICmdCmdStackListVariables::CreateSelf() {
989   return new CMICmdCmdStackListVariables();
990 }
991
992 //---------------------------------------------------------------------------------------
993 //---------------------------------------------------------------------------------------
994 //---------------------------------------------------------------------------------------
995
996 //++
997 //------------------------------------------------------------------------------------
998 // Details: CMICmdCmdStackSelectFrame constructor.
999 // Type:    Method.
1000 // Args:    None.
1001 // Return:  None.
1002 // Throws:  None.
1003 //--
1004 CMICmdCmdStackSelectFrame::CMICmdCmdStackSelectFrame()
1005     : m_bFrameInvalid(false), m_constStrArgFrameId("frame_id") {
1006   // Command factory matches this name with that received from the stdin stream
1007   m_strMiCmd = "stack-select-frame";
1008
1009   // Required by the CMICmdFactory when registering *this command
1010   m_pSelfCreatorFn = &CMICmdCmdStackSelectFrame::CreateSelf;
1011 }
1012
1013 //++
1014 //------------------------------------------------------------------------------------
1015 // Details: CMICmdCmdStackSelectFrame destructor.
1016 // Type:    Overrideable.
1017 // Args:    None.
1018 // Return:  None.
1019 // Throws:  None.
1020 //--
1021 CMICmdCmdStackSelectFrame::~CMICmdCmdStackSelectFrame() {}
1022
1023 //++
1024 //------------------------------------------------------------------------------------
1025 // Details: The invoker requires this function. The parses the command line
1026 // options
1027 //          arguments to extract values for each of those arguments.
1028 // Type:    Overridden.
1029 // Args:    None.
1030 // Return:  MIstatus::success - Function succeeded.
1031 //          MIstatus::failure - Function failed.
1032 // Throws:  None.
1033 //--
1034 bool CMICmdCmdStackSelectFrame::ParseArgs() {
1035   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgFrameId, true, false));
1036   return ParseValidateCmdOptions();
1037 }
1038
1039 //++
1040 //------------------------------------------------------------------------------------
1041 // Details: The invoker requires this function. The command does work in this
1042 // function.
1043 //          The command is likely to communicate with the LLDB SBDebugger in
1044 //          here.
1045 // Type:    Overridden.
1046 // Args:    None.
1047 // Return:  MIstatus::success - Function succeeded.
1048 //          MIstatus::failure - Function failed.
1049 // Throws:  None.
1050 //--
1051 bool CMICmdCmdStackSelectFrame::Execute() {
1052   CMICMDBASE_GETOPTION(pArgFrame, Number, m_constStrArgFrameId);
1053
1054   CMICmnLLDBDebugSessionInfo &rSessionInfo(
1055       CMICmnLLDBDebugSessionInfo::Instance());
1056   lldb::SBThread sbThread = rSessionInfo.GetProcess().GetSelectedThread();
1057
1058   const MIuint nFrameId = pArgFrame->GetValue();
1059   m_bFrameInvalid = (nFrameId >= sbThread.GetNumFrames());
1060   if (m_bFrameInvalid)
1061     return MIstatus::success;
1062
1063   lldb::SBFrame sbFrame = sbThread.SetSelectedFrame(nFrameId);
1064   m_bFrameInvalid = !sbFrame.IsValid();
1065
1066   return MIstatus::success;
1067 }
1068
1069 //++
1070 //------------------------------------------------------------------------------------
1071 // Details: The invoker requires this function. The command prepares a MI Record
1072 // Result
1073 //          for the work carried out in the Execute().
1074 // Type:    Overridden.
1075 // Args:    None.
1076 // Return:  MIstatus::success - Function succeeded.
1077 //          MIstatus::failure - Function failed.
1078 // Throws:  None.
1079 //--
1080 bool CMICmdCmdStackSelectFrame::Acknowledge() {
1081   if (m_bFrameInvalid) {
1082     // MI print "%s^error,msg=\"Command '-stack-select-frame'. Frame ID
1083     // invalid\""
1084     const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
1085         MIRSRC(IDS_CMD_ERR_FRAME_INVALID), m_cmdData.strMiCmd.c_str()));
1086     const CMICmnMIValueResult miValueResult("msg", miValueConst);
1087     const CMICmnMIResultRecord miRecordResult(
1088         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1089         miValueResult);
1090     m_miResultRecord = miRecordResult;
1091
1092     return MIstatus::success;
1093   }
1094
1095   const CMICmnMIResultRecord miRecordResult(
1096       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
1097   m_miResultRecord = miRecordResult;
1098
1099   return MIstatus::success;
1100 }
1101
1102 //++
1103 //------------------------------------------------------------------------------------
1104 // Details: Required by the CMICmdFactory when registering *this command. The
1105 // factory
1106 //          calls this function to create an instance of *this command.
1107 // Type:    Static method.
1108 // Args:    None.
1109 // Return:  CMICmdBase * - Pointer to a new command.
1110 // Throws:  None.
1111 //--
1112 CMICmdBase *CMICmdCmdStackSelectFrame::CreateSelf() {
1113   return new CMICmdCmdStackSelectFrame();
1114 }