1209bc2fbSopenharmony_ci/*
2209bc2fbSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3209bc2fbSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4209bc2fbSopenharmony_ci * you may not use this file except in compliance with the License.
5209bc2fbSopenharmony_ci * You may obtain a copy of the License at
6209bc2fbSopenharmony_ci *
7209bc2fbSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8209bc2fbSopenharmony_ci *
9209bc2fbSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10209bc2fbSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11209bc2fbSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12209bc2fbSopenharmony_ci * See the License for the specific language governing permissions and
13209bc2fbSopenharmony_ci * limitations under the License.
14209bc2fbSopenharmony_ci */
15209bc2fbSopenharmony_ci
16209bc2fbSopenharmony_ci#include "xcollie_utils.h"
17209bc2fbSopenharmony_ci#include <ctime>
18209bc2fbSopenharmony_ci#include <cinttypes>
19209bc2fbSopenharmony_ci#include <algorithm>
20209bc2fbSopenharmony_ci#include <cstdlib>
21209bc2fbSopenharmony_ci#include <csignal>
22209bc2fbSopenharmony_ci#include <sstream>
23209bc2fbSopenharmony_ci#include <iostream>
24209bc2fbSopenharmony_ci#include <unistd.h>
25209bc2fbSopenharmony_ci#include <fcntl.h>
26209bc2fbSopenharmony_ci#include <sys/prctl.h>
27209bc2fbSopenharmony_ci#include <sys/stat.h>
28209bc2fbSopenharmony_ci#include <set>
29209bc2fbSopenharmony_ci#include "directory_ex.h"
30209bc2fbSopenharmony_ci#include "file_ex.h"
31209bc2fbSopenharmony_ci#include "storage_acl.h"
32209bc2fbSopenharmony_ci#include "parameter.h"
33209bc2fbSopenharmony_ci#include "parameters.h"
34209bc2fbSopenharmony_ci#include <dlfcn.h>
35209bc2fbSopenharmony_ci
36209bc2fbSopenharmony_cinamespace OHOS {
37209bc2fbSopenharmony_cinamespace HiviewDFX {
38209bc2fbSopenharmony_cinamespace {
39209bc2fbSopenharmony_ciconstexpr int64_t SEC_TO_MANOSEC = 1000000000;
40209bc2fbSopenharmony_ciconstexpr int64_t SEC_TO_MICROSEC = 1000000;
41209bc2fbSopenharmony_ciconstexpr uint64_t MAX_FILE_SIZE = 10 * 1024 * 1024; // 10M
42209bc2fbSopenharmony_ciconst int MAX_NAME_SIZE = 128;
43209bc2fbSopenharmony_ciconst int MIN_WAIT_NUM = 3;
44209bc2fbSopenharmony_ciconst int TIME_INDEX_MAX = 32;
45209bc2fbSopenharmony_ciconst int INIT_PID = 1;
46209bc2fbSopenharmony_ciconstexpr const char* const LOGGER_TEANSPROC_PATH = "/proc/transaction_proc";
47209bc2fbSopenharmony_ciconstexpr const char* const WATCHDOG_DIR = "/data/storage/el2/log/watchdog";
48209bc2fbSopenharmony_ciconstexpr const char* const KEY_ANCO_ENABLE_TYPE = "persist.hmos_fusion_mgr.ctl.support_hmos";
49209bc2fbSopenharmony_ciconstexpr const char* const KEY_DEVELOPER_MODE_STATE = "const.security.developermode.state";
50209bc2fbSopenharmony_ciconstexpr const char* const KEY_BETA_TYPE = "const.logsystem.versiontype";
51209bc2fbSopenharmony_ciconstexpr const char* const ENABLE_VAULE = "true";
52209bc2fbSopenharmony_ciconstexpr const char* const ENABLE_BETA_VAULE = "beta";
53209bc2fbSopenharmony_ci}
54209bc2fbSopenharmony_ciuint64_t GetCurrentTickMillseconds()
55209bc2fbSopenharmony_ci{
56209bc2fbSopenharmony_ci    struct timespec t;
57209bc2fbSopenharmony_ci    t.tv_sec = 0;
58209bc2fbSopenharmony_ci    t.tv_nsec = 0;
59209bc2fbSopenharmony_ci    clock_gettime(CLOCK_MONOTONIC, &t);
60209bc2fbSopenharmony_ci    return static_cast<uint64_t>((t.tv_sec) * SEC_TO_MANOSEC + t.tv_nsec) / SEC_TO_MICROSEC;
61209bc2fbSopenharmony_ci}
62209bc2fbSopenharmony_ci
63209bc2fbSopenharmony_cibool IsFileNameFormat(char c)
64209bc2fbSopenharmony_ci{
65209bc2fbSopenharmony_ci    if (c >= '0' && c <= '9') {
66209bc2fbSopenharmony_ci        return false;
67209bc2fbSopenharmony_ci    }
68209bc2fbSopenharmony_ci
69209bc2fbSopenharmony_ci    if (c >= 'a' && c <= 'z') {
70209bc2fbSopenharmony_ci        return false;
71209bc2fbSopenharmony_ci    }
72209bc2fbSopenharmony_ci
73209bc2fbSopenharmony_ci    if (c >= 'A' && c <= 'Z') {
74209bc2fbSopenharmony_ci        return false;
75209bc2fbSopenharmony_ci    }
76209bc2fbSopenharmony_ci
77209bc2fbSopenharmony_ci    if (c == '.' || c == '-' || c == '_') {
78209bc2fbSopenharmony_ci        return false;
79209bc2fbSopenharmony_ci    }
80209bc2fbSopenharmony_ci
81209bc2fbSopenharmony_ci    return true;
82209bc2fbSopenharmony_ci}
83209bc2fbSopenharmony_ci
84209bc2fbSopenharmony_cistd::string GetSelfProcName()
85209bc2fbSopenharmony_ci{
86209bc2fbSopenharmony_ci    constexpr uint16_t READ_SIZE = 128;
87209bc2fbSopenharmony_ci    std::ifstream fin;
88209bc2fbSopenharmony_ci    fin.open("/proc/self/comm", std::ifstream::in);
89209bc2fbSopenharmony_ci    if (!fin.is_open()) {
90209bc2fbSopenharmony_ci        XCOLLIE_LOGE("fin.is_open() false");
91209bc2fbSopenharmony_ci        return "";
92209bc2fbSopenharmony_ci    }
93209bc2fbSopenharmony_ci    char readStr[READ_SIZE] = {'\0'};
94209bc2fbSopenharmony_ci    fin.getline(readStr, READ_SIZE - 1);
95209bc2fbSopenharmony_ci    fin.close();
96209bc2fbSopenharmony_ci
97209bc2fbSopenharmony_ci    std::string ret = std::string(readStr);
98209bc2fbSopenharmony_ci    ret.erase(std::remove_if(ret.begin(), ret.end(), IsFileNameFormat), ret.end());
99209bc2fbSopenharmony_ci    return ret;
100209bc2fbSopenharmony_ci}
101209bc2fbSopenharmony_ci
102209bc2fbSopenharmony_cistd::string GetFirstLine(const std::string& path)
103209bc2fbSopenharmony_ci{
104209bc2fbSopenharmony_ci    char checkPath[PATH_MAX] = {0};
105209bc2fbSopenharmony_ci    if (realpath(path.c_str(), checkPath) == nullptr) {
106209bc2fbSopenharmony_ci        XCOLLIE_LOGE("canonicalize failed. path is %{public}s", path.c_str());
107209bc2fbSopenharmony_ci        return "";
108209bc2fbSopenharmony_ci    }
109209bc2fbSopenharmony_ci
110209bc2fbSopenharmony_ci    std::ifstream inFile(checkPath);
111209bc2fbSopenharmony_ci    if (!inFile) {
112209bc2fbSopenharmony_ci        return "";
113209bc2fbSopenharmony_ci    }
114209bc2fbSopenharmony_ci    std::string firstLine;
115209bc2fbSopenharmony_ci    getline(inFile, firstLine);
116209bc2fbSopenharmony_ci    inFile.close();
117209bc2fbSopenharmony_ci    return firstLine;
118209bc2fbSopenharmony_ci}
119209bc2fbSopenharmony_ci
120209bc2fbSopenharmony_cibool IsDeveloperOpen()
121209bc2fbSopenharmony_ci{
122209bc2fbSopenharmony_ci    static std::string isDeveloperOpen;
123209bc2fbSopenharmony_ci    if (!isDeveloperOpen.empty()) {
124209bc2fbSopenharmony_ci        return (isDeveloperOpen.find(ENABLE_VAULE) != std::string::npos);
125209bc2fbSopenharmony_ci    }
126209bc2fbSopenharmony_ci    isDeveloperOpen = system::GetParameter(KEY_DEVELOPER_MODE_STATE, "");
127209bc2fbSopenharmony_ci    return (isDeveloperOpen.find(ENABLE_VAULE) != std::string::npos);
128209bc2fbSopenharmony_ci}
129209bc2fbSopenharmony_ci
130209bc2fbSopenharmony_cibool IsBetaVersion()
131209bc2fbSopenharmony_ci{
132209bc2fbSopenharmony_ci    static std::string isBetaVersion;
133209bc2fbSopenharmony_ci    if (!isBetaVersion.empty()) {
134209bc2fbSopenharmony_ci        return (isBetaVersion.find(ENABLE_BETA_VAULE) != std::string::npos);
135209bc2fbSopenharmony_ci    }
136209bc2fbSopenharmony_ci    isBetaVersion = system::GetParameter(KEY_BETA_TYPE, "");
137209bc2fbSopenharmony_ci    return (isBetaVersion.find(ENABLE_BETA_VAULE) != std::string::npos);
138209bc2fbSopenharmony_ci}
139209bc2fbSopenharmony_ci
140209bc2fbSopenharmony_cistd::string GetProcessNameFromProcCmdline(int32_t pid)
141209bc2fbSopenharmony_ci{
142209bc2fbSopenharmony_ci    static std::string curProcName;
143209bc2fbSopenharmony_ci    if (!curProcName.empty()) {
144209bc2fbSopenharmony_ci        return curProcName;
145209bc2fbSopenharmony_ci    }
146209bc2fbSopenharmony_ci    std::string procCmdlinePath = "/proc/" + std::to_string(pid) + "/cmdline";
147209bc2fbSopenharmony_ci    std::string procCmdlineContent = GetFirstLine(procCmdlinePath);
148209bc2fbSopenharmony_ci    if (procCmdlineContent.empty()) {
149209bc2fbSopenharmony_ci        return "";
150209bc2fbSopenharmony_ci    }
151209bc2fbSopenharmony_ci
152209bc2fbSopenharmony_ci    size_t procNameStartPos = 0;
153209bc2fbSopenharmony_ci    size_t procNameEndPos = procCmdlineContent.size();
154209bc2fbSopenharmony_ci    for (size_t i = 0; i < procCmdlineContent.size(); i++) {
155209bc2fbSopenharmony_ci        if (procCmdlineContent[i] == '/') {
156209bc2fbSopenharmony_ci            procNameStartPos = i + 1;
157209bc2fbSopenharmony_ci        } else if (procCmdlineContent[i] == '\0') {
158209bc2fbSopenharmony_ci            procNameEndPos = i;
159209bc2fbSopenharmony_ci            break;
160209bc2fbSopenharmony_ci        }
161209bc2fbSopenharmony_ci    }
162209bc2fbSopenharmony_ci    size_t endPos = procNameEndPos - procNameStartPos;
163209bc2fbSopenharmony_ci    curProcName = procCmdlineContent.substr(procNameStartPos, endPos);
164209bc2fbSopenharmony_ci    XCOLLIE_LOGD("curProcName is empty, name %{public}s pid %{public}d", curProcName.c_str(), pid);
165209bc2fbSopenharmony_ci    return curProcName;
166209bc2fbSopenharmony_ci}
167209bc2fbSopenharmony_ci
168209bc2fbSopenharmony_cistd::string GetLimitedSizeName(std::string name)
169209bc2fbSopenharmony_ci{
170209bc2fbSopenharmony_ci    if (name.size() > MAX_NAME_SIZE) {
171209bc2fbSopenharmony_ci        return name.substr(0, MAX_NAME_SIZE);
172209bc2fbSopenharmony_ci    }
173209bc2fbSopenharmony_ci    return name;
174209bc2fbSopenharmony_ci}
175209bc2fbSopenharmony_ci
176209bc2fbSopenharmony_cibool IsProcessDebug(int32_t pid)
177209bc2fbSopenharmony_ci{
178209bc2fbSopenharmony_ci    const int buffSize = 128;
179209bc2fbSopenharmony_ci    char paramBundle[buffSize] = {0};
180209bc2fbSopenharmony_ci    GetParameter("hiviewdfx.appfreeze.filter_bundle_name", "", paramBundle, buffSize - 1);
181209bc2fbSopenharmony_ci    std::string debugBundle(paramBundle);
182209bc2fbSopenharmony_ci    std::string procCmdlineContent = GetProcessNameFromProcCmdline(pid);
183209bc2fbSopenharmony_ci    if (procCmdlineContent.compare(debugBundle) == 0) {
184209bc2fbSopenharmony_ci        XCOLLIE_LOGI("appfreeze filtration %{public}s_%{public}s don't exit.",
185209bc2fbSopenharmony_ci            debugBundle.c_str(), procCmdlineContent.c_str());
186209bc2fbSopenharmony_ci        return true;
187209bc2fbSopenharmony_ci    }
188209bc2fbSopenharmony_ci    return false;
189209bc2fbSopenharmony_ci}
190209bc2fbSopenharmony_ci
191209bc2fbSopenharmony_civoid DelayBeforeExit(unsigned int leftTime)
192209bc2fbSopenharmony_ci{
193209bc2fbSopenharmony_ci    while (leftTime > 0) {
194209bc2fbSopenharmony_ci        leftTime = sleep(leftTime);
195209bc2fbSopenharmony_ci    }
196209bc2fbSopenharmony_ci}
197209bc2fbSopenharmony_ci
198209bc2fbSopenharmony_cistd::string TrimStr(const std::string& str, const char cTrim)
199209bc2fbSopenharmony_ci{
200209bc2fbSopenharmony_ci    std::string strTmp = str;
201209bc2fbSopenharmony_ci    strTmp.erase(0, strTmp.find_first_not_of(cTrim));
202209bc2fbSopenharmony_ci    strTmp.erase(strTmp.find_last_not_of(cTrim) + sizeof(char));
203209bc2fbSopenharmony_ci    return strTmp;
204209bc2fbSopenharmony_ci}
205209bc2fbSopenharmony_ci
206209bc2fbSopenharmony_civoid SplitStr(const std::string& str, const std::string& sep,
207209bc2fbSopenharmony_ci    std::vector<std::string>& strs, bool canEmpty, bool needTrim)
208209bc2fbSopenharmony_ci{
209209bc2fbSopenharmony_ci    strs.clear();
210209bc2fbSopenharmony_ci    std::string strTmp = needTrim ? TrimStr(str) : str;
211209bc2fbSopenharmony_ci    std::string strPart;
212209bc2fbSopenharmony_ci    while (true) {
213209bc2fbSopenharmony_ci        std::string::size_type pos = strTmp.find(sep);
214209bc2fbSopenharmony_ci        if (pos == std::string::npos || sep.empty()) {
215209bc2fbSopenharmony_ci            strPart = needTrim ? TrimStr(strTmp) : strTmp;
216209bc2fbSopenharmony_ci            if (!strPart.empty() || canEmpty) {
217209bc2fbSopenharmony_ci                strs.push_back(strPart);
218209bc2fbSopenharmony_ci            }
219209bc2fbSopenharmony_ci            break;
220209bc2fbSopenharmony_ci        } else {
221209bc2fbSopenharmony_ci            strPart = needTrim ? TrimStr(strTmp.substr(0, pos)) : strTmp.substr(0, pos);
222209bc2fbSopenharmony_ci            if (!strPart.empty() || canEmpty) {
223209bc2fbSopenharmony_ci                strs.push_back(strPart);
224209bc2fbSopenharmony_ci            }
225209bc2fbSopenharmony_ci            strTmp = strTmp.substr(sep.size() + pos, strTmp.size() - sep.size() - pos);
226209bc2fbSopenharmony_ci        }
227209bc2fbSopenharmony_ci    }
228209bc2fbSopenharmony_ci}
229209bc2fbSopenharmony_ci
230209bc2fbSopenharmony_ciint ParsePeerBinderPid(std::ifstream& fin, int32_t pid)
231209bc2fbSopenharmony_ci{
232209bc2fbSopenharmony_ci    const int decimal = 10;
233209bc2fbSopenharmony_ci    std::string line;
234209bc2fbSopenharmony_ci    bool isBinderMatchup = false;
235209bc2fbSopenharmony_ci    while (getline(fin, line)) {
236209bc2fbSopenharmony_ci        if (isBinderMatchup) {
237209bc2fbSopenharmony_ci            break;
238209bc2fbSopenharmony_ci        }
239209bc2fbSopenharmony_ci
240209bc2fbSopenharmony_ci        if (line.find("async\t") != std::string::npos) {
241209bc2fbSopenharmony_ci            continue;
242209bc2fbSopenharmony_ci        }
243209bc2fbSopenharmony_ci
244209bc2fbSopenharmony_ci        std::istringstream lineStream(line);
245209bc2fbSopenharmony_ci        std::vector<std::string> strList;
246209bc2fbSopenharmony_ci        std::string tmpstr;
247209bc2fbSopenharmony_ci        while (lineStream >> tmpstr) {
248209bc2fbSopenharmony_ci            strList.push_back(tmpstr);
249209bc2fbSopenharmony_ci        }
250209bc2fbSopenharmony_ci
251209bc2fbSopenharmony_ci        auto splitPhase = [](const std::string& str, uint16_t index) -> std::string {
252209bc2fbSopenharmony_ci            std::vector<std::string> strings;
253209bc2fbSopenharmony_ci            SplitStr(str, ":", strings);
254209bc2fbSopenharmony_ci            if (index < strings.size()) {
255209bc2fbSopenharmony_ci                return strings[index];
256209bc2fbSopenharmony_ci            }
257209bc2fbSopenharmony_ci            return "";
258209bc2fbSopenharmony_ci        };
259209bc2fbSopenharmony_ci
260209bc2fbSopenharmony_ci        if (strList.size() >= 7) { // 7: valid array size
261209bc2fbSopenharmony_ci            // 2: peer id,
262209bc2fbSopenharmony_ci            std::string server = splitPhase(strList[2], 0);
263209bc2fbSopenharmony_ci            // 0: local id,
264209bc2fbSopenharmony_ci            std::string client = splitPhase(strList[0], 0);
265209bc2fbSopenharmony_ci            // 5: wait time, s
266209bc2fbSopenharmony_ci            std::string wait = splitPhase(strList[5], 1);
267209bc2fbSopenharmony_ci            if (server == "" || client == "" || wait == "") {
268209bc2fbSopenharmony_ci                continue;
269209bc2fbSopenharmony_ci            }
270209bc2fbSopenharmony_ci            int serverNum = std::strtol(server.c_str(), nullptr, decimal);
271209bc2fbSopenharmony_ci            int clientNum = std::strtol(client.c_str(), nullptr, decimal);
272209bc2fbSopenharmony_ci            int waitNum = std::strtol(wait.c_str(), nullptr, decimal);
273209bc2fbSopenharmony_ci            XCOLLIE_LOGI("server:%{public}d, client:%{public}d, wait:%{public}d",
274209bc2fbSopenharmony_ci                serverNum, clientNum, waitNum);
275209bc2fbSopenharmony_ci            if (clientNum != pid || waitNum < MIN_WAIT_NUM) {
276209bc2fbSopenharmony_ci                continue;
277209bc2fbSopenharmony_ci            }
278209bc2fbSopenharmony_ci            return serverNum;
279209bc2fbSopenharmony_ci        }
280209bc2fbSopenharmony_ci        if (line.find("context") != line.npos) {
281209bc2fbSopenharmony_ci            isBinderMatchup = true;
282209bc2fbSopenharmony_ci        }
283209bc2fbSopenharmony_ci    }
284209bc2fbSopenharmony_ci    return -1;
285209bc2fbSopenharmony_ci}
286209bc2fbSopenharmony_ci
287209bc2fbSopenharmony_cibool KillProcessByPid(int32_t pid)
288209bc2fbSopenharmony_ci{
289209bc2fbSopenharmony_ci    std::ifstream fin;
290209bc2fbSopenharmony_ci    std::string path = std::string(LOGGER_TEANSPROC_PATH);
291209bc2fbSopenharmony_ci    char resolvePath[PATH_MAX] = {0};
292209bc2fbSopenharmony_ci    if (realpath(path.c_str(), resolvePath) == nullptr) {
293209bc2fbSopenharmony_ci        XCOLLIE_LOGI("GetBinderPeerPids realpath error");
294209bc2fbSopenharmony_ci        return false;
295209bc2fbSopenharmony_ci    }
296209bc2fbSopenharmony_ci    fin.open(resolvePath);
297209bc2fbSopenharmony_ci    if (!fin.is_open()) {
298209bc2fbSopenharmony_ci        XCOLLIE_LOGI("open file failed, %{public}s.", resolvePath);
299209bc2fbSopenharmony_ci        return false;
300209bc2fbSopenharmony_ci    }
301209bc2fbSopenharmony_ci
302209bc2fbSopenharmony_ci    int peerBinderPid = ParsePeerBinderPid(fin, pid);
303209bc2fbSopenharmony_ci    fin.close();
304209bc2fbSopenharmony_ci    if (peerBinderPid <= INIT_PID || peerBinderPid == pid) {
305209bc2fbSopenharmony_ci        XCOLLIE_LOGI("No PeerBinder process freeze occurs in the current process. "
306209bc2fbSopenharmony_ci            "peerBinderPid=%{public}d, pid=%{public}d", peerBinderPid, pid);
307209bc2fbSopenharmony_ci        return false;
308209bc2fbSopenharmony_ci    }
309209bc2fbSopenharmony_ci
310209bc2fbSopenharmony_ci    XCOLLIE_LOGI("try to Kill PeerBinder process, name=%{public}s, pid=%{public}d",
311209bc2fbSopenharmony_ci        GetProcessNameFromProcCmdline(peerBinderPid).c_str(), peerBinderPid);
312209bc2fbSopenharmony_ci    int32_t ret = kill(peerBinderPid, SIGKILL);
313209bc2fbSopenharmony_ci    if (ret == -1) {
314209bc2fbSopenharmony_ci        XCOLLIE_LOGI("Kill PeerBinder process failed");
315209bc2fbSopenharmony_ci    }
316209bc2fbSopenharmony_ci    return (ret >= 0);
317209bc2fbSopenharmony_ci}
318209bc2fbSopenharmony_ci
319209bc2fbSopenharmony_cibool CreateWatchdogDir()
320209bc2fbSopenharmony_ci{
321209bc2fbSopenharmony_ci    constexpr mode_t defaultLogDirMode = 0770;
322209bc2fbSopenharmony_ci    if (!OHOS::FileExists(WATCHDOG_DIR)) {
323209bc2fbSopenharmony_ci        OHOS::ForceCreateDirectory(WATCHDOG_DIR);
324209bc2fbSopenharmony_ci        OHOS::ChangeModeDirectory(WATCHDOG_DIR, defaultLogDirMode);
325209bc2fbSopenharmony_ci    }
326209bc2fbSopenharmony_ci    if (OHOS::StorageDaemon::AclSetAccess(WATCHDOG_DIR, "g:1201:rwx") != 0) {
327209bc2fbSopenharmony_ci        XCOLLIE_LOGI("Failed to AclSetAccess");
328209bc2fbSopenharmony_ci        return false;
329209bc2fbSopenharmony_ci    }
330209bc2fbSopenharmony_ci    return true;
331209bc2fbSopenharmony_ci}
332209bc2fbSopenharmony_ci
333209bc2fbSopenharmony_cibool WriteStackToFd(int32_t pid, std::string& path, std::string& stack, const std::string& eventName)
334209bc2fbSopenharmony_ci{
335209bc2fbSopenharmony_ci    if (!CreateWatchdogDir()) {
336209bc2fbSopenharmony_ci        return false;
337209bc2fbSopenharmony_ci    }
338209bc2fbSopenharmony_ci    std::string time = GetFormatDate();
339209bc2fbSopenharmony_ci    std::string realPath;
340209bc2fbSopenharmony_ci    if (!OHOS::PathToRealPath(WATCHDOG_DIR, realPath)) {
341209bc2fbSopenharmony_ci        XCOLLIE_LOGE("Path to realPath failed.");
342209bc2fbSopenharmony_ci        return false;
343209bc2fbSopenharmony_ci    }
344209bc2fbSopenharmony_ci    path = realPath + "/" + eventName + "_" + time.c_str() + "_" +
345209bc2fbSopenharmony_ci        std::to_string(pid).c_str() + ".txt";
346209bc2fbSopenharmony_ci    uint64_t stackSize = stack.size();
347209bc2fbSopenharmony_ci    uint64_t fileSize = OHOS::GetFolderSize(realPath) + stackSize;
348209bc2fbSopenharmony_ci    if (fileSize > MAX_FILE_SIZE) {
349209bc2fbSopenharmony_ci        XCOLLIE_LOGE("CurrentDir already over limit. Will not write to stack file."
350209bc2fbSopenharmony_ci            "MainThread fileSize: %{public}" PRIu64 " MAX_FILE_SIZE: %{public}" PRIu64 ".",
351209bc2fbSopenharmony_ci            fileSize, MAX_FILE_SIZE);
352209bc2fbSopenharmony_ci        return true;
353209bc2fbSopenharmony_ci    }
354209bc2fbSopenharmony_ci    constexpr mode_t defaultLogFileMode = 0644;
355209bc2fbSopenharmony_ci    auto fd = open(path.c_str(), O_CREAT | O_WRONLY | O_TRUNC, defaultLogFileMode);
356209bc2fbSopenharmony_ci    if (fd < 0) {
357209bc2fbSopenharmony_ci        XCOLLIE_LOGE("Failed to create path");
358209bc2fbSopenharmony_ci        return false;
359209bc2fbSopenharmony_ci    } else {
360209bc2fbSopenharmony_ci        XCOLLIE_LOGE("path=%{public}s", path.c_str());
361209bc2fbSopenharmony_ci    }
362209bc2fbSopenharmony_ci    OHOS::SaveStringToFd(fd, stack);
363209bc2fbSopenharmony_ci    close(fd);
364209bc2fbSopenharmony_ci
365209bc2fbSopenharmony_ci    return true;
366209bc2fbSopenharmony_ci}
367209bc2fbSopenharmony_ci
368209bc2fbSopenharmony_cistd::string GetFormatDate()
369209bc2fbSopenharmony_ci{
370209bc2fbSopenharmony_ci    time_t t = time(nullptr);
371209bc2fbSopenharmony_ci    char tmp[TIME_INDEX_MAX] = {0};
372209bc2fbSopenharmony_ci    strftime(tmp, sizeof(tmp), "%Y%m%d%H%M%S", localtime(&t));
373209bc2fbSopenharmony_ci    std::string date(tmp);
374209bc2fbSopenharmony_ci    return date;
375209bc2fbSopenharmony_ci}
376209bc2fbSopenharmony_ci
377209bc2fbSopenharmony_ciint64_t GetTimeStamp()
378209bc2fbSopenharmony_ci{
379209bc2fbSopenharmony_ci    std::chrono::nanoseconds ms = std::chrono::duration_cast< std::chrono::nanoseconds >(
380209bc2fbSopenharmony_ci        std::chrono::system_clock::now().time_since_epoch());
381209bc2fbSopenharmony_ci    return ms.count();
382209bc2fbSopenharmony_ci}
383209bc2fbSopenharmony_ci
384209bc2fbSopenharmony_cibool IsEnableVersion()
385209bc2fbSopenharmony_ci{
386209bc2fbSopenharmony_ci    auto enableType = system::GetParameter(KEY_ANCO_ENABLE_TYPE, "");
387209bc2fbSopenharmony_ci    return (enableType.find(ENABLE_VAULE) != std::string::npos);
388209bc2fbSopenharmony_ci}
389209bc2fbSopenharmony_ci
390209bc2fbSopenharmony_civoid* FunctionOpen(void* funcHandler, const char* funcName)
391209bc2fbSopenharmony_ci{
392209bc2fbSopenharmony_ci    dlerror();
393209bc2fbSopenharmony_ci    char* err = nullptr;
394209bc2fbSopenharmony_ci    void* func = dlsym(funcHandler, funcName);
395209bc2fbSopenharmony_ci    err = dlerror();
396209bc2fbSopenharmony_ci    if (err != nullptr) {
397209bc2fbSopenharmony_ci        XCOLLIE_LOGE("dlopen %{public}s failed. %{public}s\n", funcName, err);
398209bc2fbSopenharmony_ci        return nullptr;
399209bc2fbSopenharmony_ci    }
400209bc2fbSopenharmony_ci    return func;
401209bc2fbSopenharmony_ci}
402209bc2fbSopenharmony_ci} // end of HiviewDFX
403209bc2fbSopenharmony_ci} // end of OHOS