• 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/dynamic/client/utils/cli_command.h"
17 
18 namespace OHOS::ArkCompiler::Toolchain {
19 const std::string HELP_MSG = "usage: <command> <options>\n"
20     " These are common commands list:\n"
21     "  allocationtrack(at)                           allocation-track-start with options\n"
22     "  allocationtrack-stop(at-stop)                 allocation-track-stop\n"
23     "  heapdump(hd)                                  heapdump with options\n"
24     "  heapprofiler-enable(hp-enable)                heapdump enable\n"
25     "  heapprofiler-disable(hp-disable)              heapdump disable\n"
26     "  sampling(sampling)                            heapprofiler sampling\n"
27     "  sampling-stop(sampling-stop)                  heapprofiler sampling stop\n"
28     "  collectgarbage(gc)                            heapprofiler collectgarbage\n"
29     "  cpuprofile(cp)                                cpuprofile start\n"
30     "  cpuprofile-stop(cp-stop)                      cpuprofile stop\n"
31     "  cpuprofile-enable(cp-enable)                  cpuprofile enable\n"
32     "  cpuprofile-disable(cp-disable)                cpuprofile disable\n"
33     "  cpuprofile-show(cp-show)                      cpuprofile show\n"
34     "  cpuprofile-setSamplingInterval(cp-ssi)        cpuprofile setSamplingInterval\n"
35     "  runtime-enable(rt-enable)                     runtime enable\n"
36     "  heapusage(hu)                                 runtime getHeapUsage\n"
37     "  break(b)                                      break with options\n"
38     "  setSymbolicBreakpoints                        setSymbolicBreakpoints\n"
39     "  removeSymbolicBreakpoints                     removeSymbolicBreakpoints\n"
40     "  backtrack(bt)                                 backtrace\n"
41     "  continue(c)                                   continue\n"
42     "  delete(d)                                     delete with options\n"
43     "  disable                                       disable\n"
44     "  display                                       display\n"
45     "  enable                                        debugger enable\n"
46     "  finish(fin)                                   finish\n"
47     "  frame(f)                                      frame\n"
48     "  help(h)                                       list available commands\n"
49     "  ignore(ig)                                    ignore\n"
50     "  infobreakpoints(infob)                        info-breakpoints\n"
51     "  infosource(infos)                             info-source\n"
52     "  jump(j)                                       jump\n"
53     "  list(l)                                       list\n"
54     "  next(n)                                       next\n"
55     "  print(p)                                      print with options\n"
56     "  ptype                                         ptype\n"
57     "  quit(q)                                       quit\n"
58     "  run(r)                                        run\n"
59     "  setvar(sv)                                    set value with options\n"
60     "  step(s)                                       step\n"
61     "  undisplay                                     undisplay\n"
62     "  watch(wa)                                     watch\n"
63     "  resume                                        resume\n"
64     "  showstack(ss)                                 showstack\n"
65     "  step-into(si)                                 step-into\n"
66     "  step-out(so)                                  step-out\n"
67     "  step-over(sov)                                step-over\n"
68     "  runtime-disable                               rt-disable\n"
69     "  setAsyncStackDepth                            setAsyncStackDepth\n"
70     "  session-new                                   add new session\n"
71     "  session-remove                                del a session\n"
72     "  session-list                                  list all sessions\n"
73     "  session                                       switch session\n"
74     "  forall                                        command for all sessions\n"
75     "  success                                       test success\n"
76     "  fail                                          test fail\n";
77 
78 const std::vector<std::string> cmdList = {
79     "allocationtrack",
80     "allocationtrack-stop",
81     "heapdump",
82     "heapprofiler-enable",
83     "heapprofiler-disable",
84     "sampling",
85     "sampling-stop",
86     "collectgarbage",
87     "cpuprofile",
88     "cpuprofile-stop",
89     "cpuprofile-enable",
90     "cpuprofile-disable",
91     "cpuprofile-show",
92     "cpuprofile-setSamplingInterval",
93     "runtime-enable",
94     "heapusage",
95     "break",
96     "setSymbolicBreakpoints",
97     "removeSymbolicBreakpoints",
98     "backtrack",
99     "continue",
100     "delete",
101     "disable",
102     "display",
103     "enable",
104     "finish",
105     "frame",
106     "help",
107     "ignore",
108     "infobreakpoints",
109     "infosource",
110     "jump",
111     "list",
112     "next",
113     "print",
114     "ptype",
115     "run",
116     "setvar",
117     "step",
118     "undisplay",
119     "watch",
120     "resume",
121     "step-into",
122     "step-out",
123     "step-over",
124     "runtime-disable",
125     "setAsyncStackDepth",
126     "session-new",
127     "session-remove",
128     "session-list",
129     "session",
130     "success",
131     "fail"
132 };
133 
ExecCommand()134 ErrCode CliCommand::ExecCommand()
135 {
136     CreateCommandMap();
137 
138     ErrCode result = OnCommand();
139     return result;
140 }
141 
CreateCommandMap()142 void CliCommand::CreateCommandMap()
143 {
144     commandMap_ = {
145         {std::make_pair("allocationtrack", "at"), std::bind(&CliCommand::HeapProfilerCommand, this, "allocationtrack")},
146         {std::make_pair("allocationtrack-stop", "at-stop"),
147             std::bind(&CliCommand::HeapProfilerCommand, this, "allocationtrack-stop")},
148         {std::make_pair("heapdump", "hd"), std::bind(&CliCommand::HeapProfilerCommand, this, "heapdump")},
149         {std::make_pair("heapprofiler-enable", "hp-enable"),
150             std::bind(&CliCommand::HeapProfilerCommand, this, "heapprofiler-enable")},
151         {std::make_pair("heapprofiler-disable", "hp-disable"),
152             std::bind(&CliCommand::HeapProfilerCommand, this, "heapprofiler-disable")},
153         {std::make_pair("sampling", "sampling"), std::bind(&CliCommand::HeapProfilerCommand, this, "sampling")},
154         {std::make_pair("sampling-stop", "sampling-stop"),
155             std::bind(&CliCommand::HeapProfilerCommand, this, "sampling-stop")},
156         {std::make_pair("collectgarbage", "gc"), std::bind(&CliCommand::HeapProfilerCommand, this, "collectgarbage")},
157         {std::make_pair("cpuprofile", "cp"), std::bind(&CliCommand::CpuProfileCommand, this, "cpuprofile")},
158         {std::make_pair("cpuprofile-stop", "cp-stop"),
159             std::bind(&CliCommand::CpuProfileCommand, this, "cpuprofile-stop")},
160         {std::make_pair("cpuprofile-enable", "cp-enable"),
161             std::bind(&CliCommand::CpuProfileCommand, this, "cpuprofile-enable")},
162         {std::make_pair("cpuprofile-disable", "cp-disable"),
163             std::bind(&CliCommand::CpuProfileCommand, this, "cpuprofile-disable")},
164         {std::make_pair("cpuprofile-show", "cp-show"),
165             std::bind(&CliCommand::CpuProfileCommand, this, "cpuprofile-show")},
166         {std::make_pair("cpuprofile-setSamplingInterval", "cp-ssi"),
167             std::bind(&CliCommand::CpuProfileCommand, this, "cpuprofile-setSamplingInterval")},
168         {std::make_pair("runtime-enable", "rt-enable"), std::bind(&CliCommand::RuntimeCommand, this, "runtime-enable")},
169         {std::make_pair("heapusage", "hu"), std::bind(&CliCommand::RuntimeCommand, this, "heapusage")},
170         {std::make_pair("break", "b"), std::bind(&CliCommand::BreakCommand, this, "break")},
171         {std::make_pair("backtrack", "bt"), std::bind(&CliCommand::DebuggerCommand, this, "backtrack")},
172         {std::make_pair("continue", "c"), std::bind(&CliCommand::DebuggerCommand, this, "continue")},
173         {std::make_pair("delete", "d"), std::bind(&CliCommand::DeleteCommand, this, "delete")},
174         {std::make_pair("disable", "disable"), std::bind(&CliCommand::DebuggerCommand, this, "disable")},
175         {std::make_pair("display", "display"), std::bind(&CliCommand::DisplayCommand, this, "display")},
176         {std::make_pair("enable", "enable"), std::bind(&CliCommand::DebuggerCommand, this, "enable")},
177         {std::make_pair("finish", "fin"), std::bind(&CliCommand::DebuggerCommand, this, "finish")},
178         {std::make_pair("frame", "f"), std::bind(&CliCommand::DebuggerCommand, this, "frame")},
179         {std::make_pair("enable-launch-accelerate", "enable-acc"),
180             std::bind(&CliCommand::DebuggerCommand, this, "enable-launch-accelerate")},
181         {std::make_pair("saveAllPossibleBreakpoints", "b-new"),
182             std::bind(&CliCommand::SaveAllPossibleBreakpointsCommand, this, "saveAllPossibleBreakpoints")},
183         {std::make_pair("setSymbolicBreakpoints", "setSymbolicBreakpoints"),
184             std::bind(&CliCommand::SetSymbolicBreakpointsCommand, this, "setSymbolicBreakpoints")},
185         {std::make_pair("removeSymbolicBreakpoints", "removeSymbolicBreakpoints"),
186             std::bind(&CliCommand::RemoveSymbolicBreakpointsCommand, this, "removeSymbolicBreakpoints")},
187     };
188     CreateOtherCommandMap();
189 }
CreateOtherCommandMap()190 void CliCommand::CreateOtherCommandMap()
191 {
192     commandMap_.insert({
193         {std::make_pair("help", "h"), std::bind(&CliCommand::ExecHelpCommand, this)},
194         {std::make_pair("ignore", "ig"), std::bind(&CliCommand::DebuggerCommand, this, "ignore")},
195         {std::make_pair("infobreakpoints", "infob"), std::bind(&CliCommand::DebuggerCommand, this, "infobreakpoints")},
196         {std::make_pair("infosource", "infos"), std::bind(&CliCommand::InfosourceCommand, this, "infosource")},
197         {std::make_pair("jump", "j"), std::bind(&CliCommand::DebuggerCommand, this, "jump")},
198         {std::make_pair("list", "l"), std::bind(&CliCommand::ListCommand, this, "list")},
199         {std::make_pair("next", "n"), std::bind(&CliCommand::DebuggerCommand, this, "next")},
200         {std::make_pair("print", "p"), std::bind(&CliCommand::PrintCommand, this, "print")},
201         {std::make_pair("ptype", "ptype"), std::bind(&CliCommand::DebuggerCommand, this, "ptype")},
202         {std::make_pair("run", "r"), std::bind(&CliCommand::RuntimeCommand, this, "run")},
203         {std::make_pair("setvar", "sv"), std::bind(&CliCommand::DebuggerCommand, this, "setvar")},
204         {std::make_pair("step", "s"), std::bind(&CliCommand::DebuggerCommand, this, "step")},
205         {std::make_pair("undisplay", "undisplay"), std::bind(&CliCommand::DebuggerCommand, this, "undisplay")},
206         {std::make_pair("watch", "wa"), std::bind(&CliCommand::WatchCommand, this, "watch")},
207         {std::make_pair("resume", "resume"), std::bind(&CliCommand::DebuggerCommand, this, "resume")},
208         {std::make_pair("showstack", "ss"), std::bind(&CliCommand::ShowstackCommand, this, "showstack")},
209         {std::make_pair("step-into", "si"), std::bind(&CliCommand::StepCommand, this, "step-into")},
210         {std::make_pair("step-out", "so"), std::bind(&CliCommand::StepCommand, this, "step-out")},
211         {std::make_pair("step-over", "sov"), std::bind(&CliCommand::StepCommand, this, "step-over")},
212         {std::make_pair("runtime-disable", "rt-disable"),
213             std::bind(&CliCommand::RuntimeCommand, this, "runtime-disable")},
214         {std::make_pair("setAsyncStackDepth", "setAsyncStackDepth"),
215             std::bind(&CliCommand::DebuggerCommand, this, "setAsyncStackDepth")},
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 
SetSymbolicBreakpointsCommand(const std::string & cmd)378 ErrCode CliCommand::SetSymbolicBreakpointsCommand(const std::string &cmd)
379 {
380     bool result = false;
381     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
382     DebuggerClient &debuggerCli = session->GetDomainManager().GetDebuggerClient();
383     BreakPointManager &breakpointManager = session->GetBreakPointManager();
384     std::vector<Breaklocation> breaklist_ = breakpointManager.Getbreaklist();
385     if (GetArgList().size() == 1) { //1: one arguments
386         if (Utils::IsNumber(GetArgList()[0])) {
387             OutputCommand(cmd, false);
388             return ErrCode::ERR_FAIL;
389         }
390         debuggerCli.AddSymbolicBreakpointInfo(GetArgList()[0]);
391     } else {
392         OutputCommand(cmd, false);
393         return ErrCode::ERR_FAIL;
394     }
395 
396     result = debuggerCli.DispatcherCmd(cmd);
397     OutputCommand(cmd, true);
398     return result ? ErrCode::ERR_OK : ErrCode::ERR_FAIL;
399 }
400 
RemoveSymbolicBreakpointsCommand(const std::string & cmd)401 ErrCode CliCommand::RemoveSymbolicBreakpointsCommand(const std::string &cmd)
402 {
403     bool result = false;
404     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
405     DebuggerClient &debuggerCli = session->GetDomainManager().GetDebuggerClient();
406     BreakPointManager &breakpointManager = session->GetBreakPointManager();
407     std::vector<Breaklocation> breaklist_ = breakpointManager.Getbreaklist();
408     if (GetArgList().size() == 1) { //1: one arguments
409         if (Utils::IsNumber(GetArgList()[0])) {
410             OutputCommand(cmd, false);
411             return ErrCode::ERR_FAIL;
412         }
413         debuggerCli.AddSymbolicBreakpointInfo(GetArgList()[0]);
414     } else {
415         OutputCommand(cmd, false);
416         return ErrCode::ERR_FAIL;
417     }
418 
419     result = debuggerCli.DispatcherCmd(cmd);
420     OutputCommand(cmd, true);
421     return result ? ErrCode::ERR_OK : ErrCode::ERR_FAIL;
422 }
423 
DeleteCommand(const std::string & cmd)424 ErrCode CliCommand::DeleteCommand(const std::string &cmd)
425 {
426     bool result = false;
427     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
428     DebuggerClient &debuggerCli = session->GetDomainManager().GetDebuggerClient();
429     BreakPointManager &breakpoint = session->GetBreakPointManager();
430     if (GetArgList().size() == 1) {
431         if (!Utils::IsNumber(GetArgList()[0])) {
432             OutputCommand(cmd, false);
433             return ErrCode::ERR_FAIL;
434         }
435         int tmpNum = std::stoi(GetArgList()[0]);
436         size_t num = static_cast<size_t>(tmpNum);
437         if (breakpoint.Getbreaklist().size() >= num && num > 0) {
438             debuggerCli.AddBreakPointInfo(breakpoint.Getbreaklist()[num - 1].breakpointId, 0); // 1: breakpoinId
439             breakpoint.Deletebreaklist(num);
440         } else {
441             std::cout << "the breakpoint is not exist" << std::endl;
442             return ErrCode::ERR_FAIL;
443         }
444     } else {
445         OutputCommand(cmd, false);
446         return ErrCode::ERR_FAIL;
447     }
448     result = debuggerCli.DispatcherCmd(cmd);
449     OutputCommand(cmd, true);
450     return result ? ErrCode::ERR_OK : ErrCode::ERR_FAIL;
451 }
452 
DisplayCommand(const std::string & cmd)453 ErrCode CliCommand::DisplayCommand(const std::string &cmd)
454 {
455     if (GetArgList().size()) {
456         OutputCommand(cmd, false);
457         return ErrCode::ERR_FAIL;
458     }
459     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
460     BreakPointManager &breakpointManager = session->GetBreakPointManager();
461     breakpointManager.Show();
462     OutputCommand(cmd, true);
463     return ErrCode::ERR_OK;
464 }
465 
InfosourceCommand(const std::string & cmd)466 ErrCode CliCommand::InfosourceCommand(const std::string &cmd)
467 {
468     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
469     SourceManager &sourceManager = session->GetSourceManager();
470     if (GetArgList().size() > 1) {
471         OutputCommand(cmd, false);
472         return ErrCode::ERR_FAIL;
473     } else if (GetArgList().size() == 1) {
474         if (!Utils::IsNumber(GetArgList()[0])) {
475             OutputCommand(cmd, false);
476             return ErrCode::ERR_FAIL;
477         }
478         sourceManager.GetFileSource(std::stoi(GetArgList()[0]));
479     } else {
480         sourceManager.GetFileName();
481     }
482     OutputCommand(cmd, true);
483     return ErrCode::ERR_OK;
484 }
485 
ListCommand(const std::string & cmd)486 ErrCode CliCommand::ListCommand(const std::string &cmd)
487 {
488     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
489     SourceManager &sourceManager = session->GetSourceManager();
490     WatchManager &watchManager = session->GetWatchManager();
491     if (!watchManager.GetDebugState()) {
492         std::cout << "Start debugging your code before using the list command" << std::endl;
493         return ErrCode::ERR_FAIL;
494     }
495     if (GetArgList().size() > 2) { //2: two arguments
496         OutputCommand(cmd, false);
497         return ErrCode::ERR_FAIL;
498     } else if (GetArgList().size() == 2) { //2: two arguments
499         if (Utils::IsNumber(GetArgList()[0]) && Utils::IsNumber(GetArgList()[1])) {
500             sourceManager.GetListSource(GetArgList()[0], GetArgList()[1]);
501         } else {
502             OutputCommand(cmd, false);
503             return ErrCode::ERR_FAIL;
504         }
505     } else if (GetArgList().size() == 1) {
506         if (Utils::IsNumber(GetArgList()[0])) {
507             sourceManager.GetListSource(GetArgList()[0], "");
508         } else {
509             OutputCommand(cmd, false);
510             return ErrCode::ERR_FAIL;
511         }
512     } else {
513         sourceManager.GetListSource("", "");
514     }
515     OutputCommand(cmd, true);
516     return ErrCode::ERR_OK;
517 }
518 
StepCommand(const std::string & cmd)519 ErrCode CliCommand::StepCommand(const std::string &cmd)
520 {
521     if (GetArgList().size()) {
522         OutputCommand(cmd, false);
523         return ErrCode::ERR_FAIL;
524     }
525     bool result = false;
526     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
527     DebuggerClient &debuggerCli = session->GetDomainManager().GetDebuggerClient();
528     RuntimeClient &runtimeClient = session->GetDomainManager().GetRuntimeClient();
529     runtimeClient.SetIsInitializeTree(true);
530     result = debuggerCli.DispatcherCmd(cmd);
531     OutputCommand(cmd, true);
532     return result ? ErrCode::ERR_OK : ErrCode::ERR_FAIL;
533 }
534 
ShowstackCommand(const std::string & cmd)535 ErrCode CliCommand::ShowstackCommand(const std::string &cmd)
536 {
537     if (GetArgList().size()) {
538         OutputCommand(cmd, false);
539         return ErrCode::ERR_FAIL;
540     }
541     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
542     StackManager &stackManager = session->GetStackManager();
543     stackManager.ShowCallFrames();
544     OutputCommand(cmd, true);
545     return ErrCode::ERR_OK;
546 }
547 
PrintCommand(const std::string & cmd)548 ErrCode CliCommand::PrintCommand(const std::string &cmd)
549 {
550     int TWO_ARGS = 2;
551     if (GetArgList().size() > TWO_ARGS) {
552         OutputCommand(cmd, false);
553         return ErrCode::ERR_FAIL;
554     }
555     bool result = false;
556     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
557     RuntimeClient &runtimeClient = session->GetDomainManager().GetRuntimeClient();
558     if (GetArgList().size() == 1) {
559         if (!Utils::IsNumber(GetArgList()[0])) {
560             return ErrCode::ERR_FAIL;
561         }
562         runtimeClient.SetIsInitializeTree(false);
563         VariableManager &variableManager = session->GetVariableManager();
564         int32_t objectId = variableManager.FindObjectIdWithIndex(std::stoi(GetArgList()[0]));
565         runtimeClient.SetObjectId(std::to_string(objectId));
566     }
567     if (GetArgList().size() == TWO_ARGS) {
568         if (!Utils::IsNumber(GetArgList()[1])) {
569             return ErrCode::ERR_FAIL;
570         }
571         runtimeClient.SetIsInitializeTree(false);
572         VariableManager &variableManager = session->GetVariableManager();
573         int32_t objectId = std::stoi(GetArgList()[1]);
574         runtimeClient.SetObjectId(std::to_string(objectId));
575     }
576     result = runtimeClient.DispatcherCmd(cmd);
577     if (result) {
578         runtimeClient.SetObjectId("0");
579     } else {
580         return ErrCode::ERR_FAIL;
581     }
582     OutputCommand(cmd, true);
583     return ErrCode::ERR_OK;
584 }
585 
WatchCommand(const std::string & cmd)586 ErrCode CliCommand::WatchCommand(const std::string &cmd)
587 {
588     if (GetArgList().size() != 1) {
589         OutputCommand(cmd, false);
590         return ErrCode::ERR_FAIL;
591     }
592     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
593     WatchManager &watchManager = session->GetWatchManager();
594     watchManager.AddWatchInfo(GetArgList()[0]);
595     if (watchManager.GetDebugState()) {
596         watchManager.SendRequestWatch(watchManager.GetWatchInfoSize() - 1, watchManager.GetCallFrameId());
597     } else {
598         std::cout << "Start debugging your code before using the watch command" << std::endl;
599         return ErrCode::ERR_FAIL;
600     }
601     OutputCommand(cmd, true);
602     return ErrCode::ERR_OK;
603 }
604 
SessionAddCommand(const std::string & cmd)605 ErrCode CliCommand::SessionAddCommand([[maybe_unused]] const std::string &cmd)
606 {
607     VecStr argList = GetArgList();
608     if (argList.size() == 1) {
609         if (!SessionManager::getInstance().CreateNewSession(argList[0])) {
610             OutputCommand(cmd, true);
611             return ErrCode::ERR_OK;
612         } else {
613             std::cout << "session add failed" << std::endl;
614         }
615     } else {
616         OutputCommand(cmd, false);
617     }
618 
619     return ErrCode::ERR_FAIL;
620 }
621 
SessionDelCommand(const std::string & cmd)622 ErrCode CliCommand::SessionDelCommand([[maybe_unused]] const std::string &cmd)
623 {
624     VecStr argList = GetArgList();
625     if (argList.size() == 1 && Utils::IsNumber(argList[0])) {
626         uint32_t sessionId = 0;
627         if (Utils::StrToUInt(argList[0].c_str(), &sessionId)) {
628             if (sessionId == 0) {
629                 std::cout << "cannot remove default session 0" << std::endl;
630                 return ErrCode::ERR_OK;
631             }
632             if (SessionManager::getInstance().DelSessionById(sessionId) == 0) {
633                 std::cout << "session remove success" << std::endl;
634                 return ErrCode::ERR_OK;
635             } else {
636                 std::cout << "sessionId is not exist" << std::endl;
637             }
638         }
639     } else {
640         OutputCommand(cmd, false);
641     }
642 
643     return ErrCode::ERR_FAIL;
644 }
645 
SessionListCommand(const std::string & cmd)646 ErrCode CliCommand::SessionListCommand([[maybe_unused]] const std::string &cmd)
647 {
648     if (GetArgList().size()) {
649         OutputCommand(cmd, false);
650         return ErrCode::ERR_FAIL;
651     }
652     SessionManager::getInstance().SessionList();
653     OutputCommand(cmd, true);
654     return ErrCode::ERR_OK;
655 }
656 
SessionSwitchCommand(const std::string & cmd)657 ErrCode CliCommand::SessionSwitchCommand([[maybe_unused]] const std::string &cmd)
658 {
659     VecStr argList = GetArgList();
660     if (argList.size() == 1 && Utils::IsNumber(argList[0])) {
661         uint32_t sessionId = 0;
662         if (Utils::StrToUInt(argList[0].c_str(), &sessionId)) {
663             if (SessionManager::getInstance().SessionSwitch(sessionId) == 0) {
664                 OutputCommand(cmd, true);
665                 return ErrCode::ERR_OK;
666             } else {
667                 std::cout << "sessionId is not exist" << std::endl;
668             }
669         }
670     } else {
671         OutputCommand(cmd, false);
672     }
673     return ErrCode::ERR_FAIL;
674 }
675 
TestCommand(const std::string & cmd)676 ErrCode CliCommand::TestCommand(const std::string &cmd)
677 {
678     if (cmd == "success" || cmd == "fail") {
679         Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
680         TestClient &testClient = session->GetDomainManager().GetTestClient();
681         testClient.DispatcherCmd(cmd);
682     } else {
683         return ErrCode::ERR_FAIL;
684     }
685     return ErrCode::ERR_OK;
686 }
687 
SaveAllPossibleBreakpointsCommand(const std::string & cmd)688 ErrCode CliCommand::SaveAllPossibleBreakpointsCommand(const std::string &cmd)
689 {
690     return BreakCommand(cmd);
691 }
692 
ExecHelpCommand()693 ErrCode CliCommand::ExecHelpCommand()
694 {
695     std::cout << HELP_MSG;
696     return ErrCode::ERR_OK;
697 }
698 
OutputCommand(const std::string & cmd,bool flag)699 void CliCommand::OutputCommand(const std::string &cmd, bool flag)
700 {
701     if (flag) {
702         std::cout << "exe success, cmd is " << cmd << std::endl;
703     } else {
704         std::cout << cmd << " parameters is incorrect" << std::endl;
705     }
706 }
707 
OnCommand()708 ErrCode CliCommand::OnCommand()
709 {
710     std::map<StrPair, std::function<ErrCode()>>::iterator it;
711     StrPair cmdPair;
712     bool haveCmdFlag = false;
713 
714     for (it = commandMap_.begin(); it != commandMap_.end(); it++) {
715         cmdPair = it->first;
716         if (!strcmp(cmdPair.first.c_str(), cmd_.c_str())
717             ||!strcmp(cmdPair.second.c_str(), cmd_.c_str())) {
718             auto respond = it->second;
719             return respond();
720         }
721     }
722 
723     for (unsigned int i = 0; i < cmdList.size(); i++) {
724         if (!strncmp(cmdList[i].c_str(), cmd_.c_str(), std::strlen(cmd_.c_str()))) {
725             haveCmdFlag = true;
726             std::cout << cmdList[i] << " ";
727         }
728     }
729 
730     if (haveCmdFlag) {
731         std::cout << std::endl;
732     } else {
733         ExecHelpCommand();
734     }
735 
736     return ErrCode::ERR_FAIL;
737 }
738 } // namespace OHOS::ArkCompiler::Toolchain
739