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