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