1e509ee18Sopenharmony_ci/* 2e509ee18Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3e509ee18Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e509ee18Sopenharmony_ci * you may not use this file except in compliance with the License. 5e509ee18Sopenharmony_ci * You may obtain a copy of the License at 6e509ee18Sopenharmony_ci * 7e509ee18Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e509ee18Sopenharmony_ci * 9e509ee18Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e509ee18Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e509ee18Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e509ee18Sopenharmony_ci * See the License for the specific language governing permissions and 13e509ee18Sopenharmony_ci * limitations under the License. 14e509ee18Sopenharmony_ci */ 15e509ee18Sopenharmony_ci 16e509ee18Sopenharmony_ci#include "tooling/client/domain/profiler_client.h" 17e509ee18Sopenharmony_ci#include "tooling/base/pt_types.h" 18e509ee18Sopenharmony_ci#include "common/log_wrapper.h" 19e509ee18Sopenharmony_ci#include "tooling/utils/utils.h" 20e509ee18Sopenharmony_ci#include "tooling/client/session/session.h" 21e509ee18Sopenharmony_ci 22e509ee18Sopenharmony_ci#include <map> 23e509ee18Sopenharmony_ci#include <functional> 24e509ee18Sopenharmony_ci#include <cstring> 25e509ee18Sopenharmony_ci#include <fstream> 26e509ee18Sopenharmony_ci 27e509ee18Sopenharmony_ciusing Result = panda::ecmascript::tooling::Result; 28e509ee18Sopenharmony_ciusing Profile = panda::ecmascript::tooling::Profile; 29e509ee18Sopenharmony_cinamespace OHOS::ArkCompiler::Toolchain { 30e509ee18Sopenharmony_cibool ProfilerClient::DispatcherCmd(const std::string &cmd) 31e509ee18Sopenharmony_ci{ 32e509ee18Sopenharmony_ci std::map<std::string, std::function<int()>> dispatcherTable { 33e509ee18Sopenharmony_ci { "cpuprofile", std::bind(&ProfilerClient::CpuprofileCommand, this)}, 34e509ee18Sopenharmony_ci { "cpuprofile-stop", std::bind(&ProfilerClient::CpuprofileStopCommand, this)}, 35e509ee18Sopenharmony_ci { "cpuprofile-setSamplingInterval", std::bind(&ProfilerClient::SetSamplingIntervalCommand, this)}, 36e509ee18Sopenharmony_ci { "cpuprofile-enable", std::bind(&ProfilerClient::CpuprofileEnableCommand, this)}, 37e509ee18Sopenharmony_ci { "cpuprofile-disable", std::bind(&ProfilerClient::CpuprofileDisableCommand, this)}, 38e509ee18Sopenharmony_ci }; 39e509ee18Sopenharmony_ci 40e509ee18Sopenharmony_ci auto entry = dispatcherTable.find(cmd); 41e509ee18Sopenharmony_ci if (entry == dispatcherTable.end()) { 42e509ee18Sopenharmony_ci LOGI("Unknown commond: %{public}s", cmd.c_str()); 43e509ee18Sopenharmony_ci return false; 44e509ee18Sopenharmony_ci } 45e509ee18Sopenharmony_ci entry->second(); 46e509ee18Sopenharmony_ci LOGI("DispatcherCmd cmd: %{public}s", cmd.c_str()); 47e509ee18Sopenharmony_ci return true; 48e509ee18Sopenharmony_ci} 49e509ee18Sopenharmony_ci 50e509ee18Sopenharmony_ciint ProfilerClient::CpuprofileEnableCommand() 51e509ee18Sopenharmony_ci{ 52e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 53e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 54e509ee18Sopenharmony_ci 55e509ee18Sopenharmony_ci idEventMap_.emplace(id, "cpuprofileenable"); 56e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 57e509ee18Sopenharmony_ci request->Add("id", id); 58e509ee18Sopenharmony_ci request->Add("method", "Profiler.enable"); 59e509ee18Sopenharmony_ci 60e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 61e509ee18Sopenharmony_ci request->Add("params", params); 62e509ee18Sopenharmony_ci 63e509ee18Sopenharmony_ci std::string message = request->Stringify(); 64e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 65e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "Profiler"); 66e509ee18Sopenharmony_ci } 67e509ee18Sopenharmony_ci return 0; 68e509ee18Sopenharmony_ci} 69e509ee18Sopenharmony_ci 70e509ee18Sopenharmony_ciint ProfilerClient::CpuprofileDisableCommand() 71e509ee18Sopenharmony_ci{ 72e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 73e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 74e509ee18Sopenharmony_ci 75e509ee18Sopenharmony_ci idEventMap_.emplace(id, "cpuprofiledisable"); 76e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 77e509ee18Sopenharmony_ci request->Add("id", id); 78e509ee18Sopenharmony_ci request->Add("method", "Profiler.disable"); 79e509ee18Sopenharmony_ci 80e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 81e509ee18Sopenharmony_ci request->Add("params", params); 82e509ee18Sopenharmony_ci 83e509ee18Sopenharmony_ci std::string message = request->Stringify(); 84e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 85e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "Profiler"); 86e509ee18Sopenharmony_ci } 87e509ee18Sopenharmony_ci return 0; 88e509ee18Sopenharmony_ci} 89e509ee18Sopenharmony_ci 90e509ee18Sopenharmony_ciint ProfilerClient::CpuprofileCommand() 91e509ee18Sopenharmony_ci{ 92e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 93e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 94e509ee18Sopenharmony_ci 95e509ee18Sopenharmony_ci idEventMap_.emplace(id, "cpuprofile"); 96e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 97e509ee18Sopenharmony_ci request->Add("id", id); 98e509ee18Sopenharmony_ci request->Add("method", "Profiler.start"); 99e509ee18Sopenharmony_ci 100e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 101e509ee18Sopenharmony_ci request->Add("params", params); 102e509ee18Sopenharmony_ci 103e509ee18Sopenharmony_ci std::string message = request->Stringify(); 104e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 105e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "Profiler"); 106e509ee18Sopenharmony_ci } 107e509ee18Sopenharmony_ci return 0; 108e509ee18Sopenharmony_ci} 109e509ee18Sopenharmony_ci 110e509ee18Sopenharmony_ciint ProfilerClient::CpuprofileStopCommand() 111e509ee18Sopenharmony_ci{ 112e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 113e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 114e509ee18Sopenharmony_ci 115e509ee18Sopenharmony_ci idEventMap_.emplace(id, "cpuprofilestop"); 116e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 117e509ee18Sopenharmony_ci request->Add("id", id); 118e509ee18Sopenharmony_ci request->Add("method", "Profiler.stop"); 119e509ee18Sopenharmony_ci 120e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 121e509ee18Sopenharmony_ci request->Add("params", params); 122e509ee18Sopenharmony_ci 123e509ee18Sopenharmony_ci std::string message = request->Stringify(); 124e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 125e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "Profiler"); 126e509ee18Sopenharmony_ci } 127e509ee18Sopenharmony_ci return 0; 128e509ee18Sopenharmony_ci} 129e509ee18Sopenharmony_ci 130e509ee18Sopenharmony_ciint ProfilerClient::SetSamplingIntervalCommand() 131e509ee18Sopenharmony_ci{ 132e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 133e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 134e509ee18Sopenharmony_ci 135e509ee18Sopenharmony_ci idEventMap_.emplace(id, "setsamplinginterval"); 136e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 137e509ee18Sopenharmony_ci request->Add("id", id); 138e509ee18Sopenharmony_ci request->Add("method", "Profiler.setSamplingInterval"); 139e509ee18Sopenharmony_ci 140e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 141e509ee18Sopenharmony_ci params->Add("interval", interval_); 142e509ee18Sopenharmony_ci request->Add("params", params); 143e509ee18Sopenharmony_ci 144e509ee18Sopenharmony_ci std::string message = request->Stringify(); 145e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 146e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "Profiler"); 147e509ee18Sopenharmony_ci } 148e509ee18Sopenharmony_ci return 0; 149e509ee18Sopenharmony_ci} 150e509ee18Sopenharmony_ci 151e509ee18Sopenharmony_civoid ProfilerClient::RecvProfilerResult(std::unique_ptr<PtJson> json) 152e509ee18Sopenharmony_ci{ 153e509ee18Sopenharmony_ci if (json == nullptr) { 154e509ee18Sopenharmony_ci LOGE("arkdb: json parse error"); 155e509ee18Sopenharmony_ci return; 156e509ee18Sopenharmony_ci } 157e509ee18Sopenharmony_ci 158e509ee18Sopenharmony_ci if (!json->IsObject()) { 159e509ee18Sopenharmony_ci LOGE("arkdb: json parse format error"); 160e509ee18Sopenharmony_ci json->ReleaseRoot(); 161e509ee18Sopenharmony_ci return; 162e509ee18Sopenharmony_ci } 163e509ee18Sopenharmony_ci 164e509ee18Sopenharmony_ci std::unique_ptr<PtJson> result; 165e509ee18Sopenharmony_ci Result ret = json->GetObject("result", &result); 166e509ee18Sopenharmony_ci if (ret != Result::SUCCESS) { 167e509ee18Sopenharmony_ci LOGE("arkdb: find result error"); 168e509ee18Sopenharmony_ci return; 169e509ee18Sopenharmony_ci } 170e509ee18Sopenharmony_ci 171e509ee18Sopenharmony_ci std::unique_ptr<PtJson> profile; 172e509ee18Sopenharmony_ci ret = result->GetObject("profile", &profile); 173e509ee18Sopenharmony_ci if (ret != Result::SUCCESS) { 174e509ee18Sopenharmony_ci LOGE("arkdb: the cmd is not cp-stop!"); 175e509ee18Sopenharmony_ci return; 176e509ee18Sopenharmony_ci } 177e509ee18Sopenharmony_ci 178e509ee18Sopenharmony_ci char date[16]; 179e509ee18Sopenharmony_ci char time[16]; 180e509ee18Sopenharmony_ci bool res = Utils::GetCurrentTime(date, time, sizeof(date)); 181e509ee18Sopenharmony_ci if (!res) { 182e509ee18Sopenharmony_ci LOGE("arkdb: get time failed"); 183e509ee18Sopenharmony_ci return; 184e509ee18Sopenharmony_ci } 185e509ee18Sopenharmony_ci 186e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 187e509ee18Sopenharmony_ci ProfilerSingleton &pro = session->GetProfilerSingleton(); 188e509ee18Sopenharmony_ci std::string fileName = "CPU-" + std::to_string(sessionId_) + "-" + std::string(date) + "T" + 189e509ee18Sopenharmony_ci std::string(time) + ".cpuprofile"; 190e509ee18Sopenharmony_ci std::string cpufile = pro.GetAddress() + fileName; 191e509ee18Sopenharmony_ci std::cout << "session " << sessionId_ << " cpuprofile file name is " << cpufile << std::endl; 192e509ee18Sopenharmony_ci std::cout << ">>> "; 193e509ee18Sopenharmony_ci fflush(stdout); 194e509ee18Sopenharmony_ci WriteCpuProfileForFile(cpufile, profile->Stringify()); 195e509ee18Sopenharmony_ci pro.AddCpuName(fileName); 196e509ee18Sopenharmony_ci} 197e509ee18Sopenharmony_ci 198e509ee18Sopenharmony_cibool ProfilerClient::WriteCpuProfileForFile(const std::string &fileName, const std::string &data) 199e509ee18Sopenharmony_ci{ 200e509ee18Sopenharmony_ci std::ofstream ofs; 201e509ee18Sopenharmony_ci std::string realPath; 202e509ee18Sopenharmony_ci bool res = Utils::RealPath(fileName, realPath, false); 203e509ee18Sopenharmony_ci if (!res) { 204e509ee18Sopenharmony_ci LOGE("arkdb: path is not realpath!"); 205e509ee18Sopenharmony_ci return false; 206e509ee18Sopenharmony_ci } 207e509ee18Sopenharmony_ci ofs.open(fileName.c_str(), std::ios::out); 208e509ee18Sopenharmony_ci if (!ofs.is_open()) { 209e509ee18Sopenharmony_ci LOGE("arkdb: file open error!"); 210e509ee18Sopenharmony_ci return false; 211e509ee18Sopenharmony_ci } 212e509ee18Sopenharmony_ci size_t strSize = data.size(); 213e509ee18Sopenharmony_ci ofs.write(data.c_str(), strSize); 214e509ee18Sopenharmony_ci ofs.close(); 215e509ee18Sopenharmony_ci ofs.clear(); 216e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 217e509ee18Sopenharmony_ci ProfilerSingleton &pro = session->GetProfilerSingleton(); 218e509ee18Sopenharmony_ci pro.SetAddress("/data/"); 219e509ee18Sopenharmony_ci return true; 220e509ee18Sopenharmony_ci} 221e509ee18Sopenharmony_ci 222e509ee18Sopenharmony_civoid ProfilerClient::SetSamplingInterval(int interval) 223e509ee18Sopenharmony_ci{ 224e509ee18Sopenharmony_ci this->interval_ = interval; 225e509ee18Sopenharmony_ci} 226e509ee18Sopenharmony_ci} // OHOS::ArkCompiler::Toolchain 227