1 //===-- MICmdCmdExec.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:    CMICmdCmdExecRun                implementation.
11 //              CMICmdCmdExecContinue           implementation.
12 //              CMICmdCmdExecNext               implementation.
13 //              CMICmdCmdExecStep               implementation.
14 //              CMICmdCmdExecNextInstruction    implementation.
15 //              CMICmdCmdExecStepInstruction    implementation.
16 //              CMICmdCmdExecFinish             implementation.
17 //              CMICmdCmdExecInterrupt          implementation.
18 //              CMICmdCmdExecArguments          implementation.
19 //              CMICmdCmdExecAbort              implementation.
20 
21 // Third Party Headers:
22 #include "lldb/API/SBCommandInterpreter.h"
23 #include "lldb/API/SBProcess.h"
24 #include "lldb/API/SBStream.h"
25 #include "lldb/API/SBThread.h"
26 #include "lldb/lldb-enumerations.h"
27 
28 // In-house headers:
29 #include "MICmdArgValListOfN.h"
30 #include "MICmdArgValNumber.h"
31 #include "MICmdArgValOptionLong.h"
32 #include "MICmdArgValOptionShort.h"
33 #include "MICmdArgValString.h"
34 #include "MICmdArgValThreadGrp.h"
35 #include "MICmdCmdExec.h"
36 #include "MICmnLLDBDebugSessionInfo.h"
37 #include "MICmnLLDBDebugger.h"
38 #include "MICmnMIOutOfBandRecord.h"
39 #include "MICmnMIResultRecord.h"
40 #include "MICmnMIValueConst.h"
41 #include "MICmnStreamStdout.h"
42 #include "MIDriver.h"
43 
44 //++
45 //------------------------------------------------------------------------------------
46 // Details: CMICmdCmdExecRun constructor.
47 // Type:    Method.
48 // Args:    None.
49 // Return:  None.
50 // Throws:  None.
51 //--
CMICmdCmdExecRun()52 CMICmdCmdExecRun::CMICmdCmdExecRun() : m_constStrArgStart("start") {
53   // Command factory matches this name with that received from the stdin stream
54   m_strMiCmd = "exec-run";
55 
56   // Required by the CMICmdFactory when registering *this command
57   m_pSelfCreatorFn = &CMICmdCmdExecRun::CreateSelf;
58 }
59 
60 //++
61 //------------------------------------------------------------------------------------
62 // Details: CMICmdCmdExecRun destructor.
63 // Type:    Overrideable.
64 // Args:    None.
65 // Return:  None.
66 // Throws:  None.
67 //--
~CMICmdCmdExecRun()68 CMICmdCmdExecRun::~CMICmdCmdExecRun() {}
69 
70 //++
71 //------------------------------------------------------------------------------------
72 // Details: The invoker requires this function. It parses the command line
73 // options'
74 //          arguments to extract values for each of those arguments.
75 // Type:    Overridden.
76 // Args:    None.
77 // Return:  MIstatus::success - Functional succeeded.
78 //          MIstatus::failure - Functional failed.
79 // Throws:  None.
80 //--
ParseArgs()81 bool CMICmdCmdExecRun::ParseArgs() {
82   m_setCmdArgs.Add(new CMICmdArgValOptionLong(
83       m_constStrArgStart, false, true,
84       CMICmdArgValListBase::eArgValType_OptionLong, 0));
85   return ParseValidateCmdOptions();
86 }
87 
88 //++
89 //------------------------------------------------------------------------------------
90 // Details: The invoker requires this function. The command does work in this
91 // function.
92 //          The command is likely to communicate with the LLDB SBDebugger in
93 //          here.
94 // Type:    Overridden.
95 // Args:    None.
96 // Return:  MIstatus::success - Functional succeeded.
97 //          MIstatus::failure - Functional failed.
98 // Throws:  None.
99 //--
Execute()100 bool CMICmdCmdExecRun::Execute() {
101   CMICmnLLDBDebugSessionInfo &rSessionInfo(
102       CMICmnLLDBDebugSessionInfo::Instance());
103 
104   {
105     // Check we have a valid target.
106     // Note: target created via 'file-exec-and-symbols' command.
107     lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
108     if (!sbTarget.IsValid() ||
109         sbTarget == rSessionInfo.GetDebugger().GetDummyTarget()) {
110       SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT),
111                                      m_cmdData.strMiCmd.c_str()));
112       return MIstatus::failure;
113     }
114   }
115 
116   lldb::SBError error;
117   lldb::SBStream errMsg;
118   lldb::SBLaunchInfo launchInfo = rSessionInfo.GetTarget().GetLaunchInfo();
119   launchInfo.SetListener(rSessionInfo.GetListener());
120 
121   // Run to first instruction or main() requested?
122   CMICMDBASE_GETOPTION(pArgStart, OptionLong, m_constStrArgStart);
123   if (pArgStart->GetFound()) {
124     launchInfo.SetLaunchFlags(launchInfo.GetLaunchFlags() |
125                               lldb::eLaunchFlagStopAtEntry);
126   }
127 
128   lldb::SBProcess process = rSessionInfo.GetTarget().Launch(launchInfo, error);
129   if (!process.IsValid()) {
130     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS),
131                                    m_cmdData.strMiCmd.c_str(),
132                                    errMsg.GetData()));
133     return MIstatus::failure;
134   }
135 
136   const auto successHandler = [this] {
137     if (!CMIDriver::Instance().SetDriverStateRunningDebugging()) {
138       const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription());
139       SetError(CMIUtilString::Format(
140           MIRSRC(IDS_CMD_ERR_SET_NEW_DRIVER_STATE),
141           m_cmdData.strMiCmd.c_str(), rErrMsg.c_str()));
142       return MIstatus::failure;
143     }
144     return MIstatus::success;
145   };
146 
147   return HandleSBErrorWithSuccess(error, successHandler);
148 }
149 
150 //++
151 //------------------------------------------------------------------------------------
152 // Details: The invoker requires this function. The command prepares a MI Record
153 // Result
154 //          for the work carried out in the Execute().
155 //          Called only if Execute() set status as successful on completion.
156 // Type:    Overridden.
157 // Args:    None.
158 // Return:  MIstatus::success - Functional succeeded.
159 //          MIstatus::failure - Functional failed.
160 // Throws:  None.
161 //--
Acknowledge()162 bool CMICmdCmdExecRun::Acknowledge() {
163   m_miResultRecord = CMICmnMIResultRecord(
164       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
165 
166   CMICmnLLDBDebugSessionInfo &rSessionInfo(
167       CMICmnLLDBDebugSessionInfo::Instance());
168   lldb::pid_t pid = rSessionInfo.GetProcess().GetProcessID();
169   // Give the client '=thread-group-started,id="i1" pid="xyz"'
170   m_bHasResultRecordExtra = true;
171   const CMICmnMIValueConst miValueConst2("i1");
172   const CMICmnMIValueResult miValueResult2("id", miValueConst2);
173   const CMIUtilString strPid(CMIUtilString::Format("%lld", pid));
174   const CMICmnMIValueConst miValueConst(strPid);
175   const CMICmnMIValueResult miValueResult("pid", miValueConst);
176   CMICmnMIOutOfBandRecord miOutOfBand(
177       CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupStarted, miValueResult2);
178   miOutOfBand.Add(miValueResult);
179   m_miResultRecordExtra = miOutOfBand.GetString();
180 
181   return MIstatus::success;
182 }
183 
184 //++
185 //------------------------------------------------------------------------------------
186 // Details: Required by the CMICmdFactory when registering *this command. The
187 // factory
188 //          calls this function to create an instance of *this command.
189 // Type:    Static method.
190 // Args:    None.
191 // Return:  CMICmdBase * - Pointer to a new command.
192 // Throws:  None.
193 //--
CreateSelf()194 CMICmdBase *CMICmdCmdExecRun::CreateSelf() { return new CMICmdCmdExecRun(); }
195 
196 //---------------------------------------------------------------------------------------
197 //---------------------------------------------------------------------------------------
198 //---------------------------------------------------------------------------------------
199 
200 //++
201 //------------------------------------------------------------------------------------
202 // Details: CMICmdCmdExecContinue constructor.
203 // Type:    Method.
204 // Args:    None.
205 // Return:  None.
206 // Throws:  None.
207 //--
CMICmdCmdExecContinue()208 CMICmdCmdExecContinue::CMICmdCmdExecContinue() {
209   // Command factory matches this name with that received from the stdin stream
210   m_strMiCmd = "exec-continue";
211 
212   // Required by the CMICmdFactory when registering *this command
213   m_pSelfCreatorFn = &CMICmdCmdExecContinue::CreateSelf;
214 }
215 
216 //++
217 //------------------------------------------------------------------------------------
218 // Details: CMICmdCmdExecContinue destructor.
219 // Type:    Overrideable.
220 // Args:    None.
221 // Return:  None.
222 // Throws:  None.
223 //--
~CMICmdCmdExecContinue()224 CMICmdCmdExecContinue::~CMICmdCmdExecContinue() {}
225 
226 //++
227 //------------------------------------------------------------------------------------
228 // Details: The invoker requires this function. The command does work in this
229 // function.
230 //          The command is likely to communicate with the LLDB SBDebugger in
231 //          here.
232 // Type:    Overridden.
233 // Args:    None.
234 // Return:  MIstatus::success - Functional succeeded.
235 //          MIstatus::failure - Functional failed.
236 // Throws:  None.
237 //--
Execute()238 bool CMICmdCmdExecContinue::Execute() {
239   const auto successHandler = [this] {
240     // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
241     if (!CMIDriver::Instance().SetDriverStateRunningDebugging()) {
242       const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription());
243       SetError(CMIUtilString::Format(
244           MIRSRC(IDS_CMD_ERR_SET_NEW_DRIVER_STATE),
245           m_cmdData.strMiCmd.c_str(), rErrMsg.c_str()));
246       return MIstatus::failure;
247     }
248     return MIstatus::success;
249   };
250 
251   return HandleSBErrorWithSuccess(
252       CMICmnLLDBDebugSessionInfo::Instance().GetProcess().Continue(),
253       successHandler);
254 }
255 
256 //++
257 //------------------------------------------------------------------------------------
258 // Details: The invoker requires this function. The command prepares a MI Record
259 // Result
260 //          for the work carried out in the Execute().
261 // Type:    Overridden.
262 // Args:    None.
263 // Return:  MIstatus::success - Functional succeeded.
264 //          MIstatus::failure - Functional failed.
265 // Throws:  None.
266 //--
Acknowledge()267 bool CMICmdCmdExecContinue::Acknowledge() {
268   m_miResultRecord = CMICmnMIResultRecord(
269       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
270   return MIstatus::success;
271 }
272 
273 //++
274 //------------------------------------------------------------------------------------
275 // Details: Required by the CMICmdFactory when registering *this command. The
276 // factory
277 //          calls this function to create an instance of *this command.
278 // Type:    Static method.
279 // Args:    None.
280 // Return:  CMICmdBase * - Pointer to a new command.
281 // Throws:  None.
282 //--
CreateSelf()283 CMICmdBase *CMICmdCmdExecContinue::CreateSelf() {
284   return new CMICmdCmdExecContinue();
285 }
286 
287 //---------------------------------------------------------------------------------------
288 //---------------------------------------------------------------------------------------
289 //---------------------------------------------------------------------------------------
290 
291 //++
292 //------------------------------------------------------------------------------------
293 // Details: CMICmdCmdExecNext constructor.
294 // Type:    Method.
295 // Args:    None.
296 // Return:  None.
297 // Throws:  None.
298 //--
CMICmdCmdExecNext()299 CMICmdCmdExecNext::CMICmdCmdExecNext() : m_constStrArgNumber("number") {
300   // Command factory matches this name with that received from the stdin stream
301   m_strMiCmd = "exec-next";
302 
303   // Required by the CMICmdFactory when registering *this command
304   m_pSelfCreatorFn = &CMICmdCmdExecNext::CreateSelf;
305 }
306 
307 //++
308 //------------------------------------------------------------------------------------
309 // Details: CMICmdCmdExecNext destructor.
310 // Type:    Overrideable.
311 // Args:    None.
312 // Return:  None.
313 // Throws:  None.
314 //--
~CMICmdCmdExecNext()315 CMICmdCmdExecNext::~CMICmdCmdExecNext() {}
316 
317 //++
318 //------------------------------------------------------------------------------------
319 // Details: The invoker requires this function. The parses the command line
320 // options
321 //          arguments to extract values for each of those arguments.
322 // Type:    Overridden.
323 // Args:    None.
324 // Return:  MIstatus::success - Functional succeeded.
325 //          MIstatus::failure - Functional failed.
326 // Throws:  None.
327 //--
ParseArgs()328 bool CMICmdCmdExecNext::ParseArgs() {
329   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNumber, false, false));
330   return ParseValidateCmdOptions();
331 }
332 
333 //++
334 //------------------------------------------------------------------------------------
335 // Details: The invoker requires this function. The command does work in this
336 // function.
337 //          The command is likely to communicate with the LLDB SBDebugger in
338 //          here.
339 // Type:    Overridden.
340 // Args:    None.
341 // Return:  MIstatus::success - Functional succeeded.
342 //          MIstatus::failure - Functional failed.
343 // Throws:  None.
344 //--
Execute()345 bool CMICmdCmdExecNext::Execute() {
346   CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
347 
348   // Retrieve the --thread option's thread ID (only 1)
349   MIuint64 nThreadId = UINT64_MAX;
350   if (pArgThread->GetFound() &&
351       !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
352     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID),
353                                    m_cmdData.strMiCmd.c_str(),
354                                    m_constStrArgThread.c_str()));
355     return MIstatus::failure;
356   }
357 
358   CMICmnLLDBDebugSessionInfo &rSessionInfo(
359       CMICmnLLDBDebugSessionInfo::Instance());
360 
361   lldb::SBError error;
362   if (nThreadId != UINT64_MAX) {
363     lldb::SBThread sbThread = rSessionInfo.GetProcess().GetThreadByIndexID(nThreadId);
364     if (!sbThread.IsValid()) {
365       SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID),
366                                      m_cmdData.strMiCmd.c_str(),
367                                      m_constStrArgThread.c_str()));
368       return MIstatus::failure;
369     }
370     sbThread.StepOver(lldb::eOnlyDuringStepping, error);
371   } else
372     rSessionInfo.GetProcess().GetSelectedThread().StepOver(
373         lldb::eOnlyDuringStepping, error);
374 
375   return HandleSBError(error);
376 }
377 
378 //++
379 //------------------------------------------------------------------------------------
380 // Details: The invoker requires this function. The command prepares a MI Record
381 // Result
382 //          for the work carried out in the Execute().
383 // Type:    Overridden.
384 // Args:    None.
385 // Return:  MIstatus::success - Functional succeeded.
386 //          MIstatus::failure - Functional failed.
387 // Throws:  None.
388 //--
Acknowledge()389 bool CMICmdCmdExecNext::Acknowledge() {
390   m_miResultRecord = CMICmnMIResultRecord(
391       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
392   return MIstatus::success;
393 }
394 
395 //++
396 //------------------------------------------------------------------------------------
397 // Details: Required by the CMICmdFactory when registering *this command. The
398 // factory
399 //          calls this function to create an instance of *this command.
400 // Type:    Static method.
401 // Args:    None.
402 // Return:  CMICmdBase * - Pointer to a new command.
403 // Throws:  None.
404 //--
CreateSelf()405 CMICmdBase *CMICmdCmdExecNext::CreateSelf() { return new CMICmdCmdExecNext(); }
406 
407 //---------------------------------------------------------------------------------------
408 //---------------------------------------------------------------------------------------
409 //---------------------------------------------------------------------------------------
410 
411 //++
412 //------------------------------------------------------------------------------------
413 // Details: CMICmdCmdExecStep constructor.
414 // Type:    Method.
415 // Args:    None.
416 // Return:  None.
417 // Throws:  None.
418 //--
CMICmdCmdExecStep()419 CMICmdCmdExecStep::CMICmdCmdExecStep() : m_constStrArgNumber("number") {
420   // Command factory matches this name with that received from the stdin stream
421   m_strMiCmd = "exec-step";
422 
423   // Required by the CMICmdFactory when registering *this command
424   m_pSelfCreatorFn = &CMICmdCmdExecStep::CreateSelf;
425 }
426 
427 //++
428 //------------------------------------------------------------------------------------
429 // Details: CMICmdCmdExecStep destructor.
430 // Type:    Overrideable.
431 // Args:    None.
432 // Return:  None.
433 // Throws:  None.
434 //--
~CMICmdCmdExecStep()435 CMICmdCmdExecStep::~CMICmdCmdExecStep() {}
436 
437 //++
438 //------------------------------------------------------------------------------------
439 // Details: The invoker requires this function. The parses the command line
440 // options
441 //          arguments to extract values for each of those arguments.
442 // Type:    Overridden.
443 // Args:    None.
444 // Return:  MIstatus::success - Functional succeeded.
445 //          MIstatus::failure - Functional failed.
446 // Throws:  None.
447 //--
ParseArgs()448 bool CMICmdCmdExecStep::ParseArgs() {
449   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNumber, false, false));
450   return ParseValidateCmdOptions();
451 }
452 
453 //++
454 //------------------------------------------------------------------------------------
455 // Details: The invoker requires this function. The command does work in this
456 // function.
457 //          The command is likely to communicate with the LLDB SBDebugger in
458 //          here.
459 // Type:    Overridden.
460 // Args:    None.
461 // Return:  MIstatus::success - Functional succeeded.
462 //          MIstatus::failure - Functional failed.
463 // Throws:  None.
464 //--
Execute()465 bool CMICmdCmdExecStep::Execute() {
466   CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
467 
468   // Retrieve the --thread option's thread ID (only 1)
469   MIuint64 nThreadId = UINT64_MAX;
470   if (pArgThread->GetFound() &&
471       !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
472     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
473                                    m_cmdData.strMiCmd.c_str(),
474                                    m_constStrArgThread.c_str()));
475     return MIstatus::failure;
476   }
477 
478   CMICmnLLDBDebugSessionInfo &rSessionInfo(
479       CMICmnLLDBDebugSessionInfo::Instance());
480 
481   lldb::SBError error;
482   if (nThreadId != UINT64_MAX) {
483     lldb::SBThread sbThread =
484         rSessionInfo.GetProcess().GetThreadByIndexID(nThreadId);
485     if (!sbThread.IsValid()) {
486       SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID),
487                                      m_cmdData.strMiCmd.c_str(),
488                                      m_constStrArgThread.c_str()));
489       return MIstatus::failure;
490     }
491     sbThread.StepInto(nullptr, LLDB_INVALID_LINE_NUMBER, error);
492   } else
493     rSessionInfo.GetProcess().GetSelectedThread().StepInto(
494         nullptr, LLDB_INVALID_LINE_NUMBER, error);
495 
496   return HandleSBError(error);
497 }
498 
499 //++
500 //------------------------------------------------------------------------------------
501 // Details: The invoker requires this function. The command prepares a MI Record
502 // Result
503 //          for the work carried out in the Execute().
504 // Type:    Overridden.
505 // Args:    None.
506 // Return:  MIstatus::success - Functional succeeded.
507 //          MIstatus::failure - Functional failed.
508 // Throws:  None.
509 //--
Acknowledge()510 bool CMICmdCmdExecStep::Acknowledge() {
511   m_miResultRecord = CMICmnMIResultRecord(
512       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
513   return MIstatus::success;
514 }
515 
516 //++
517 //------------------------------------------------------------------------------------
518 // Details: Required by the CMICmdFactory when registering *this command. The
519 // factory
520 //          calls this function to create an instance of *this command.
521 // Type:    Static method.
522 // Args:    None.
523 // Return:  CMICmdBase * - Pointer to a new command.
524 // Throws:  None.
525 //--
CreateSelf()526 CMICmdBase *CMICmdCmdExecStep::CreateSelf() { return new CMICmdCmdExecStep(); }
527 
528 //---------------------------------------------------------------------------------------
529 //---------------------------------------------------------------------------------------
530 //---------------------------------------------------------------------------------------
531 
532 //++
533 //------------------------------------------------------------------------------------
534 // Details: CMICmdCmdExecNextInstruction constructor.
535 // Type:    Method.
536 // Args:    None.
537 // Return:  None.
538 // Throws:  None.
539 //--
CMICmdCmdExecNextInstruction()540 CMICmdCmdExecNextInstruction::CMICmdCmdExecNextInstruction()
541     : m_constStrArgNumber("number") {
542   // Command factory matches this name with that received from the stdin stream
543   m_strMiCmd = "exec-next-instruction";
544 
545   // Required by the CMICmdFactory when registering *this command
546   m_pSelfCreatorFn = &CMICmdCmdExecNextInstruction::CreateSelf;
547 }
548 
549 //++
550 //------------------------------------------------------------------------------------
551 // Details: CMICmdCmdExecNextInstruction destructor.
552 // Type:    Overrideable.
553 // Args:    None.
554 // Return:  None.
555 // Throws:  None.
556 //--
~CMICmdCmdExecNextInstruction()557 CMICmdCmdExecNextInstruction::~CMICmdCmdExecNextInstruction() {}
558 
559 //++
560 //------------------------------------------------------------------------------------
561 // Details: The invoker requires this function. The parses the command line
562 // options
563 //          arguments to extract values for each of those arguments.
564 // Type:    Overridden.
565 // Args:    None.
566 // Return:  MIstatus::success - Functional succeeded.
567 //          MIstatus::failure - Functional failed.
568 // Throws:  None.
569 //--
ParseArgs()570 bool CMICmdCmdExecNextInstruction::ParseArgs() {
571   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNumber, false, false));
572   return ParseValidateCmdOptions();
573 }
574 
575 //++
576 //------------------------------------------------------------------------------------
577 // Details: The invoker requires this function. The command does work in this
578 // function.
579 //          The command is likely to communicate with the LLDB SBDebugger in
580 //          here.
581 // Type:    Overridden.
582 // Args:    None.
583 // Return:  MIstatus::success - Functional succeeded.
584 //          MIstatus::failure - Functional failed.
585 // Throws:  None.
586 //--
Execute()587 bool CMICmdCmdExecNextInstruction::Execute() {
588   CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
589 
590   // Retrieve the --thread option's thread ID (only 1)
591   MIuint64 nThreadId = UINT64_MAX;
592   if (pArgThread->GetFound() &&
593       !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
594     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
595                                    m_cmdData.strMiCmd.c_str(),
596                                    m_constStrArgThread.c_str()));
597     return MIstatus::failure;
598   }
599 
600   CMICmnLLDBDebugSessionInfo &rSessionInfo(
601       CMICmnLLDBDebugSessionInfo::Instance());
602 
603   lldb::SBError error;
604   if (nThreadId != UINT64_MAX) {
605     lldb::SBThread sbThread =
606         rSessionInfo.GetProcess().GetThreadByIndexID(nThreadId);
607     if (!sbThread.IsValid()) {
608       SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID),
609                                      m_cmdData.strMiCmd.c_str(),
610                                      m_constStrArgThread.c_str()));
611       return MIstatus::failure;
612     }
613     sbThread.StepInstruction(true, error);
614   } else
615     rSessionInfo.GetProcess().GetSelectedThread().StepInstruction(
616         true, error);
617 
618   return HandleSBError(error);
619 }
620 
621 //++
622 //------------------------------------------------------------------------------------
623 // Details: The invoker requires this function. The command prepares a MI Record
624 // Result
625 //          for the work carried out in the Execute().
626 // Type:    Overridden.
627 // Args:    None.
628 // Return:  MIstatus::success - Functional succeeded.
629 //          MIstatus::failure - Functional failed.
630 // Throws:  None.
631 //--
Acknowledge()632 bool CMICmdCmdExecNextInstruction::Acknowledge() {
633   m_miResultRecord = CMICmnMIResultRecord(
634       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
635   return MIstatus::success;
636 }
637 
638 //++
639 //------------------------------------------------------------------------------------
640 // Details: Required by the CMICmdFactory when registering *this command. The
641 // factory
642 //          calls this function to create an instance of *this command.
643 // Type:    Static method.
644 // Args:    None.
645 // Return:  CMICmdBase * - Pointer to a new command.
646 // Throws:  None.
647 //--
CreateSelf()648 CMICmdBase *CMICmdCmdExecNextInstruction::CreateSelf() {
649   return new CMICmdCmdExecNextInstruction();
650 }
651 
652 //---------------------------------------------------------------------------------------
653 //---------------------------------------------------------------------------------------
654 //---------------------------------------------------------------------------------------
655 
656 //++
657 //------------------------------------------------------------------------------------
658 // Details: CMICmdCmdExecStepInstruction constructor.
659 // Type:    Method.
660 // Args:    None.
661 // Return:  None.
662 // Throws:  None.
663 //--
CMICmdCmdExecStepInstruction()664 CMICmdCmdExecStepInstruction::CMICmdCmdExecStepInstruction()
665     : m_constStrArgNumber("number") {
666   // Command factory matches this name with that received from the stdin stream
667   m_strMiCmd = "exec-step-instruction";
668 
669   // Required by the CMICmdFactory when registering *this command
670   m_pSelfCreatorFn = &CMICmdCmdExecStepInstruction::CreateSelf;
671 }
672 
673 //++
674 //------------------------------------------------------------------------------------
675 // Details: CMICmdCmdExecStepInstruction destructor.
676 // Type:    Overrideable.
677 // Args:    None.
678 // Return:  None.
679 // Throws:  None.
680 //--
~CMICmdCmdExecStepInstruction()681 CMICmdCmdExecStepInstruction::~CMICmdCmdExecStepInstruction() {}
682 
683 //++
684 //------------------------------------------------------------------------------------
685 // Details: The invoker requires this function. The parses the command line
686 // options
687 //          arguments to extract values for each of those arguments.
688 // Type:    Overridden.
689 // Args:    None.
690 // Return:  MIstatus::success - Functional succeeded.
691 //          MIstatus::failure - Functional failed.
692 // Throws:  None.
693 //--
ParseArgs()694 bool CMICmdCmdExecStepInstruction::ParseArgs() {
695   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNumber, false, false));
696   return ParseValidateCmdOptions();
697 }
698 
699 //++
700 //------------------------------------------------------------------------------------
701 // Details: The invoker requires this function. The command does work in this
702 // function.
703 //          The command is likely to communicate with the LLDB SBDebugger in
704 //          here.
705 // Type:    Overridden.
706 // Args:    None.
707 // Return:  MIstatus::success - Functional succeeded.
708 //          MIstatus::failure - Functional failed.
709 // Throws:  None.
710 //--
Execute()711 bool CMICmdCmdExecStepInstruction::Execute() {
712   CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
713 
714   // Retrieve the --thread option's thread ID (only 1)
715   MIuint64 nThreadId = UINT64_MAX;
716   if (pArgThread->GetFound() &&
717       !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
718     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
719                                    m_cmdData.strMiCmd.c_str(),
720                                    m_constStrArgThread.c_str()));
721     return MIstatus::failure;
722   }
723 
724   CMICmnLLDBDebugSessionInfo &rSessionInfo(
725       CMICmnLLDBDebugSessionInfo::Instance());
726 
727   lldb::SBError error;
728   if (nThreadId != UINT64_MAX) {
729     lldb::SBThread sbThread =
730         rSessionInfo.GetProcess().GetThreadByIndexID(nThreadId);
731     if (!sbThread.IsValid()) {
732       SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID),
733                                      m_cmdData.strMiCmd.c_str(),
734                                      m_constStrArgThread.c_str()));
735       return MIstatus::failure;
736     }
737     sbThread.StepInstruction(false, error);
738   } else
739     rSessionInfo.GetProcess().GetSelectedThread().StepInstruction(
740         false, error);
741 
742   return HandleSBError(error);
743 }
744 
745 //++
746 //------------------------------------------------------------------------------------
747 // Details: The invoker requires this function. The command prepares a MI Record
748 // Result
749 //          for the work carried out in the Execute().
750 // Type:    Overridden.
751 // Args:    None.
752 // Return:  MIstatus::success - Functional succeeded.
753 //          MIstatus::failure - Functional failed.
754 // Throws:  None.
755 //--
Acknowledge()756 bool CMICmdCmdExecStepInstruction::Acknowledge() {
757   m_miResultRecord = CMICmnMIResultRecord(
758       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
759   return MIstatus::success;
760 }
761 
762 //++
763 //------------------------------------------------------------------------------------
764 // Details: Required by the CMICmdFactory when registering *this command. The
765 // factory
766 //          calls this function to create an instance of *this command.
767 // Type:    Static method.
768 // Args:    None.
769 // Return:  CMICmdBase * - Pointer to a new command.
770 // Throws:  None.
771 //--
CreateSelf()772 CMICmdBase *CMICmdCmdExecStepInstruction::CreateSelf() {
773   return new CMICmdCmdExecStepInstruction();
774 }
775 
776 //---------------------------------------------------------------------------------------
777 //---------------------------------------------------------------------------------------
778 //---------------------------------------------------------------------------------------
779 
780 //++
781 //------------------------------------------------------------------------------------
782 // Details: CMICmdCmdExecFinish constructor.
783 // Type:    Method.
784 // Args:    None.
785 // Return:  None.
786 // Throws:  None.
787 //--
CMICmdCmdExecFinish()788 CMICmdCmdExecFinish::CMICmdCmdExecFinish() {
789   // Command factory matches this name with that received from the stdin stream
790   m_strMiCmd = "exec-finish";
791 
792   // Required by the CMICmdFactory when registering *this command
793   m_pSelfCreatorFn = &CMICmdCmdExecFinish::CreateSelf;
794 }
795 
796 //++
797 //------------------------------------------------------------------------------------
798 // Details: CMICmdCmdExecFinish destructor.
799 // Type:    Overrideable.
800 // Args:    None.
801 // Return:  None.
802 // Throws:  None.
803 //--
~CMICmdCmdExecFinish()804 CMICmdCmdExecFinish::~CMICmdCmdExecFinish() {}
805 
806 //++
807 //------------------------------------------------------------------------------------
808 // Details: The invoker requires this function. The parses the command line
809 // options
810 //          arguments to extract values for each of those arguments.
811 // Type:    Overridden.
812 // Args:    None.
813 // Return:  MIstatus::success - Functional succeeded.
814 //          MIstatus::failure - Functional failed.
815 // Throws:  None.
816 //--
ParseArgs()817 bool CMICmdCmdExecFinish::ParseArgs() { 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 //--
Execute()831 bool CMICmdCmdExecFinish::Execute() {
832   CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
833 
834   // Retrieve the --thread option's thread ID (only 1)
835   MIuint64 nThreadId = UINT64_MAX;
836   if (pArgThread->GetFound() &&
837       !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
838     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
839                                    m_cmdData.strMiCmd.c_str(),
840                                    m_constStrArgThread.c_str()));
841     return MIstatus::failure;
842   }
843 
844   CMICmnLLDBDebugSessionInfo &rSessionInfo(
845       CMICmnLLDBDebugSessionInfo::Instance());
846 
847   lldb::SBError error;
848   if (nThreadId != UINT64_MAX) {
849     lldb::SBThread sbThread =
850         rSessionInfo.GetProcess().GetThreadByIndexID(nThreadId);
851     if (!sbThread.IsValid()) {
852       SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID),
853                                      m_cmdData.strMiCmd.c_str(),
854                                      m_constStrArgThread.c_str()));
855       return MIstatus::failure;
856     }
857     sbThread.StepOut(error);
858   } else
859     rSessionInfo.GetProcess().GetSelectedThread().StepOut(error);
860 
861   return HandleSBError(error);
862 }
863 
864 //++
865 //------------------------------------------------------------------------------------
866 // Details: The invoker requires this function. The command prepares a MI Record
867 // Result
868 //          for the work carried out in the Execute().
869 // Type:    Overridden.
870 // Args:    None.
871 // Return:  MIstatus::success - Functional succeeded.
872 //          MIstatus::failure - Functional failed.
873 // Throws:  None.
874 //--
Acknowledge()875 bool CMICmdCmdExecFinish::Acknowledge() {
876   m_miResultRecord = CMICmnMIResultRecord(
877       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
878   return MIstatus::success;
879 }
880 
881 //++
882 //------------------------------------------------------------------------------------
883 // Details: Required by the CMICmdFactory when registering *this command. The
884 // factory
885 //          calls this function to create an instance of *this command.
886 // Type:    Static method.
887 // Args:    None.
888 // Return:  CMICmdBase * - Pointer to a new command.
889 // Throws:  None.
890 //--
CreateSelf()891 CMICmdBase *CMICmdCmdExecFinish::CreateSelf() {
892   return new CMICmdCmdExecFinish();
893 }
894 
895 //---------------------------------------------------------------------------------------
896 //---------------------------------------------------------------------------------------
897 //---------------------------------------------------------------------------------------
898 
899 //++
900 //------------------------------------------------------------------------------------
901 // Details: CMICmdCmdExecInterrupt constructor.
902 // Type:    Method.
903 // Args:    None.
904 // Return:  None.
905 // Throws:  None.
906 //--
CMICmdCmdExecInterrupt()907 CMICmdCmdExecInterrupt::CMICmdCmdExecInterrupt() {
908   // Command factory matches this name with that received from the stdin stream
909   m_strMiCmd = "exec-interrupt";
910 
911   // Required by the CMICmdFactory when registering *this command
912   m_pSelfCreatorFn = &CMICmdCmdExecInterrupt::CreateSelf;
913 }
914 
915 //++
916 //------------------------------------------------------------------------------------
917 // Details: CMICmdCmdExecInterrupt destructor.
918 // Type:    Overrideable.
919 // Args:    None.
920 // Return:  None.
921 // Throws:  None.
922 //--
~CMICmdCmdExecInterrupt()923 CMICmdCmdExecInterrupt::~CMICmdCmdExecInterrupt() {}
924 
925 //++
926 //------------------------------------------------------------------------------------
927 // Details: The invoker requires this function. The command does work in this
928 // function.
929 //          The command is likely to communicate with the LLDB SBDebugger in
930 //          here.
931 // Type:    Overridden.
932 // Args:    None.
933 // Return:  MIstatus::success - Functional succeeded.
934 //          MIstatus::failure - Functional failed.
935 // Throws:  None.
936 //--
Execute()937 bool CMICmdCmdExecInterrupt::Execute() {
938   const auto successHandler = [this] {
939     // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
940     if (!CMIDriver::Instance().SetDriverStateRunningNotDebugging()) {
941       const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription());
942       SetErrorDescription(CMIUtilString::Format(
943           MIRSRC(IDS_CMD_ERR_SET_NEW_DRIVER_STATE),
944           m_cmdData.strMiCmd.c_str(),
945           rErrMsg.c_str()));
946       return MIstatus::failure;
947     }
948     return MIstatus::success;
949   };
950 
951   return HandleSBErrorWithSuccess(
952       CMICmnLLDBDebugSessionInfo::Instance().GetProcess().Stop(),
953       successHandler);
954 }
955 
956 //++
957 //------------------------------------------------------------------------------------
958 // Details: The invoker requires this function. The command prepares a MI Record
959 // Result
960 //          for the work carried out in the Execute().
961 // Type:    Overridden.
962 // Args:    None.
963 // Return:  MIstatus::success - Functional succeeded.
964 //          MIstatus::failure - Functional failed.
965 // Throws:  None.
966 //--
Acknowledge()967 bool CMICmdCmdExecInterrupt::Acknowledge() {
968   m_miResultRecord = CMICmnMIResultRecord(
969       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
970   return MIstatus::success;
971 }
972 
973 //++
974 //------------------------------------------------------------------------------------
975 // Details: Required by the CMICmdFactory when registering *this command. The
976 // factory
977 //          calls this function to create an instance of *this command.
978 // Type:    Static method.
979 // Args:    None.
980 // Return:  CMICmdBase * - Pointer to a new command.
981 // Throws:  None.
982 //--
CreateSelf()983 CMICmdBase *CMICmdCmdExecInterrupt::CreateSelf() {
984   return new CMICmdCmdExecInterrupt();
985 }
986 
987 //---------------------------------------------------------------------------------------
988 //---------------------------------------------------------------------------------------
989 //---------------------------------------------------------------------------------------
990 
991 //++
992 //------------------------------------------------------------------------------------
993 // Details: CMICmdCmdExecArguments constructor.
994 // Type:    Method.
995 // Args:    None.
996 // Return:  None.
997 // Throws:  None.
998 //--
CMICmdCmdExecArguments()999 CMICmdCmdExecArguments::CMICmdCmdExecArguments()
1000     : m_constStrArgArguments("arguments") {
1001   // Command factory matches this name with that received from the stdin stream
1002   m_strMiCmd = "exec-arguments";
1003 
1004   // Required by the CMICmdFactory when registering *this command
1005   m_pSelfCreatorFn = &CMICmdCmdExecArguments::CreateSelf;
1006 }
1007 
1008 //++
1009 //------------------------------------------------------------------------------------
1010 // Details: CMICmdCmdExecArguments destructor.
1011 // Type:    Overrideable.
1012 // Args:    None.
1013 // Return:  None.
1014 // Throws:  None.
1015 //--
~CMICmdCmdExecArguments()1016 CMICmdCmdExecArguments::~CMICmdCmdExecArguments() {}
1017 
1018 //++
1019 //------------------------------------------------------------------------------------
1020 // Details: The invoker requires this function. The parses the command line
1021 // options
1022 //          arguments to extract values for each of those arguments.
1023 // Type:    Overridden.
1024 // Args:    None.
1025 // Return:  MIstatus::success - Function succeeded.
1026 //          MIstatus::failure - Function failed.
1027 // Throws:  None.
1028 //--
ParseArgs()1029 bool CMICmdCmdExecArguments::ParseArgs() {
1030   m_setCmdArgs.Add(new CMICmdArgValListOfN(
1031       m_constStrArgArguments, false, true,
1032       CMICmdArgValListBase::eArgValType_StringAnything));
1033   return ParseValidateCmdOptions();
1034 }
1035 
1036 //++
1037 //------------------------------------------------------------------------------------
1038 // Details: The invoker requires this function. The command does work in this
1039 // function.
1040 //          The command is likely to communicate with the LLDB SBDebugger in
1041 //          here.
1042 // Type:    Overridden.
1043 // Args:    None.
1044 // Return:  MIstatus::success - Function succeeded.
1045 //          MIstatus::failure - Function failed.
1046 // Throws:  None.
1047 //--
Execute()1048 bool CMICmdCmdExecArguments::Execute() {
1049   CMICMDBASE_GETOPTION(pArgArguments, ListOfN, m_constStrArgArguments);
1050 
1051   CMICmnLLDBDebugSessionInfo &rSessionInfo(
1052       CMICmnLLDBDebugSessionInfo::Instance());
1053   lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
1054   if (!sbTarget.IsValid()) {
1055     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT),
1056                                    m_cmdData.strMiCmd.c_str()));
1057     return MIstatus::failure;
1058   }
1059 
1060   lldb::SBLaunchInfo sbLaunchInfo = sbTarget.GetLaunchInfo();
1061   sbLaunchInfo.SetArguments(NULL, false);
1062 
1063   CMIUtilString strArg;
1064   size_t nArgIndex = 0;
1065   while (pArgArguments->GetExpectedOption<CMICmdArgValString, CMIUtilString>(
1066       strArg, nArgIndex)) {
1067     const char *argv[2] = {strArg.c_str(), NULL};
1068     sbLaunchInfo.SetArguments(argv, true);
1069     ++nArgIndex;
1070   }
1071 
1072   sbTarget.SetLaunchInfo(sbLaunchInfo);
1073 
1074   return MIstatus::success;
1075 }
1076 
1077 //++
1078 //------------------------------------------------------------------------------------
1079 // Details: The invoker requires this function. The command prepares a MI Record
1080 // Result
1081 //          for the work carried out in the Execute().
1082 // Type:    Overridden.
1083 // Args:    None.
1084 // Return:  MIstatus::success - Function succeeded.
1085 //          MIstatus::failure - Function failed.
1086 // Throws:  None.
1087 //--
Acknowledge()1088 bool CMICmdCmdExecArguments::Acknowledge() {
1089   m_miResultRecord = CMICmnMIResultRecord(
1090       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
1091   return MIstatus::success;
1092 }
1093 
1094 //++
1095 //------------------------------------------------------------------------------------
1096 // Details: Required by the CMICmdFactory when registering *this command. The
1097 // factory
1098 //          calls this function to create an instance of *this command.
1099 // Type:    Static method.
1100 // Args:    None.
1101 // Return:  CMICmdBase * - Pointer to a new command.
1102 // Throws:  None.
1103 //--
CreateSelf()1104 CMICmdBase *CMICmdCmdExecArguments::CreateSelf() {
1105   return new CMICmdCmdExecArguments();
1106 }
1107 
1108 //---------------------------------------------------------------------------------------
1109 //---------------------------------------------------------------------------------------
1110 //---------------------------------------------------------------------------------------
1111 
1112 //++
1113 //------------------------------------------------------------------------------------
1114 // Details: CMICmdCmdExecAbort constructor.
1115 // Type:    Method.
1116 // Args:    None.
1117 // Return:  None.
1118 // Throws:  None.
1119 //--
CMICmdCmdExecAbort()1120 CMICmdCmdExecAbort::CMICmdCmdExecAbort() {
1121   // Command factory matches this name with that received from the stdin stream
1122   m_strMiCmd = "exec-abort";
1123 
1124   // Required by the CMICmdFactory when registering *this command
1125   m_pSelfCreatorFn = &CMICmdCmdExecAbort::CreateSelf;
1126 }
1127 
1128 //++
1129 //------------------------------------------------------------------------------------
1130 // Details: CMICmdCmdExecAbort destructor.
1131 // Type:    Overrideable.
1132 // Args:    None.
1133 // Return:  None.
1134 // Throws:  None.
1135 //--
~CMICmdCmdExecAbort()1136 CMICmdCmdExecAbort::~CMICmdCmdExecAbort() {}
1137 
1138 //++
1139 //------------------------------------------------------------------------------------
1140 // Details: The invoker requires this function. The command does work in this
1141 // function.
1142 //          The command is likely to communicate with the LLDB SBDebugger in
1143 //          here.
1144 // Type:    Overridden.
1145 // Args:    None.
1146 // Return:  MIstatus::success - Function succeeded.
1147 //          MIstatus::failure - Function failed.
1148 // Throws:  None.
1149 //--
Execute()1150 bool CMICmdCmdExecAbort::Execute() {
1151   CMICmnLLDBDebugSessionInfo &rSessionInfo(
1152       CMICmnLLDBDebugSessionInfo::Instance());
1153   lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
1154   if (!sbProcess.IsValid()) {
1155     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS),
1156                                    m_cmdData.strMiCmd.c_str()));
1157     return MIstatus::failure;
1158   }
1159 
1160   lldb::SBError sbError = sbProcess.Destroy();
1161   if (sbError.Fail()) {
1162     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDBPROCESS_DESTROY),
1163                                    m_cmdData.strMiCmd.c_str(),
1164                                    sbError.GetCString()));
1165     return MIstatus::failure;
1166   }
1167 
1168   return MIstatus::success;
1169 }
1170 
1171 //++
1172 //------------------------------------------------------------------------------------
1173 // Details: The invoker requires this function. The command prepares a MI Record
1174 // Result
1175 //          for the work carried out in the Execute().
1176 // Type:    Overridden.
1177 // Args:    None.
1178 // Return:  MIstatus::success - Function succeeded.
1179 //          MIstatus::failure - Function failed.
1180 // Throws:  None.
1181 //--
Acknowledge()1182 bool CMICmdCmdExecAbort::Acknowledge() {
1183   m_miResultRecord = CMICmnMIResultRecord(
1184       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
1185   return MIstatus::success;
1186 }
1187 
1188 //++
1189 //------------------------------------------------------------------------------------
1190 // Details: Required by the CMICmdFactory when registering *this command. The
1191 // factory
1192 //          calls this function to create an instance of *this command.
1193 // Type:    Static method.
1194 // Args:    None.
1195 // Return:  CMICmdBase * - Pointer to a new command.
1196 // Throws:  None.
1197 //--
CreateSelf()1198 CMICmdBase *CMICmdCmdExecAbort::CreateSelf() {
1199   return new CMICmdCmdExecAbort();
1200 }
1201