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