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