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", &params);
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