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