• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "tooling/client/utils/cli_command.h"
17 
18 #include <functional>
19 #include <iostream>
20 
21 #include "tooling/client/domain/debugger_client.h"
22 #include "tooling/client/domain/runtime_client.h"
23 #include "common/log_wrapper.h"
24 #include "tooling/client/manager/breakpoint_manager.h"
25 #include "tooling/client/manager/domain_manager.h"
26 #include "tooling/client/manager/stack_manager.h"
27 #include "tooling/client/manager/variable_manager.h"
28 #include "tooling/client/session/session.h"
29 
30 namespace OHOS::ArkCompiler::Toolchain {
31 const std::string HELP_MSG = "usage: <command> <options>\n"
32     " These are common commands list:\n"
33     "  allocationtrack(at)                           allocation-track-start with options\n"
34     "  allocationtrack-stop(at-stop)                 allocation-track-stop\n"
35     "  heapdump(hd)                                  heapdump with options\n"
36     "  heapprofiler-enable(hp-enable)                heapdump enable\n"
37     "  heapprofiler-disable(hp-disable)              heapdump disable\n"
38     "  sampling(sampling)                            heapprofiler sampling\n"
39     "  sampling-stop(sampling-stop)                  heapprofiler sampling stop\n"
40     "  collectgarbage(gc)                            heapprofiler collectgarbage\n"
41     "  cpuprofile(cp)                                cpuprofile start\n"
42     "  cpuprofile-stop(cp-stop)                      cpuprofile stop\n"
43     "  cpuprofile-enable(cp-enable)                  cpuprofile enable\n"
44     "  cpuprofile-disable(cp-disable)                cpuprofile disable\n"
45     "  cpuprofile-show(cp-show)                      cpuprofile show\n"
46     "  cpuprofile-setSamplingInterval(cp-ssi)        cpuprofile setSamplingInterval\n"
47     "  runtime-enable(rt-enable)                     runtime enable\n"
48     "  heapusage(hu)                                 runtime getHeapUsage\n"
49     "  break(b)                                      break with options\n"
50     "  backtrack(bt)                                 backtrace\n"
51     "  continue(c)                                   continue\n"
52     "  delete(d)                                     delete with options\n"
53     "  disable                                       disable\n"
54     "  display                                       display\n"
55     "  enable                                        debugger enable\n"
56     "  finish(fin)                                   finish\n"
57     "  frame(f)                                      frame\n"
58     "  help(h)                                       list available commands\n"
59     "  ignore(ig)                                    ignore\n"
60     "  infobreakpoints(infob)                        info-breakpoints\n"
61     "  infosource(infos)                             info-source\n"
62     "  jump(j)                                       jump\n"
63     "  list(l)                                       list\n"
64     "  next(n)                                       next\n"
65     "  print(p)                                      print with options\n"
66     "  ptype                                         ptype\n"
67     "  quit(q)                                       quit\n"
68     "  run(r)                                        run\n"
69     "  setvar(sv)                                    set value with options\n"
70     "  step(s)                                       step\n"
71     "  undisplay                                     undisplay\n"
72     "  watch(wa)                                     watch\n"
73     "  resume                                        resume\n"
74     "  showstack(ss)                                 showstack\n"
75     "  step-into(si)                                 step-into\n"
76     "  step-out(so)                                  step-out\n"
77     "  step-over(sov)                                step-over\n"
78     "  runtime-disable                               rt-disable\n"
79     "  session-new                                   add new session\n"
80     "  session-remove                                del a session\n"
81     "  session-list                                  list all sessions\n"
82     "  session                                       switch session\n"
83     "  forall                                        command for all sessions\n"
84     "  success                                       test success\n"
85     "  fail                                          test fail\n";
86 
87 const std::vector<std::string> cmdList = {
88     "allocationtrack",
89     "allocationtrack-stop",
90     "heapdump",
91     "heapprofiler-enable",
92     "heapprofiler-disable",
93     "sampling",
94     "sampling-stop",
95     "collectgarbage",
96     "cpuprofile",
97     "cpuprofile-stop",
98     "cpuprofile-enable",
99     "cpuprofile-disable",
100     "cpuprofile-show",
101     "cpuprofile-setSamplingInterval",
102     "runtime-enable",
103     "heapusage",
104     "break",
105     "backtrack",
106     "continue",
107     "delete",
108     "disable",
109     "display",
110     "enable",
111     "finish",
112     "frame",
113     "help",
114     "ignore",
115     "infobreakpoints",
116     "infosource",
117     "jump",
118     "list",
119     "next",
120     "print",
121     "ptype",
122     "run",
123     "setvar",
124     "step",
125     "undisplay",
126     "watch",
127     "resume",
128     "step-into",
129     "step-out",
130     "step-over",
131     "runtime-disable",
132     "session-new",
133     "session-remove",
134     "session-list",
135     "session",
136     "success",
137     "fail"
138 };
139 
ExecCommand()140 ErrCode CliCommand::ExecCommand()
141 {
142     CreateCommandMap();
143 
144     ErrCode result = OnCommand();
145     return result;
146 }
147 
CreateCommandMap()148 void CliCommand::CreateCommandMap()
149 {
150     commandMap_ = {
151         {std::make_pair("allocationtrack", "at"), std::bind(&CliCommand::HeapProfilerCommand, this, "allocationtrack")},
152         {std::make_pair("allocationtrack-stop", "at-stop"),
153             std::bind(&CliCommand::HeapProfilerCommand, this, "allocationtrack-stop")},
154         {std::make_pair("heapdump", "hd"), std::bind(&CliCommand::HeapProfilerCommand, this, "heapdump")},
155         {std::make_pair("heapprofiler-enable", "hp-enable"),
156             std::bind(&CliCommand::HeapProfilerCommand, this, "heapprofiler-enable")},
157         {std::make_pair("heapprofiler-disable", "hp-disable"),
158             std::bind(&CliCommand::HeapProfilerCommand, this, "heapprofiler-disable")},
159         {std::make_pair("sampling", "sampling"), std::bind(&CliCommand::HeapProfilerCommand, this, "sampling")},
160         {std::make_pair("sampling-stop", "sampling-stop"),
161             std::bind(&CliCommand::HeapProfilerCommand, this, "sampling-stop")},
162         {std::make_pair("collectgarbage", "gc"), std::bind(&CliCommand::HeapProfilerCommand, this, "collectgarbage")},
163         {std::make_pair("cpuprofile", "cp"), std::bind(&CliCommand::CpuProfileCommand, this, "cpuprofile")},
164         {std::make_pair("cpuprofile-stop", "cp-stop"),
165             std::bind(&CliCommand::CpuProfileCommand, this, "cpuprofile-stop")},
166         {std::make_pair("cpuprofile-enable", "cp-enable"),
167             std::bind(&CliCommand::CpuProfileCommand, this, "cpuprofile-enable")},
168         {std::make_pair("cpuprofile-disable", "cp-disable"),
169             std::bind(&CliCommand::CpuProfileCommand, this, "cpuprofile-disable")},
170         {std::make_pair("cpuprofile-show", "cp-show"),
171             std::bind(&CliCommand::CpuProfileCommand, this, "cpuprofile-show")},
172         {std::make_pair("cpuprofile-setSamplingInterval", "cp-ssi"),
173             std::bind(&CliCommand::CpuProfileCommand, this, "cpuprofile-setSamplingInterval")},
174         {std::make_pair("runtime-enable", "rt-enable"), std::bind(&CliCommand::RuntimeCommand, this, "runtime-enable")},
175         {std::make_pair("heapusage", "hu"), std::bind(&CliCommand::RuntimeCommand, this, "heapusage")},
176         {std::make_pair("break", "b"), std::bind(&CliCommand::BreakCommand, this, "break")},
177         {std::make_pair("backtrack", "bt"), std::bind(&CliCommand::DebuggerCommand, this, "backtrack")},
178         {std::make_pair("continue", "c"), std::bind(&CliCommand::DebuggerCommand, this, "continue")},
179         {std::make_pair("delete", "d"), std::bind(&CliCommand::DeleteCommand, this, "delete")},
180         {std::make_pair("disable", "disable"), std::bind(&CliCommand::DebuggerCommand, this, "disable")},
181         {std::make_pair("display", "display"), std::bind(&CliCommand::DisplayCommand, this, "display")},
182         {std::make_pair("enable", "enable"), std::bind(&CliCommand::DebuggerCommand, this, "enable")},
183         {std::make_pair("finish", "fin"), std::bind(&CliCommand::DebuggerCommand, this, "finish")},
184         {std::make_pair("frame", "f"), std::bind(&CliCommand::DebuggerCommand, this, "frame")},
185         {std::make_pair("enable-launch-accelerate", "enable-acc"),
186             std::bind(&CliCommand::DebuggerCommand, this, "enable-launch-accelerate")},
187         {std::make_pair("saveAllPossibleBreakpoints", "b-new"),
188             std::bind(&CliCommand::SaveAllPossibleBreakpointsCommand, this, "saveAllPossibleBreakpoints")},
189     };
190     CreateOtherCommandMap();
191 }
CreateOtherCommandMap()192 void CliCommand::CreateOtherCommandMap()
193 {
194     commandMap_.insert({
195         {std::make_pair("help", "h"), std::bind(&CliCommand::ExecHelpCommand, this)},
196         {std::make_pair("ignore", "ig"), std::bind(&CliCommand::DebuggerCommand, this, "ignore")},
197         {std::make_pair("infobreakpoints", "infob"), std::bind(&CliCommand::DebuggerCommand, this, "infobreakpoints")},
198         {std::make_pair("infosource", "infos"), std::bind(&CliCommand::InfosourceCommand, this, "infosource")},
199         {std::make_pair("jump", "j"), std::bind(&CliCommand::DebuggerCommand, this, "jump")},
200         {std::make_pair("list", "l"), std::bind(&CliCommand::ListCommand, this, "list")},
201         {std::make_pair("next", "n"), std::bind(&CliCommand::DebuggerCommand, this, "next")},
202         {std::make_pair("print", "p"), std::bind(&CliCommand::PrintCommand, this, "print")},
203         {std::make_pair("ptype", "ptype"), std::bind(&CliCommand::DebuggerCommand, this, "ptype")},
204         {std::make_pair("run", "r"), std::bind(&CliCommand::RuntimeCommand, this, "run")},
205         {std::make_pair("setvar", "sv"), std::bind(&CliCommand::DebuggerCommand, this, "setvar")},
206         {std::make_pair("step", "s"), std::bind(&CliCommand::DebuggerCommand, this, "step")},
207         {std::make_pair("undisplay", "undisplay"), std::bind(&CliCommand::DebuggerCommand, this, "undisplay")},
208         {std::make_pair("watch", "wa"), std::bind(&CliCommand::WatchCommand, this, "watch")},
209         {std::make_pair("resume", "resume"), std::bind(&CliCommand::DebuggerCommand, this, "resume")},
210         {std::make_pair("showstack", "ss"), std::bind(&CliCommand::ShowstackCommand, this, "showstack")},
211         {std::make_pair("step-into", "si"), std::bind(&CliCommand::StepCommand, this, "step-into")},
212         {std::make_pair("step-out", "so"), std::bind(&CliCommand::StepCommand, this, "step-out")},
213         {std::make_pair("step-over", "sov"), std::bind(&CliCommand::StepCommand, this, "step-over")},
214         {std::make_pair("runtime-disable", "rt-disable"),
215             std::bind(&CliCommand::RuntimeCommand, this, "runtime-disable")},
216         {std::make_pair("session-new", "session-new"),
217             std::bind(&CliCommand::SessionAddCommand, this, "session-new")},
218         {std::make_pair("session-remove", "session-remove"),
219             std::bind(&CliCommand::SessionDelCommand, this, "session-remove")},
220         {std::make_pair("session-list", "session-list"),
221             std::bind(&CliCommand::SessionListCommand, this, "session-list")},
222         {std::make_pair("session", "session"),
223             std::bind(&CliCommand::SessionSwitchCommand, this, "session")},
224         {std::make_pair("success", "success"),
225             std::bind(&CliCommand::TestCommand, this, "success")},
226         {std::make_pair("fail", "fail"),
227             std::bind(&CliCommand::TestCommand, this, "fail")},
228     });
229 }
230 
HeapProfilerCommand(const std::string & cmd)231 ErrCode CliCommand::HeapProfilerCommand(const std::string &cmd)
232 {
233     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
234     DomainManager &domainManager = session->GetDomainManager();
235     HeapProfilerClient &heapProfilerClient = domainManager.GetHeapProfilerClient();
236     VecStr argList = GetArgList();
237     if ((cmd == "allocationtrack" || cmd == "sampling") && !argList.empty()) {
238         std::cout << "This command does not need to follow a suffix" << std::endl;
239         return ErrCode::ERR_FAIL;
240     } else {
241         if (argList.empty()) {
242             argList.push_back("/data/");
243             std::cout << "exe success, cmd is " << cmd << std::endl;
244         } else {
245             const std::string &arg = argList[0];
246             std::string pathDump = arg;
247             std::ifstream fileExit(pathDump.c_str());
248             if (fileExit.good() && (pathDump[0] == pathDump[pathDump.size()-1]) && (GetArgList().size() == 1)) {
249                 std::cout << "exe success, cmd is " << cmd << std::endl;
250             } else if (GetArgList().size() > 1) {
251                 std::cout << "The folder path may contains spaces" << std::endl;
252                 return ErrCode::ERR_FAIL;
253             } else if (pathDump[0] != pathDump[pathDump.size()-1]) {
254                 std::cout << "The folder path format is incorrect :" << pathDump << std::endl;
255                 std::cout << "Attention: Check for symbols /" << std::endl;
256                 return ErrCode::ERR_FAIL;
257             } else {
258                 std::cout << "The folder path does not exist :" << pathDump << std::endl;
259                 return ErrCode::ERR_FAIL;
260             }
261         }
262     }
263 
264     bool result = heapProfilerClient.DispatcherCmd(cmd, argList[0]);
265     return result ? ErrCode::ERR_OK : ErrCode::ERR_FAIL;
266 }
267 
CpuProfileCommand(const std::string & cmd)268 ErrCode CliCommand::CpuProfileCommand(const std::string &cmd)
269 {
270     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
271     DomainManager &domainManager = session->GetDomainManager();
272     ProfilerClient &profilerClient = domainManager.GetProfilerClient();
273     ProfilerSingleton &pro = session->GetProfilerSingleton();
274     VecStr argList = GetArgList();
275     if (cmd == "cpuprofile") {
276         if (argList.empty()) {
277             std::cout << "exe success, cmd is " << cmd << std::endl;
278         } else {
279             std::cout << "This command does not need to follow a suffix" << std::endl;
280             return ErrCode::ERR_FAIL;
281         }
282     }
283     if (cmd == "cpuprofile-show") {
284         std::cout << "exe success, cmd is " << cmd << std::endl;
285         pro.ShowCpuFile();
286         return ErrCode::ERR_OK;
287     }
288     if (cmd == "cpuprofile-setSamplingInterval") {
289         std::cout << "exe success, cmd is " << cmd << std::endl;
290         profilerClient.SetSamplingInterval(std::atoi(GetArgList()[0].c_str()));
291     }
292     if (cmd == "cpuprofile-stop" && GetArgList().size() == 1) {
293         pro.SetAddress(GetArgList()[0]);
294         const std::string &arg = argList[0];
295         std::string pathCpuPro = arg;
296         std::ifstream fileExit(pathCpuPro.c_str());
297         if (fileExit.good() && (pathCpuPro[0] == pathCpuPro[pathCpuPro.size()-1])) {
298             std::cout << "exe success, cmd is " << cmd << std::endl;
299         } else if (pathCpuPro[0] != pathCpuPro[pathCpuPro.size()-1]) {
300             std::cout << "The folder path format is incorrect :" << pathCpuPro << std::endl;
301             std::cout << "Attention: Check for symbols /" << std::endl;
302             return ErrCode::ERR_FAIL;
303         } else {
304             std::cout << "The folder path does not exist :" << pathCpuPro << std::endl;
305             return ErrCode::ERR_FAIL;
306         }
307     }
308     bool result = profilerClient.DispatcherCmd(cmd);
309     return result ? ErrCode::ERR_OK : ErrCode::ERR_FAIL;
310 }
311 
DebuggerCommand(const std::string & cmd)312 ErrCode CliCommand::DebuggerCommand(const std::string &cmd)
313 {
314     if (GetArgList().size()) {
315         OutputCommand(cmd, false);
316         return ErrCode::ERR_FAIL;
317     }
318 
319     bool result = false;
320     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
321     DebuggerClient &debuggerCli = session->GetDomainManager().GetDebuggerClient();
322 
323     result = debuggerCli.DispatcherCmd(cmd);
324     OutputCommand(cmd, true);
325     return result ? ErrCode::ERR_OK : ErrCode::ERR_FAIL;
326 }
327 
RuntimeCommand(const std::string & cmd)328 ErrCode CliCommand::RuntimeCommand(const std::string &cmd)
329 {
330     if (GetArgList().size()) {
331         OutputCommand(cmd, false);
332         return ErrCode::ERR_FAIL;
333     }
334     bool result = false;
335     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
336     RuntimeClient &runtimeClient = session->GetDomainManager().GetRuntimeClient();
337 
338     result = runtimeClient.DispatcherCmd(cmd);
339     if (result) {
340         runtimeClient.SetObjectId("0");
341     } else {
342         return ErrCode::ERR_FAIL;
343     }
344     OutputCommand(cmd, true);
345     return ErrCode::ERR_OK;
346 }
347 
BreakCommand(const std::string & cmd)348 ErrCode CliCommand::BreakCommand(const std::string &cmd)
349 {
350     bool result = false;
351     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
352     DebuggerClient &debuggerCli = session->GetDomainManager().GetDebuggerClient();
353     BreakPointManager &breakpointManager = session->GetBreakPointManager();
354     std::vector<Breaklocation> breaklist_ = breakpointManager.Getbreaklist();
355     if (GetArgList().size() == 2) { //2: two arguments
356         if (!Utils::IsNumber(GetArgList()[1])) {
357             OutputCommand(cmd, false);
358             return ErrCode::ERR_FAIL;
359         }
360         for (auto breakpoint : breaklist_) {
361             if (breakpoint.url == GetArgList()[0] &&
362                 std::stoi(breakpoint.lineNumber) + 1 == std::stoi(GetArgList()[1])) {
363                 std::cout << "the breakpoint is exist" << std::endl;
364                 return ErrCode::ERR_FAIL;
365             }
366         }
367         debuggerCli.AddBreakPointInfo(GetArgList()[0], std::stoi(GetArgList()[1]));
368     } else {
369         OutputCommand(cmd, false);
370         return ErrCode::ERR_FAIL;
371     }
372 
373     result = debuggerCli.DispatcherCmd(cmd);
374     OutputCommand(cmd, true);
375     return result ? ErrCode::ERR_OK : ErrCode::ERR_FAIL;
376 }
377 
DeleteCommand(const std::string & cmd)378 ErrCode CliCommand::DeleteCommand(const std::string &cmd)
379 {
380     bool result = false;
381     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
382     DebuggerClient &debuggerCli = session->GetDomainManager().GetDebuggerClient();
383     BreakPointManager &breakpoint = session->GetBreakPointManager();
384     if (GetArgList().size() == 1) {
385         if (!Utils::IsNumber(GetArgList()[0])) {
386             OutputCommand(cmd, false);
387             return ErrCode::ERR_FAIL;
388         }
389         int tmpNum = std::stoi(GetArgList()[0]);
390         size_t num = static_cast<size_t>(tmpNum);
391         if (breakpoint.Getbreaklist().size() >= num && num > 0) {
392             debuggerCli.AddBreakPointInfo(breakpoint.Getbreaklist()[num - 1].breakpointId, 0); // 1: breakpoinId
393             breakpoint.Deletebreaklist(num);
394         } else {
395             std::cout << "the breakpoint is not exist" << std::endl;
396             return ErrCode::ERR_FAIL;
397         }
398     } else {
399         OutputCommand(cmd, false);
400         return ErrCode::ERR_FAIL;
401     }
402     result = debuggerCli.DispatcherCmd(cmd);
403     OutputCommand(cmd, true);
404     return result ? ErrCode::ERR_OK : ErrCode::ERR_FAIL;
405 }
406 
DisplayCommand(const std::string & cmd)407 ErrCode CliCommand::DisplayCommand(const std::string &cmd)
408 {
409     if (GetArgList().size()) {
410         OutputCommand(cmd, false);
411         return ErrCode::ERR_FAIL;
412     }
413     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
414     BreakPointManager &breakpointManager = session->GetBreakPointManager();
415     breakpointManager.Show();
416     OutputCommand(cmd, true);
417     return ErrCode::ERR_OK;
418 }
419 
InfosourceCommand(const std::string & cmd)420 ErrCode CliCommand::InfosourceCommand(const std::string &cmd)
421 {
422     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
423     SourceManager &sourceManager = session->GetSourceManager();
424     if (GetArgList().size() > 1) {
425         OutputCommand(cmd, false);
426         return ErrCode::ERR_FAIL;
427     } else if (GetArgList().size() == 1) {
428         if (!Utils::IsNumber(GetArgList()[0])) {
429             OutputCommand(cmd, false);
430             return ErrCode::ERR_FAIL;
431         }
432         sourceManager.GetFileSource(std::stoi(GetArgList()[0]));
433     } else {
434         sourceManager.GetFileName();
435     }
436     OutputCommand(cmd, true);
437     return ErrCode::ERR_OK;
438 }
439 
ListCommand(const std::string & cmd)440 ErrCode CliCommand::ListCommand(const std::string &cmd)
441 {
442     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
443     SourceManager &sourceManager = session->GetSourceManager();
444     WatchManager &watchManager = session->GetWatchManager();
445     if (!watchManager.GetDebugState()) {
446         std::cout << "Start debugging your code before using the list command" << std::endl;
447         return ErrCode::ERR_FAIL;
448     }
449     if (GetArgList().size() > 2) { //2: two arguments
450         OutputCommand(cmd, false);
451         return ErrCode::ERR_FAIL;
452     } else if (GetArgList().size() == 2) { //2: two arguments
453         if (Utils::IsNumber(GetArgList()[0]) && Utils::IsNumber(GetArgList()[1])) {
454             sourceManager.GetListSource(GetArgList()[0], GetArgList()[1]);
455         } else {
456             OutputCommand(cmd, false);
457             return ErrCode::ERR_FAIL;
458         }
459     } else if (GetArgList().size() == 1) {
460         if (Utils::IsNumber(GetArgList()[0])) {
461             sourceManager.GetListSource(GetArgList()[0], "");
462         } else {
463             OutputCommand(cmd, false);
464             return ErrCode::ERR_FAIL;
465         }
466     } else {
467         sourceManager.GetListSource("", "");
468     }
469     OutputCommand(cmd, true);
470     return ErrCode::ERR_OK;
471 }
472 
StepCommand(const std::string & cmd)473 ErrCode CliCommand::StepCommand(const std::string &cmd)
474 {
475     if (GetArgList().size()) {
476         OutputCommand(cmd, false);
477         return ErrCode::ERR_FAIL;
478     }
479     bool result = false;
480     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
481     DebuggerClient &debuggerCli = session->GetDomainManager().GetDebuggerClient();
482     RuntimeClient &runtimeClient = session->GetDomainManager().GetRuntimeClient();
483     runtimeClient.SetIsInitializeTree(true);
484     result = debuggerCli.DispatcherCmd(cmd);
485     OutputCommand(cmd, true);
486     return result ? ErrCode::ERR_OK : ErrCode::ERR_FAIL;
487 }
488 
ShowstackCommand(const std::string & cmd)489 ErrCode CliCommand::ShowstackCommand(const std::string &cmd)
490 {
491     if (GetArgList().size()) {
492         OutputCommand(cmd, false);
493         return ErrCode::ERR_FAIL;
494     }
495     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
496     StackManager &stackManager = session->GetStackManager();
497     stackManager.ShowCallFrames();
498     OutputCommand(cmd, true);
499     return ErrCode::ERR_OK;
500 }
501 
PrintCommand(const std::string & cmd)502 ErrCode CliCommand::PrintCommand(const std::string &cmd)
503 {
504     if (GetArgList().size() > 1) {
505         OutputCommand(cmd, false);
506         return ErrCode::ERR_FAIL;
507     }
508     bool result = false;
509     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
510     RuntimeClient &runtimeClient = session->GetDomainManager().GetRuntimeClient();
511     if (GetArgList().size() == 1) {
512         runtimeClient.SetIsInitializeTree(false);
513         VariableManager &variableManager = session->GetVariableManager();
514         int32_t objectId = variableManager.FindObjectIdWithIndex(std::stoi(GetArgList()[0]));
515         runtimeClient.SetObjectId(std::to_string(objectId));
516     }
517     result = runtimeClient.DispatcherCmd(cmd);
518     if (result) {
519         runtimeClient.SetObjectId("0");
520     } else {
521         return ErrCode::ERR_FAIL;
522     }
523     OutputCommand(cmd, true);
524     return ErrCode::ERR_OK;
525 }
526 
WatchCommand(const std::string & cmd)527 ErrCode CliCommand::WatchCommand(const std::string &cmd)
528 {
529     if (GetArgList().size() != 1) {
530         OutputCommand(cmd, false);
531         return ErrCode::ERR_FAIL;
532     }
533     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
534     WatchManager &watchManager = session->GetWatchManager();
535     watchManager.AddWatchInfo(GetArgList()[0]);
536     if (watchManager.GetDebugState()) {
537         watchManager.SendRequestWatch(watchManager.GetWatchInfoSize() - 1, watchManager.GetCallFrameId());
538     } else {
539         std::cout << "Start debugging your code before using the watch command" << std::endl;
540         return ErrCode::ERR_FAIL;
541     }
542     OutputCommand(cmd, true);
543     return ErrCode::ERR_OK;
544 }
545 
SessionAddCommand(const std::string & cmd)546 ErrCode CliCommand::SessionAddCommand([[maybe_unused]] const std::string &cmd)
547 {
548     VecStr argList = GetArgList();
549     if (argList.size() == 1) {
550         if (!SessionManager::getInstance().CreateNewSession(argList[0])) {
551             OutputCommand(cmd, true);
552             return ErrCode::ERR_OK;
553         } else {
554             std::cout << "session add failed" << std::endl;
555         }
556     } else {
557         OutputCommand(cmd, false);
558     }
559 
560     return ErrCode::ERR_FAIL;
561 }
562 
SessionDelCommand(const std::string & cmd)563 ErrCode CliCommand::SessionDelCommand([[maybe_unused]] const std::string &cmd)
564 {
565     VecStr argList = GetArgList();
566     if (argList.size() == 1 && Utils::IsNumber(argList[0])) {
567         uint32_t sessionId = 0;
568         if (Utils::StrToUInt(argList[0].c_str(), &sessionId)) {
569             if (sessionId == 0) {
570                 std::cout << "cannot remove default session 0" << std::endl;
571                 return ErrCode::ERR_OK;
572             }
573             if (SessionManager::getInstance().DelSessionById(sessionId) == 0) {
574                 std::cout << "session remove success" << std::endl;
575                 return ErrCode::ERR_OK;
576             } else {
577                 std::cout << "sessionId is not exist" << std::endl;
578             }
579         }
580     } else {
581         OutputCommand(cmd, false);
582     }
583 
584     return ErrCode::ERR_FAIL;
585 }
586 
SessionListCommand(const std::string & cmd)587 ErrCode CliCommand::SessionListCommand([[maybe_unused]] const std::string &cmd)
588 {
589     if (GetArgList().size()) {
590         OutputCommand(cmd, false);
591         return ErrCode::ERR_FAIL;
592     }
593     SessionManager::getInstance().SessionList();
594     OutputCommand(cmd, true);
595     return ErrCode::ERR_OK;
596 }
597 
SessionSwitchCommand(const std::string & cmd)598 ErrCode CliCommand::SessionSwitchCommand([[maybe_unused]] const std::string &cmd)
599 {
600     VecStr argList = GetArgList();
601     if (argList.size() == 1 && Utils::IsNumber(argList[0])) {
602         uint32_t sessionId = 0;
603         if (Utils::StrToUInt(argList[0].c_str(), &sessionId)) {
604             if (SessionManager::getInstance().SessionSwitch(sessionId) == 0) {
605                 OutputCommand(cmd, true);
606                 return ErrCode::ERR_OK;
607             } else {
608                 std::cout << "sessionId is not exist" << std::endl;
609             }
610         }
611     } else {
612         OutputCommand(cmd, false);
613     }
614     return ErrCode::ERR_FAIL;
615 }
616 
TestCommand(const std::string & cmd)617 ErrCode CliCommand::TestCommand(const std::string &cmd)
618 {
619     if (cmd == "success" || cmd == "fail") {
620         Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
621         TestClient &testClient = session->GetDomainManager().GetTestClient();
622         testClient.DispatcherCmd(cmd);
623     } else {
624         return ErrCode::ERR_FAIL;
625     }
626     return ErrCode::ERR_OK;
627 }
628 
SaveAllPossibleBreakpointsCommand(const std::string & cmd)629 ErrCode CliCommand::SaveAllPossibleBreakpointsCommand(const std::string &cmd)
630 {
631     return BreakCommand(cmd);
632 }
633 
ExecHelpCommand()634 ErrCode CliCommand::ExecHelpCommand()
635 {
636     std::cout << HELP_MSG;
637     return ErrCode::ERR_OK;
638 }
639 
OutputCommand(const std::string & cmd,bool flag)640 void CliCommand::OutputCommand(const std::string &cmd, bool flag)
641 {
642     if (flag) {
643         std::cout << "exe success, cmd is " << cmd << std::endl;
644     } else {
645         std::cout << cmd << " parameters is incorrect" << std::endl;
646     }
647 }
648 
OnCommand()649 ErrCode CliCommand::OnCommand()
650 {
651     std::map<StrPair, std::function<ErrCode()>>::iterator it;
652     StrPair cmdPair;
653     bool haveCmdFlag = false;
654 
655     for (it = commandMap_.begin(); it != commandMap_.end(); it++) {
656         cmdPair = it->first;
657         if (!strcmp(cmdPair.first.c_str(), cmd_.c_str())
658             ||!strcmp(cmdPair.second.c_str(), cmd_.c_str())) {
659             auto respond = it->second;
660             return respond();
661         }
662     }
663 
664     for (unsigned int i = 0; i < cmdList.size(); i++) {
665         if (!strncmp(cmdList[i].c_str(), cmd_.c_str(), std::strlen(cmd_.c_str()))) {
666             haveCmdFlag = true;
667             std::cout << cmdList[i] << " ";
668         }
669     }
670 
671     if (haveCmdFlag) {
672         std::cout << std::endl;
673     } else {
674         ExecHelpCommand();
675     }
676 
677     return ErrCode::ERR_FAIL;
678 }
679 } // namespace OHOS::ArkCompiler::Toolchain
680