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 //--
CMICmdCmdStackInfoDepth()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 //--
~CMICmdCmdStackInfoDepth()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 //--
ParseArgs()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 //--
Execute()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 //--
Acknowledge()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 //--
CreateSelf()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 //--
CMICmdCmdStackInfoFrame()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 //--
~CMICmdCmdStackInfoFrame()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 //--
ParseArgs()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 //--
Execute()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 //--
Acknowledge()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 //--
CreateSelf()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 //--
CMICmdCmdStackListFrames()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 //--
~CMICmdCmdStackListFrames()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 //--
ParseArgs()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 //--
Execute()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 //--
Acknowledge()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 //--
CreateSelf()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 //--
CMICmdCmdStackListArguments()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 //--
~CMICmdCmdStackListArguments()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 //--
ParseArgs()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 //--
Execute()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 //--
Acknowledge()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 //--
CreateSelf()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 //--
CMICmdCmdStackListLocals()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 //--
~CMICmdCmdStackListLocals()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 //--
ParseArgs()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 //--
Execute()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 //--
Acknowledge()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 //--
CreateSelf()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 //--
CMICmdCmdStackListVariables()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 //--
~CMICmdCmdStackListVariables()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 //--
ParseArgs()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 //--
Execute()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 //--
Acknowledge()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 //--
CreateSelf()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 //--
CMICmdCmdStackSelectFrame()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 //--
~CMICmdCmdStackSelectFrame()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 //--
ParseArgs()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 //--
Execute()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 //--
Acknowledge()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 //--
CreateSelf()1112 CMICmdBase *CMICmdCmdStackSelectFrame::CreateSelf() {
1113 return new CMICmdCmdStackSelectFrame();
1114 }
1115