• 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/profiler_client.h"
17 #include "tooling/client/session/session.h"
18 
19 using Result = panda::ecmascript::tooling::Result;
20 using Profile = panda::ecmascript::tooling::Profile;
21 namespace OHOS::ArkCompiler::Toolchain {
DispatcherCmd(const std::string & cmd)22 bool ProfilerClient::DispatcherCmd(const std::string &cmd)
23 {
24     std::map<std::string, std::function<int()>> dispatcherTable {
25         { "cpuprofile", std::bind(&ProfilerClient::CpuprofileCommand, this)},
26         { "cpuprofile-stop", std::bind(&ProfilerClient::CpuprofileStopCommand, this)},
27         { "cpuprofile-setSamplingInterval", std::bind(&ProfilerClient::SetSamplingIntervalCommand, this)},
28         { "cpuprofile-enable", std::bind(&ProfilerClient::CpuprofileEnableCommand, this)},
29         { "cpuprofile-disable", std::bind(&ProfilerClient::CpuprofileDisableCommand, this)},
30     };
31 
32     auto entry = dispatcherTable.find(cmd);
33     if (entry == dispatcherTable.end()) {
34         LOGI("Unknown commond: %{public}s", cmd.c_str());
35         return false;
36     }
37     entry->second();
38     LOGI("DispatcherCmd cmd: %{public}s", cmd.c_str());
39     return true;
40 }
41 
CpuprofileEnableCommand()42 int ProfilerClient::CpuprofileEnableCommand()
43 {
44     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
45     uint32_t id = session->GetMessageId();
46 
47     idEventMap_.emplace(id, "cpuprofileenable");
48     std::unique_ptr<PtJson> request = PtJson::CreateObject();
49     request->Add("id", id);
50     request->Add("method", "Profiler.enable");
51 
52     std::unique_ptr<PtJson> params = PtJson::CreateObject();
53     request->Add("params", params);
54 
55     std::string message = request->Stringify();
56     if (session->ClientSendReq(message)) {
57         session->GetDomainManager().SetDomainById(id, "Profiler");
58     }
59     return 0;
60 }
61 
CpuprofileDisableCommand()62 int ProfilerClient::CpuprofileDisableCommand()
63 {
64     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
65     uint32_t id = session->GetMessageId();
66 
67     idEventMap_.emplace(id, "cpuprofiledisable");
68     std::unique_ptr<PtJson> request = PtJson::CreateObject();
69     request->Add("id", id);
70     request->Add("method", "Profiler.disable");
71 
72     std::unique_ptr<PtJson> params = PtJson::CreateObject();
73     request->Add("params", params);
74 
75     std::string message = request->Stringify();
76     if (session->ClientSendReq(message)) {
77         session->GetDomainManager().SetDomainById(id, "Profiler");
78     }
79     return 0;
80 }
81 
CpuprofileCommand()82 int ProfilerClient::CpuprofileCommand()
83 {
84     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
85     uint32_t id = session->GetMessageId();
86 
87     idEventMap_.emplace(id, "cpuprofile");
88     std::unique_ptr<PtJson> request = PtJson::CreateObject();
89     request->Add("id", id);
90     request->Add("method", "Profiler.start");
91 
92     std::unique_ptr<PtJson> params = PtJson::CreateObject();
93     request->Add("params", params);
94 
95     std::string message = request->Stringify();
96     if (session->ClientSendReq(message)) {
97         session->GetDomainManager().SetDomainById(id, "Profiler");
98     }
99     return 0;
100 }
101 
CpuprofileStopCommand()102 int ProfilerClient::CpuprofileStopCommand()
103 {
104     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
105     uint32_t id = session->GetMessageId();
106 
107     idEventMap_.emplace(id, "cpuprofilestop");
108     std::unique_ptr<PtJson> request = PtJson::CreateObject();
109     request->Add("id", id);
110     request->Add("method", "Profiler.stop");
111 
112     std::unique_ptr<PtJson> params = PtJson::CreateObject();
113     request->Add("params", params);
114 
115     std::string message = request->Stringify();
116     if (session->ClientSendReq(message)) {
117         session->GetDomainManager().SetDomainById(id, "Profiler");
118     }
119     return 0;
120 }
121 
SetSamplingIntervalCommand()122 int ProfilerClient::SetSamplingIntervalCommand()
123 {
124     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
125     uint32_t id = session->GetMessageId();
126 
127     idEventMap_.emplace(id, "setsamplinginterval");
128     std::unique_ptr<PtJson> request = PtJson::CreateObject();
129     request->Add("id", id);
130     request->Add("method", "Profiler.setSamplingInterval");
131 
132     std::unique_ptr<PtJson> params = PtJson::CreateObject();
133     params->Add("interval", interval_);
134     request->Add("params", params);
135 
136     std::string message = request->Stringify();
137     if (session->ClientSendReq(message)) {
138         session->GetDomainManager().SetDomainById(id, "Profiler");
139     }
140     return 0;
141 }
142 
RecvProfilerResult(std::unique_ptr<PtJson> json)143 void ProfilerClient::RecvProfilerResult(std::unique_ptr<PtJson> json)
144 {
145     if (json == nullptr) {
146         LOGE("arkdb: json parse error");
147         return;
148     }
149 
150     if (!json->IsObject()) {
151         LOGE("arkdb: json parse format error");
152         json->ReleaseRoot();
153         return;
154     }
155 
156     std::unique_ptr<PtJson> result;
157     Result ret = json->GetObject("result", &result);
158     if (ret != Result::SUCCESS) {
159         LOGE("arkdb: find result error");
160         return;
161     }
162 
163     std::unique_ptr<PtJson> profile;
164     ret = result->GetObject("profile", &profile);
165     if (ret != Result::SUCCESS) {
166         LOGE("arkdb: the cmd is not cp-stop!");
167         return;
168     }
169 
170     char date[16];
171     char time[16];
172     bool res = Utils::GetCurrentTime(date, time, sizeof(date));
173     if (!res) {
174         LOGE("arkdb: get time failed");
175         return;
176     }
177 
178     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
179     ProfilerSingleton &pro = session->GetProfilerSingleton();
180     std::string fileName = "CPU-" + std::to_string(sessionId_) + "-" + std::string(date) + "T" +
181                            std::string(time) + ".cpuprofile";
182     std::string cpufile = pro.GetAddress() + fileName;
183     std::cout << "session " << sessionId_ << " cpuprofile file name is " << cpufile << std::endl;
184     std::cout << ">>> ";
185     fflush(stdout);
186     WriteCpuProfileForFile(cpufile, profile->Stringify());
187     pro.AddCpuName(fileName);
188 }
189 
WriteCpuProfileForFile(const std::string & fileName,const std::string & data)190 bool ProfilerClient::WriteCpuProfileForFile(const std::string &fileName, const std::string &data)
191 {
192     std::ofstream ofs;
193     std::string realPath;
194     bool res = Utils::RealPath(fileName, realPath, false);
195     if (!res) {
196         LOGE("arkdb: path is not realpath!");
197         return false;
198     }
199     ofs.open(fileName.c_str(), std::ios::out);
200     if (!ofs.is_open()) {
201         LOGE("arkdb: file open error!");
202         return false;
203     }
204     size_t strSize = data.size();
205     ofs.write(data.c_str(), strSize);
206     ofs.close();
207     ofs.clear();
208     Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
209     ProfilerSingleton &pro = session->GetProfilerSingleton();
210     pro.SetAddress("/data/");
211     return true;
212 }
213 
SetSamplingInterval(int interval)214 void ProfilerClient::SetSamplingInterval(int interval)
215 {
216     this->interval_ = interval;
217 }
218 } // OHOS::ArkCompiler::Toolchain
219