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/heapprofiler_client.h" 17e509ee18Sopenharmony_ci#include "common/log_wrapper.h" 18e509ee18Sopenharmony_ci#include "tooling/utils/utils.h" 19e509ee18Sopenharmony_ci#include "tooling/client/session/session.h" 20e509ee18Sopenharmony_ci 21e509ee18Sopenharmony_ci#include <map> 22e509ee18Sopenharmony_ci#include <functional> 23e509ee18Sopenharmony_ci#include <cstring> 24e509ee18Sopenharmony_ci 25e509ee18Sopenharmony_ciusing Result = panda::ecmascript::tooling::Result; 26e509ee18Sopenharmony_cinamespace OHOS::ArkCompiler::Toolchain { 27e509ee18Sopenharmony_cistatic constexpr int32_t SAMPLING_INTERVAL = 16384; 28e509ee18Sopenharmony_cibool HeapProfilerClient::DispatcherCmd(const std::string &cmd, const std::string &arg) 29e509ee18Sopenharmony_ci{ 30e509ee18Sopenharmony_ci path_ = arg; 31e509ee18Sopenharmony_ci 32e509ee18Sopenharmony_ci std::map<std::string, std::function<int()>> dispatcherTable { 33e509ee18Sopenharmony_ci { "allocationtrack", std::bind(&HeapProfilerClient::AllocationTrackCommand, this)}, 34e509ee18Sopenharmony_ci { "allocationtrack-stop", std::bind(&HeapProfilerClient::AllocationTrackStopCommand, this)}, 35e509ee18Sopenharmony_ci { "heapdump", std::bind(&HeapProfilerClient::HeapDumpCommand, this)}, 36e509ee18Sopenharmony_ci { "heapprofiler-enable", std::bind(&HeapProfilerClient::Enable, this)}, 37e509ee18Sopenharmony_ci { "heapprofiler-disable", std::bind(&HeapProfilerClient::Disable, this)}, 38e509ee18Sopenharmony_ci { "sampling", std::bind(&HeapProfilerClient::Samping, this)}, 39e509ee18Sopenharmony_ci { "sampling-stop", std::bind(&HeapProfilerClient::SampingStop, this)}, 40e509ee18Sopenharmony_ci { "collectgarbage", std::bind(&HeapProfilerClient::CollectGarbage, this)} 41e509ee18Sopenharmony_ci }; 42e509ee18Sopenharmony_ci 43e509ee18Sopenharmony_ci auto entry = dispatcherTable.find(cmd); 44e509ee18Sopenharmony_ci if (entry != dispatcherTable.end() && entry->second != nullptr) { 45e509ee18Sopenharmony_ci entry->second(); 46e509ee18Sopenharmony_ci LOGI("DispatcherCmd reqStr1: %{public}s", cmd.c_str()); 47e509ee18Sopenharmony_ci return true; 48e509ee18Sopenharmony_ci } 49e509ee18Sopenharmony_ci 50e509ee18Sopenharmony_ci LOGI("unknown command: %{public}s", cmd.c_str()); 51e509ee18Sopenharmony_ci return false; 52e509ee18Sopenharmony_ci} 53e509ee18Sopenharmony_ci 54e509ee18Sopenharmony_ciint HeapProfilerClient::HeapDumpCommand() 55e509ee18Sopenharmony_ci{ 56e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 57e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 58e509ee18Sopenharmony_ci 59e509ee18Sopenharmony_ci idEventMap_.emplace(id, HEAPDUMP); 60e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 61e509ee18Sopenharmony_ci request->Add("id", id); 62e509ee18Sopenharmony_ci request->Add("method", "HeapProfiler.takeHeapSnapshot"); 63e509ee18Sopenharmony_ci 64e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 65e509ee18Sopenharmony_ci params->Add("reportProgress", true); 66e509ee18Sopenharmony_ci params->Add("captureNumericValue", true); 67e509ee18Sopenharmony_ci params->Add("exposeInternals", false); 68e509ee18Sopenharmony_ci request->Add("params", params); 69e509ee18Sopenharmony_ci 70e509ee18Sopenharmony_ci std::string message = request->Stringify(); 71e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 72e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "HeapProfiler"); 73e509ee18Sopenharmony_ci } 74e509ee18Sopenharmony_ci return 0; 75e509ee18Sopenharmony_ci} 76e509ee18Sopenharmony_ci 77e509ee18Sopenharmony_ciint HeapProfilerClient::AllocationTrackCommand() 78e509ee18Sopenharmony_ci{ 79e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 80e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 81e509ee18Sopenharmony_ci 82e509ee18Sopenharmony_ci idEventMap_.emplace(id, ALLOCATION); 83e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 84e509ee18Sopenharmony_ci request->Add("id", id); 85e509ee18Sopenharmony_ci request->Add("method", "HeapProfiler.startTrackingHeapObjects"); 86e509ee18Sopenharmony_ci 87e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 88e509ee18Sopenharmony_ci params->Add("trackAllocations", true); 89e509ee18Sopenharmony_ci request->Add("params", params); 90e509ee18Sopenharmony_ci 91e509ee18Sopenharmony_ci std::string message = request->Stringify(); 92e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 93e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "HeapProfiler"); 94e509ee18Sopenharmony_ci } 95e509ee18Sopenharmony_ci return 0; 96e509ee18Sopenharmony_ci} 97e509ee18Sopenharmony_ci 98e509ee18Sopenharmony_ciint HeapProfilerClient::AllocationTrackStopCommand() 99e509ee18Sopenharmony_ci{ 100e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 101e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 102e509ee18Sopenharmony_ci 103e509ee18Sopenharmony_ci idEventMap_.emplace(id, ALLOCATION_STOP); 104e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 105e509ee18Sopenharmony_ci request->Add("id", id); 106e509ee18Sopenharmony_ci request->Add("method", "HeapProfiler.stopTrackingHeapObjects"); 107e509ee18Sopenharmony_ci 108e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 109e509ee18Sopenharmony_ci params->Add("reportProgress", true); 110e509ee18Sopenharmony_ci request->Add("params", params); 111e509ee18Sopenharmony_ci 112e509ee18Sopenharmony_ci std::string message = request->Stringify(); 113e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 114e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "HeapProfiler"); 115e509ee18Sopenharmony_ci } 116e509ee18Sopenharmony_ci return 0; 117e509ee18Sopenharmony_ci} 118e509ee18Sopenharmony_ci 119e509ee18Sopenharmony_ciint HeapProfilerClient::Enable() 120e509ee18Sopenharmony_ci{ 121e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 122e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 123e509ee18Sopenharmony_ci 124e509ee18Sopenharmony_ci idEventMap_.emplace(id, ENABLE); 125e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 126e509ee18Sopenharmony_ci request->Add("id", id); 127e509ee18Sopenharmony_ci request->Add("method", "HeapProfiler.enable"); 128e509ee18Sopenharmony_ci 129e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 130e509ee18Sopenharmony_ci request->Add("params", params); 131e509ee18Sopenharmony_ci 132e509ee18Sopenharmony_ci std::string message = request->Stringify(); 133e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 134e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "HeapProfiler"); 135e509ee18Sopenharmony_ci } 136e509ee18Sopenharmony_ci return 0; 137e509ee18Sopenharmony_ci} 138e509ee18Sopenharmony_ci 139e509ee18Sopenharmony_ciint HeapProfilerClient::Disable() 140e509ee18Sopenharmony_ci{ 141e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 142e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 143e509ee18Sopenharmony_ci 144e509ee18Sopenharmony_ci idEventMap_.emplace(id, DISABLE); 145e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 146e509ee18Sopenharmony_ci request->Add("id", id); 147e509ee18Sopenharmony_ci request->Add("method", "HeapProfiler.disable"); 148e509ee18Sopenharmony_ci 149e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 150e509ee18Sopenharmony_ci request->Add("params", params); 151e509ee18Sopenharmony_ci 152e509ee18Sopenharmony_ci std::string message = request->Stringify(); 153e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 154e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "HeapProfiler"); 155e509ee18Sopenharmony_ci } 156e509ee18Sopenharmony_ci return 0; 157e509ee18Sopenharmony_ci} 158e509ee18Sopenharmony_ci 159e509ee18Sopenharmony_ciint HeapProfilerClient::Samping() 160e509ee18Sopenharmony_ci{ 161e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 162e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 163e509ee18Sopenharmony_ci 164e509ee18Sopenharmony_ci idEventMap_.emplace(id, SAMPLING); 165e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 166e509ee18Sopenharmony_ci request->Add("id", id); 167e509ee18Sopenharmony_ci request->Add("method", "HeapProfiler.startSampling"); 168e509ee18Sopenharmony_ci 169e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 170e509ee18Sopenharmony_ci params->Add("samplingInterval", SAMPLING_INTERVAL); 171e509ee18Sopenharmony_ci request->Add("params", params); 172e509ee18Sopenharmony_ci 173e509ee18Sopenharmony_ci std::string message = request->Stringify(); 174e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 175e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "HeapProfiler"); 176e509ee18Sopenharmony_ci } 177e509ee18Sopenharmony_ci return 0; 178e509ee18Sopenharmony_ci} 179e509ee18Sopenharmony_ci 180e509ee18Sopenharmony_ciint HeapProfilerClient::SampingStop() 181e509ee18Sopenharmony_ci{ 182e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 183e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 184e509ee18Sopenharmony_ci 185e509ee18Sopenharmony_ci idEventMap_.emplace(id, SAMPLING_STOP); 186e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 187e509ee18Sopenharmony_ci request->Add("id", id); 188e509ee18Sopenharmony_ci request->Add("method", "HeapProfiler.stopSampling"); 189e509ee18Sopenharmony_ci 190e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 191e509ee18Sopenharmony_ci request->Add("params", params); 192e509ee18Sopenharmony_ci 193e509ee18Sopenharmony_ci std::string message = request->Stringify(); 194e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 195e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "HeapProfiler"); 196e509ee18Sopenharmony_ci } 197e509ee18Sopenharmony_ci return 0; 198e509ee18Sopenharmony_ci} 199e509ee18Sopenharmony_ci 200e509ee18Sopenharmony_ciint HeapProfilerClient::CollectGarbage() 201e509ee18Sopenharmony_ci{ 202e509ee18Sopenharmony_ci Session *session = SessionManager::getInstance().GetSessionById(sessionId_); 203e509ee18Sopenharmony_ci uint32_t id = session->GetMessageId(); 204e509ee18Sopenharmony_ci 205e509ee18Sopenharmony_ci idEventMap_.emplace(id, COLLECT_GARBAGE); 206e509ee18Sopenharmony_ci std::unique_ptr<PtJson> request = PtJson::CreateObject(); 207e509ee18Sopenharmony_ci request->Add("id", id); 208e509ee18Sopenharmony_ci request->Add("method", "HeapProfiler.collectGarbage"); 209e509ee18Sopenharmony_ci 210e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params = PtJson::CreateObject(); 211e509ee18Sopenharmony_ci request->Add("params", params); 212e509ee18Sopenharmony_ci 213e509ee18Sopenharmony_ci std::string message = request->Stringify(); 214e509ee18Sopenharmony_ci if (session->ClientSendReq(message)) { 215e509ee18Sopenharmony_ci session->GetDomainManager().SetDomainById(id, "HeapProfiler"); 216e509ee18Sopenharmony_ci } 217e509ee18Sopenharmony_ci return 0; 218e509ee18Sopenharmony_ci} 219e509ee18Sopenharmony_ci 220e509ee18Sopenharmony_civoid HeapProfilerClient::RecvReply(std::unique_ptr<PtJson> json) 221e509ee18Sopenharmony_ci{ 222e509ee18Sopenharmony_ci if (json == nullptr) { 223e509ee18Sopenharmony_ci LOGE("json parse error"); 224e509ee18Sopenharmony_ci return; 225e509ee18Sopenharmony_ci } 226e509ee18Sopenharmony_ci if (!json->IsObject()) { 227e509ee18Sopenharmony_ci LOGE("json parse format error"); 228e509ee18Sopenharmony_ci json->ReleaseRoot(); 229e509ee18Sopenharmony_ci return; 230e509ee18Sopenharmony_ci } 231e509ee18Sopenharmony_ci std::unique_ptr<PtJson> result; 232e509ee18Sopenharmony_ci Result ret = json->GetObject("result", &result); 233e509ee18Sopenharmony_ci if (ret == Result::SUCCESS) { 234e509ee18Sopenharmony_ci SaveHeapsamplingData(std::move(result)); 235e509ee18Sopenharmony_ci return; 236e509ee18Sopenharmony_ci } 237e509ee18Sopenharmony_ci std::string wholeMethod; 238e509ee18Sopenharmony_ci std::string method; 239e509ee18Sopenharmony_ci ret = json->GetString("method", &wholeMethod); 240e509ee18Sopenharmony_ci if (ret != Result::SUCCESS || wholeMethod.empty()) { 241e509ee18Sopenharmony_ci LOGE("find method error"); 242e509ee18Sopenharmony_ci return; 243e509ee18Sopenharmony_ci } 244e509ee18Sopenharmony_ci std::string::size_type length = wholeMethod.length(); 245e509ee18Sopenharmony_ci std::string::size_type indexPoint = 0; 246e509ee18Sopenharmony_ci indexPoint = wholeMethod.find_first_of('.', 0); 247e509ee18Sopenharmony_ci if (indexPoint == std::string::npos || indexPoint == 0 || indexPoint == length - 1) { 248e509ee18Sopenharmony_ci return; 249e509ee18Sopenharmony_ci } 250e509ee18Sopenharmony_ci method = wholeMethod.substr(indexPoint + 1, length); 251e509ee18Sopenharmony_ci if (method == "lastSeenObjectId") { 252e509ee18Sopenharmony_ci isAllocationMsg_ = true; 253e509ee18Sopenharmony_ci } 254e509ee18Sopenharmony_ci std::unique_ptr<PtJson> params; 255e509ee18Sopenharmony_ci ret = json->GetObject("params", ¶ms); 256e509ee18Sopenharmony_ci if (ret != Result::SUCCESS) { 257e509ee18Sopenharmony_ci LOGE("find params error"); 258e509ee18Sopenharmony_ci return; 259e509ee18Sopenharmony_ci } 260e509ee18Sopenharmony_ci std::string chunk; 261e509ee18Sopenharmony_ci ret = params->GetString("chunk", &chunk); 262e509ee18Sopenharmony_ci if (ret == Result::SUCCESS) { 263e509ee18Sopenharmony_ci SaveHeapSnapshotAndAllocationTrackData(chunk); 264e509ee18Sopenharmony_ci } 265e509ee18Sopenharmony_ci return; 266e509ee18Sopenharmony_ci} 267e509ee18Sopenharmony_ci 268e509ee18Sopenharmony_civoid HeapProfilerClient::SaveHeapSnapshotAndAllocationTrackData(const std::string &chunk) 269e509ee18Sopenharmony_ci{ 270e509ee18Sopenharmony_ci std::string head = "{\"snapshot\":\n"; 271e509ee18Sopenharmony_ci std::string heapFile; 272e509ee18Sopenharmony_ci if (!strncmp(chunk.c_str(), head.c_str(), head.length())) { 273e509ee18Sopenharmony_ci char date[16]; 274e509ee18Sopenharmony_ci char time[16]; 275e509ee18Sopenharmony_ci bool res = Utils::GetCurrentTime(date, time, sizeof(date)); 276e509ee18Sopenharmony_ci if (!res) { 277e509ee18Sopenharmony_ci LOGE("arkdb: get time failed"); 278e509ee18Sopenharmony_ci return; 279e509ee18Sopenharmony_ci } 280e509ee18Sopenharmony_ci if (isAllocationMsg_) { 281e509ee18Sopenharmony_ci heapFile = "Heap-" + std::to_string(sessionId_) + "-" + std::string(date) + "T" + std::string(time) + 282e509ee18Sopenharmony_ci ".heaptimeline"; 283e509ee18Sopenharmony_ci fileName_ = path_ + heapFile; 284e509ee18Sopenharmony_ci std::cout << "heaptimeline file name is " << fileName_ << std::endl; 285e509ee18Sopenharmony_ci } else { 286e509ee18Sopenharmony_ci heapFile = "Heap-"+ std::to_string(sessionId_) + "-" + std::string(date) + "T" + std::string(time) + 287e509ee18Sopenharmony_ci ".heapsnapshot"; 288e509ee18Sopenharmony_ci fileName_ = path_ + heapFile; 289e509ee18Sopenharmony_ci std::cout << "heapsnapshot file name is " << fileName_ << std::endl; 290e509ee18Sopenharmony_ci } 291e509ee18Sopenharmony_ci std::cout << ">>> "; 292e509ee18Sopenharmony_ci fflush(stdout); 293e509ee18Sopenharmony_ci } 294e509ee18Sopenharmony_ci 295e509ee18Sopenharmony_ci std::string tail = "]\n}\n"; 296e509ee18Sopenharmony_ci std::string subStr = chunk.substr(chunk.length() - tail.length(), chunk.length()); 297e509ee18Sopenharmony_ci if (!strncmp(subStr.c_str(), tail.c_str(), tail.length())) { 298e509ee18Sopenharmony_ci isAllocationMsg_ = false; 299e509ee18Sopenharmony_ci } 300e509ee18Sopenharmony_ci WriteHeapProfilerForFile(fileName_, chunk); 301e509ee18Sopenharmony_ci return; 302e509ee18Sopenharmony_ci} 303e509ee18Sopenharmony_ci 304e509ee18Sopenharmony_civoid HeapProfilerClient::SaveHeapsamplingData(std::unique_ptr<PtJson> result) 305e509ee18Sopenharmony_ci{ 306e509ee18Sopenharmony_ci std::unique_ptr<PtJson> profile; 307e509ee18Sopenharmony_ci std::string heapFile; 308e509ee18Sopenharmony_ci Result ret = result->GetObject("profile", &profile); 309e509ee18Sopenharmony_ci if (ret != Result::SUCCESS) { 310e509ee18Sopenharmony_ci LOGE("arkdb: get profile failed"); 311e509ee18Sopenharmony_ci return; 312e509ee18Sopenharmony_ci } 313e509ee18Sopenharmony_ci char date[16]; 314e509ee18Sopenharmony_ci char time[16]; 315e509ee18Sopenharmony_ci bool res = Utils::GetCurrentTime(date, time, sizeof(date)); 316e509ee18Sopenharmony_ci if (!res) { 317e509ee18Sopenharmony_ci LOGE("arkdb: get time failed"); 318e509ee18Sopenharmony_ci return; 319e509ee18Sopenharmony_ci } 320e509ee18Sopenharmony_ci heapFile = "Heap-" + std::to_string(sessionId_) + "-" + std::string(date) + "T" + std::string(time) + 321e509ee18Sopenharmony_ci ".heapprofile"; 322e509ee18Sopenharmony_ci fileName_ = path_ + heapFile; 323e509ee18Sopenharmony_ci std::cout << "heapprofile file name is " << fileName_ << std::endl; 324e509ee18Sopenharmony_ci std::cout << ">>> "; 325e509ee18Sopenharmony_ci fflush(stdout); 326e509ee18Sopenharmony_ci 327e509ee18Sopenharmony_ci WriteHeapProfilerForFile(fileName_, profile->Stringify()); 328e509ee18Sopenharmony_ci return; 329e509ee18Sopenharmony_ci} 330e509ee18Sopenharmony_ci 331e509ee18Sopenharmony_cibool HeapProfilerClient::WriteHeapProfilerForFile(const std::string &fileName, const std::string &data) 332e509ee18Sopenharmony_ci{ 333e509ee18Sopenharmony_ci std::ofstream ofs; 334e509ee18Sopenharmony_ci std::string realPath; 335e509ee18Sopenharmony_ci bool res = Utils::RealPath(fileName, realPath, false); 336e509ee18Sopenharmony_ci if (!res) { 337e509ee18Sopenharmony_ci LOGE("arkdb: path is not realpath!"); 338e509ee18Sopenharmony_ci return false; 339e509ee18Sopenharmony_ci } 340e509ee18Sopenharmony_ci ofs.open(fileName.c_str(), std::ios::app); 341e509ee18Sopenharmony_ci if (!ofs.is_open()) { 342e509ee18Sopenharmony_ci LOGE("arkdb: file open error!"); 343e509ee18Sopenharmony_ci return false; 344e509ee18Sopenharmony_ci } 345e509ee18Sopenharmony_ci size_t strSize = data.size(); 346e509ee18Sopenharmony_ci ofs.write(data.c_str(), strSize); 347e509ee18Sopenharmony_ci ofs.close(); 348e509ee18Sopenharmony_ci ofs.clear(); 349e509ee18Sopenharmony_ci return true; 350e509ee18Sopenharmony_ci} 351e509ee18Sopenharmony_ci} // OHOS::ArkCompiler::Toolchain