• 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/domain/debugger_client.h"
17 
18 #include "tooling/client/session/session.h"
19 
20 using PtJson = panda::ecmascript::tooling::PtJson;
21 namespace OHOS::ArkCompiler::Toolchain {
DispatcherCmd(const std::string & cmd)22 bool DebuggerClient::DispatcherCmd(const std::string &cmd)
23 {
24     std::map<std::string, std::function<int()>> dispatcherTable {
25         { "break", std::bind(&DebuggerClient::BreakCommand, this)},
26         { "backtrack", std::bind(&DebuggerClient::BacktrackCommand, this)},
27         { "continue", std::bind(&DebuggerClient::ResumeCommand, this)},
28         { "delete", std::bind(&DebuggerClient::DeleteCommand, this)},
29         { "jump", std::bind(&DebuggerClient::JumpCommand, this)},
30         { "disable", std::bind(&DebuggerClient::DisableCommand, this)},
31         { "display", std::bind(&DebuggerClient::DisplayCommand, this)},
32         { "enable", std::bind(&DebuggerClient::EnableCommand, this)},
33         { "finish", std::bind(&DebuggerClient::FinishCommand, this)},
34         { "frame", std::bind(&DebuggerClient::FrameCommand, this)},
35         { "ignore", std::bind(&DebuggerClient::IgnoreCommand, this)},
36         { "infobreakpoints", std::bind(&DebuggerClient::InfobreakpointsCommand, this)},
37         { "infosource", std::bind(&DebuggerClient::InfosourceCommand, this)},
38         { "list", std::bind(&DebuggerClient::ListCommand, this)},
39         { "next", std::bind(&DebuggerClient::NextCommand, this)},
40         { "ptype", std::bind(&DebuggerClient::PtypeCommand, this)},
41         { "run", std::bind(&DebuggerClient::RunCommand, this)},
42         { "setvar", std::bind(&DebuggerClient::SetvarCommand, this)},
43         { "step", std::bind(&DebuggerClient::StepCommand, this)},
44         { "undisplay", std::bind(&DebuggerClient::UndisplayCommand, this)},
45         { "watch", std::bind(&DebuggerClient::WatchCommand, this)},
46         { "resume", std::bind(&DebuggerClient::ResumeCommand, this)},
47         { "step-into", std::bind(&DebuggerClient::StepIntoCommand, this)},
48         { "step-out", std::bind(&DebuggerClient::StepOutCommand, this)},
49         { "step-over", std::bind(&DebuggerClient::StepOverCommand, this)},
50         { "enable-launch-accelerate", std::bind(&DebuggerClient::EnableLaunchAccelerateCommand, this)},
51         { "saveAllPossibleBreakpoints", std::bind(&DebuggerClient::SaveAllPossibleBreakpointsCommand, this)},
52     };
53 
54     auto entry = dispatcherTable.find(cmd);
55     if (entry != dispatcherTable.end()) {
56         entry->second();
57         LOGI("DebuggerClient DispatcherCmd cmd: %{public}s", cmd.c_str());
58         return true;
59     }
60 
61     LOGI("unknown command: %{public}s", cmd.c_str());
62     return false;
63 }
64 
BreakCommand()65 int DebuggerClient::BreakCommand()
66 {
67     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
68     uint32_t id = session->GetMessageId();
69 
70     std::unique_ptr<PtJson> request = PtJson::CreateObject();
71     request->Add("id", id);
72     request->Add("method", "Debugger.setBreakpointByUrl");
73 
74     std::unique_ptr<PtJson> params = PtJson::CreateObject();
75     params->Add("columnNumber", breakPointInfoList_.back().columnNumber);
76     params->Add("lineNumber", breakPointInfoList_.back().lineNumber);
77     params->Add("url", breakPointInfoList_.back().url.c_str());
78     request->Add("params", params);
79 
80     std::string message = request->Stringify();
81     if (session->ClientSendReq(message)) {
82         session->GetDomainManager().SetDomainById(id, "Debugger");
83     }
84     return 0;
85 }
86 
BacktrackCommand()87 int DebuggerClient::BacktrackCommand()
88 {
89     return 0;
90 }
91 
DeleteCommand()92 int DebuggerClient::DeleteCommand()
93 {
94     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
95     uint32_t id = session->GetMessageId();
96 
97     std::unique_ptr<PtJson> request = PtJson::CreateObject();
98     request->Add("id", id);
99     request->Add("method", "Debugger.removeBreakpoint");
100 
101     std::unique_ptr<PtJson> params = PtJson::CreateObject();
102     std::string breakpointId = breakPointInfoList_.back().url;
103     params->Add("breakpointId", breakpointId.c_str());
104     request->Add("params", params);
105 
106     std::string message = request->Stringify();
107     if (session->ClientSendReq(message)) {
108         session->GetDomainManager().SetDomainById(id, "Debugger");
109     }
110     return 0;
111 }
112 
DisableCommand()113 int DebuggerClient::DisableCommand()
114 {
115     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
116     uint32_t id = session->GetMessageId();
117 
118     std::unique_ptr<PtJson> request = PtJson::CreateObject();
119     request->Add("id", id);
120     request->Add("method", "Debugger.disable");
121 
122     std::unique_ptr<PtJson> params = PtJson::CreateObject();
123     request->Add("params", params);
124 
125     std::string message = request->Stringify();
126     if (session->ClientSendReq(message)) {
127         session->GetDomainManager().SetDomainById(id, "Debugger");
128     }
129     return 0;
130 }
131 
DisplayCommand()132 int DebuggerClient::DisplayCommand()
133 {
134     return 0;
135 }
136 
EnableCommand()137 int DebuggerClient::EnableCommand()
138 {
139     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
140     uint32_t id = session->GetMessageId();
141 
142     std::unique_ptr<PtJson> request = PtJson::CreateObject();
143     request->Add("id", id);
144     request->Add("method", "Debugger.enable");
145 
146     std::unique_ptr<PtJson> params = PtJson::CreateObject();
147     request->Add("params", params);
148 
149     std::string message = request->Stringify();
150     if (session->ClientSendReq(message)) {
151         session->GetDomainManager().SetDomainById(id, "Debugger");
152     }
153     return 0;
154 }
155 
FinishCommand()156 int DebuggerClient::FinishCommand()
157 {
158     return 0;
159 }
160 
FrameCommand()161 int DebuggerClient::FrameCommand()
162 {
163     return 0;
164 }
165 
IgnoreCommand()166 int DebuggerClient::IgnoreCommand()
167 {
168     return 0;
169 }
170 
InfobreakpointsCommand()171 int DebuggerClient::InfobreakpointsCommand()
172 {
173     return 0;
174 }
175 
InfosourceCommand()176 int DebuggerClient::InfosourceCommand()
177 {
178     return 0;
179 }
180 
JumpCommand()181 int DebuggerClient::JumpCommand()
182 {
183     return 0;
184 }
185 
NextCommand()186 int DebuggerClient::NextCommand()
187 {
188     return 0;
189 }
190 
ListCommand()191 int DebuggerClient::ListCommand()
192 {
193     return 0;
194 }
195 
PtypeCommand()196 int DebuggerClient::PtypeCommand()
197 {
198     return 0;
199 }
200 
RunCommand()201 int DebuggerClient::RunCommand()
202 {
203     return 0;
204 }
205 
SetvarCommand()206 int DebuggerClient::SetvarCommand()
207 {
208     return 0;
209 }
210 
StepCommand()211 int DebuggerClient::StepCommand()
212 {
213     return 0;
214 }
215 
UndisplayCommand()216 int DebuggerClient::UndisplayCommand()
217 {
218     return 0;
219 }
220 
WatchCommand()221 int DebuggerClient::WatchCommand()
222 {
223     return 0;
224 }
225 
ResumeCommand()226 int DebuggerClient::ResumeCommand()
227 {
228     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
229     uint32_t id = session->GetMessageId();
230 
231     std::unique_ptr<PtJson> request = PtJson::CreateObject();
232     request->Add("id", id);
233     request->Add("method", "Debugger.resume");
234 
235     std::unique_ptr<PtJson> params = PtJson::CreateObject();
236     request->Add("params", params);
237 
238     std::string message = request->Stringify();
239     if (session->ClientSendReq(message)) {
240         session->GetDomainManager().SetDomainById(id, "Debugger");
241     }
242     return 0;
243 }
244 
StepIntoCommand()245 int DebuggerClient::StepIntoCommand()
246 {
247     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
248     uint32_t id = session->GetMessageId();
249 
250     std::unique_ptr<PtJson> request = PtJson::CreateObject();
251     request->Add("id", id);
252     request->Add("method", "Debugger.stepInto");
253 
254     std::unique_ptr<PtJson> params = PtJson::CreateObject();
255     request->Add("params", params);
256 
257     std::string message = request->Stringify();
258     if (session->ClientSendReq(message)) {
259         session->GetDomainManager().SetDomainById(id, "Debugger");
260     }
261     return 0;
262 }
263 
StepOutCommand()264 int DebuggerClient::StepOutCommand()
265 {
266     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
267     uint32_t id = session->GetMessageId();
268 
269     std::unique_ptr<PtJson> request = PtJson::CreateObject();
270     request->Add("id", id);
271     request->Add("method", "Debugger.stepOut");
272 
273     std::unique_ptr<PtJson> params = PtJson::CreateObject();
274     request->Add("params", params);
275 
276     std::string message = request->Stringify();
277     if (session->ClientSendReq(message)) {
278         session->GetDomainManager().SetDomainById(id, "Debugger");
279     }
280     return 0;
281 }
282 
StepOverCommand()283 int DebuggerClient::StepOverCommand()
284 {
285     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
286     uint32_t id = session->GetMessageId();
287 
288     std::unique_ptr<PtJson> request = PtJson::CreateObject();
289     request->Add("id", id);
290     request->Add("method", "Debugger.stepOver");
291 
292     std::unique_ptr<PtJson> params = PtJson::CreateObject();
293     request->Add("params", params);
294 
295     std::string message = request->Stringify();
296     if (session->ClientSendReq(message)) {
297         session->GetDomainManager().SetDomainById(id, "Debugger");
298     }
299     return 0;
300 }
301 
AddBreakPointInfo(const std::string & url,const int & lineNumber,const int & columnNumber)302 void DebuggerClient::AddBreakPointInfo(const std::string& url, const int& lineNumber, const int& columnNumber)
303 {
304     BreakPointInfo breakPointInfo;
305     breakPointInfo.url = url;
306     breakPointInfo.lineNumber = lineNumber - 1;
307     breakPointInfo.columnNumber = columnNumber;
308     breakPointInfoList_.emplace_back(breakPointInfo);
309 }
310 
RecvReply(std::unique_ptr<PtJson> json)311 void DebuggerClient::RecvReply(std::unique_ptr<PtJson> json)
312 {
313     if (json == nullptr) {
314         LOGE("arkdb: json parse error");
315         return;
316     }
317 
318     if (!json->IsObject()) {
319         LOGE("arkdb: json parse format error");
320         json->ReleaseRoot();
321         return;
322     }
323 
324     std::string wholeMethod;
325     std::string method;
326     Result ret = json->GetString("method", &wholeMethod);
327     if (ret != Result::SUCCESS) {
328         LOGE("arkdb: find method error");
329     }
330 
331     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
332     SourceManager &sourceManager = session->GetSourceManager();
333     WatchManager &watchManager = session->GetWatchManager();
334 
335     std::string::size_type length = wholeMethod.length();
336     std::string::size_type indexPoint = 0;
337     indexPoint = wholeMethod.find_first_of('.', 0);
338     method = wholeMethod.substr(indexPoint + 1, length);
339     if (method == "paused") {
340         PausedReply(std::move(json));
341         return;
342     } else if (method == "scriptParsed") {
343         sourceManager.EnableReply(std::move(json));
344         return;
345     } else if (method == "resumed") {
346         watchManager.DebugFalseState();
347         return;
348     } else {
349         LOGI("arkdb: Debugger reply is: %{public}s", json->Stringify().c_str());
350     }
351     handleResponse(std::move(json));
352 }
353 
PausedReply(const std::unique_ptr<PtJson> json)354 void DebuggerClient::PausedReply(const std::unique_ptr<PtJson> json)
355 {
356     if (json == nullptr) {
357         LOGE("arkdb: json parse error");
358         return;
359     }
360 
361     if (!json->IsObject()) {
362         LOGE("arkdb: json parse format error");
363         json->ReleaseRoot();
364         return;
365     }
366 
367     std::unique_ptr<PtJson> params;
368     Result ret = json->GetObject("params", &params);
369     if (ret != Result::SUCCESS) {
370         LOGE("arkdb: find params error");
371         return;
372     }
373 
374     std::unique_ptr<PtJson> callFrames;
375     ret = params->GetArray("callFrames", &callFrames);
376     if (ret != Result::SUCCESS) {
377         LOGE("arkdb: find callFrames error");
378         return;
379     }
380 
381     std::map<int32_t, std::unique_ptr<CallFrame>> data;
382     for (int32_t i = 0; i < callFrames->GetSize(); i++) {
383         std::unique_ptr<CallFrame> callFrameInfo = CallFrame::Create(*(callFrames->Get(i)));
384         if (callFrameInfo == nullptr) {
385             LOGE("arkdb: get call frame info error");
386             return;
387         }
388         data.emplace(i + 1, std::move(callFrameInfo));
389     }
390 
391     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
392     StackManager& stackManager = session->GetStackManager();
393     SourceManager &sourceManager = session->GetSourceManager();
394     WatchManager &watchManager = session->GetWatchManager();
395     stackManager.ClearCallFrame();
396     stackManager.SetCallFrames(std::move(data));
397     sourceManager.GetDebugSources(callFrames->Get(0));
398     watchManager.RequestWatchInfo(callFrames->Get(0));
399     watchManager.DebugTrueState();
400 }
401 
handleResponse(std::unique_ptr<PtJson> json)402 void DebuggerClient::handleResponse(std::unique_ptr<PtJson> json)
403 {
404     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
405     SourceManager &sourceManager = session->GetSourceManager();
406     WatchManager &watchManager = session->GetWatchManager();
407     BreakPointManager& breakpoint = session->GetBreakPointManager();
408     std::unique_ptr<PtJson> result;
409     Result ret = json->GetObject("result", &result);
410     if (ret != Result::SUCCESS) {
411         LOGE("arkdb: find result error");
412         return;
413     }
414     int32_t id;
415     ret = json->GetInt("id", &id);
416     if (ret == Result::SUCCESS) {
417         std::string scriptSource;
418         ret = result->GetString("scriptSource", &scriptSource);
419         if (ret == Result::SUCCESS) {
420             sourceManager.SetFileSource(id, scriptSource);
421             return;
422         }
423     }
424     std::string breakpointId;
425     ret = result->GetString("breakpointId", &breakpointId);
426     if (ret == Result::SUCCESS) {
427         breakpoint.Createbreaklocation(std::move(json));
428         return;
429     }
430     if (watchManager.HandleWatchResult(std::move(json), id)) {
431         return;
432     }
433     return;
434 }
435 
SaveAllPossibleBreakpointsCommand()436 int DebuggerClient::SaveAllPossibleBreakpointsCommand()
437 {
438     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
439     uint32_t id = session->GetMessageId();
440 
441     std::unique_ptr<PtJson> request = PtJson::CreateObject();
442     request->Add("id", id);
443     request->Add("method", "Debugger.saveAllPossibleBreakpoints");
444 
445     std::unique_ptr<PtJson> params = PtJson::CreateObject();
446     std::unique_ptr<PtJson> locations = PtJson::CreateObject();
447     std::unique_ptr<PtJson> vector = PtJson::CreateArray();
448 
449     std::unique_ptr<PtJson> bp = PtJson::CreateObject();
450     bp->Add("lineNumber", breakPointInfoList_.back().lineNumber);
451     bp->Add("columnNumber", breakPointInfoList_.back().columnNumber);
452     vector->Push(bp);
453     locations->Add(breakPointInfoList_.back().url.c_str(), vector);
454     params->Add("locations", locations);
455     request->Add("params", params);
456 
457     std::string message = request->Stringify();
458     if (session->ClientSendReq(message)) {
459         session->GetDomainManager().SetDomainById(id, "Debugger");
460     }
461 
462     return 0;
463 }
464 
EnableLaunchAccelerateCommand()465 int DebuggerClient::EnableLaunchAccelerateCommand()
466 {
467     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
468     uint32_t id = session->GetMessageId();
469 
470     std::unique_ptr<PtJson> request = PtJson::CreateObject();
471     request->Add("id", id);
472     request->Add("method", "Debugger.enable");
473 
474     std::unique_ptr<PtJson> params = PtJson::CreateObject();
475     std::unique_ptr<PtJson> options = PtJson::CreateArray();
476 
477     options->Push("enableLaunchAccelerate");
478     params->Add("options", options);
479     request->Add("params", params);
480 
481     std::string message = request->Stringify();
482     if (session->ClientSendReq(message)) {
483         session->GetDomainManager().SetDomainById(id, "Debugger");
484     }
485 
486     return 0;
487 }
488 } // OHOS::ArkCompiler::Toolchain