1800b99b8Sopenharmony_ci/*
2800b99b8Sopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License.
5800b99b8Sopenharmony_ci * You may obtain a copy of the License at
6800b99b8Sopenharmony_ci *
7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8800b99b8Sopenharmony_ci *
9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and
13800b99b8Sopenharmony_ci * limitations under the License.
14800b99b8Sopenharmony_ci */
15800b99b8Sopenharmony_ci
16800b99b8Sopenharmony_ci#include "dfx_dump_catcher.h"
17800b99b8Sopenharmony_ci
18800b99b8Sopenharmony_ci#include <atomic>
19800b99b8Sopenharmony_ci#include <cerrno>
20800b99b8Sopenharmony_ci#include <memory>
21800b99b8Sopenharmony_ci#include <thread>
22800b99b8Sopenharmony_ci#include <vector>
23800b99b8Sopenharmony_ci
24800b99b8Sopenharmony_ci#include <dlfcn.h>
25800b99b8Sopenharmony_ci#include <poll.h>
26800b99b8Sopenharmony_ci#include <sys/syscall.h>
27800b99b8Sopenharmony_ci#include <sys/types.h>
28800b99b8Sopenharmony_ci#include <securec.h>
29800b99b8Sopenharmony_ci#include <strings.h>
30800b99b8Sopenharmony_ci
31800b99b8Sopenharmony_ci#include "backtrace_local.h"
32800b99b8Sopenharmony_ci#include "dfx_define.h"
33800b99b8Sopenharmony_ci#include "dfx_dump_res.h"
34800b99b8Sopenharmony_ci#include "dfx_kernel_stack.h"
35800b99b8Sopenharmony_ci#include "dfx_log.h"
36800b99b8Sopenharmony_ci#include "dfx_trace_dlsym.h"
37800b99b8Sopenharmony_ci#include "dfx_util.h"
38800b99b8Sopenharmony_ci#include "elapsed_time.h"
39800b99b8Sopenharmony_ci#include "faultloggerd_client.h"
40800b99b8Sopenharmony_ci#include "file_ex.h"
41800b99b8Sopenharmony_ci#include "procinfo.h"
42800b99b8Sopenharmony_ci
43800b99b8Sopenharmony_cinamespace OHOS {
44800b99b8Sopenharmony_cinamespace HiviewDFX {
45800b99b8Sopenharmony_cinamespace {
46800b99b8Sopenharmony_ci#ifdef LOG_DOMAIN
47800b99b8Sopenharmony_ci#undef LOG_DOMAIN
48800b99b8Sopenharmony_ci#define LOG_DOMAIN 0xD002D11
49800b99b8Sopenharmony_ci#endif
50800b99b8Sopenharmony_ci
51800b99b8Sopenharmony_ci#ifdef LOG_TAG
52800b99b8Sopenharmony_ci#undef LOG_TAG
53800b99b8Sopenharmony_ci#define LOG_TAG "DfxDumpCatcher"
54800b99b8Sopenharmony_ci#endif
55800b99b8Sopenharmony_cistatic const int DUMP_CATCHE_WORK_TIME_S = 60;
56800b99b8Sopenharmony_cistatic const std::string DFXDUMPCATCHER_TAG = "DfxDumpCatcher";
57800b99b8Sopenharmony_cistatic std::string g_kernelStackInfo;
58800b99b8Sopenharmony_cistatic std::atomic_bool g_asyncThreadRunning;
59800b99b8Sopenharmony_cistatic pid_t g_kernelStackPid = 0;
60800b99b8Sopenharmony_cistatic std::condition_variable g_cv;
61800b99b8Sopenharmony_cistatic std::mutex g_kernelStackMutex;
62800b99b8Sopenharmony_cistatic constexpr int WAIT_GET_KERNEL_STACK_TIMEOUT = 1000; // 1000 : time out 1000 ms
63800b99b8Sopenharmony_ci
64800b99b8Sopenharmony_cienum DfxDumpPollRes : int32_t {
65800b99b8Sopenharmony_ci    DUMP_POLL_INIT = -1,
66800b99b8Sopenharmony_ci    DUMP_POLL_OK,
67800b99b8Sopenharmony_ci    DUMP_POLL_FD,
68800b99b8Sopenharmony_ci    DUMP_POLL_FAILED,
69800b99b8Sopenharmony_ci    DUMP_POLL_TIMEOUT,
70800b99b8Sopenharmony_ci    DUMP_POLL_RETURN,
71800b99b8Sopenharmony_ci};
72800b99b8Sopenharmony_ci
73800b99b8Sopenharmony_cienum DfxDumpStatRes : int32_t {
74800b99b8Sopenharmony_ci    DUMP_RES_NO_KERNELSTACK = -2,
75800b99b8Sopenharmony_ci    DUMP_RES_WITH_KERNELSTACK = -1,
76800b99b8Sopenharmony_ci    DUMP_RES_WITH_USERSTACK = 0,
77800b99b8Sopenharmony_ci};
78800b99b8Sopenharmony_ci}
79800b99b8Sopenharmony_ci
80800b99b8Sopenharmony_cibool DfxDumpCatcher::DoDumpCurrTid(const size_t skipFrameNum, std::string& msg, size_t maxFrameNums)
81800b99b8Sopenharmony_ci{
82800b99b8Sopenharmony_ci    bool ret = false;
83800b99b8Sopenharmony_ci
84800b99b8Sopenharmony_ci    ret = GetBacktrace(msg, skipFrameNum + 1, false, maxFrameNums);
85800b99b8Sopenharmony_ci    if (!ret) {
86800b99b8Sopenharmony_ci        int currTid = gettid();
87800b99b8Sopenharmony_ci        msg.append("Failed to dump curr thread:" + std::to_string(currTid) + ".\n");
88800b99b8Sopenharmony_ci    }
89800b99b8Sopenharmony_ci    DFXLOGD("%{public}s :: DoDumpCurrTid :: return %{public}d.", DFXDUMPCATCHER_TAG.c_str(), ret);
90800b99b8Sopenharmony_ci    return ret;
91800b99b8Sopenharmony_ci}
92800b99b8Sopenharmony_ci
93800b99b8Sopenharmony_cibool DfxDumpCatcher::DoDumpLocalTid(const int tid, std::string& msg, size_t maxFrameNums)
94800b99b8Sopenharmony_ci{
95800b99b8Sopenharmony_ci    bool ret = false;
96800b99b8Sopenharmony_ci    if (tid <= 0) {
97800b99b8Sopenharmony_ci        DFXLOGE("%{public}s :: DoDumpLocalTid :: return false as param error.", DFXDUMPCATCHER_TAG.c_str());
98800b99b8Sopenharmony_ci        return ret;
99800b99b8Sopenharmony_ci    }
100800b99b8Sopenharmony_ci    ret = GetBacktraceStringByTid(msg, tid, 0, false, maxFrameNums);
101800b99b8Sopenharmony_ci    if (!ret) {
102800b99b8Sopenharmony_ci        msg.append("Failed to dump thread:" + std::to_string(tid) + ".\n");
103800b99b8Sopenharmony_ci    }
104800b99b8Sopenharmony_ci    DFXLOGD("%{public}s :: DoDumpLocalTid :: return %{public}d.", DFXDUMPCATCHER_TAG.c_str(), ret);
105800b99b8Sopenharmony_ci    return ret;
106800b99b8Sopenharmony_ci}
107800b99b8Sopenharmony_ci
108800b99b8Sopenharmony_cibool DfxDumpCatcher::DoDumpLocalPid(int pid, std::string& msg, size_t maxFrameNums)
109800b99b8Sopenharmony_ci{
110800b99b8Sopenharmony_ci    bool ret = false;
111800b99b8Sopenharmony_ci    if (pid <= 0) {
112800b99b8Sopenharmony_ci        DFXLOGE("%{public}s :: DoDumpLocalPid :: return false as param error.", DFXDUMPCATCHER_TAG.c_str());
113800b99b8Sopenharmony_ci        return ret;
114800b99b8Sopenharmony_ci    }
115800b99b8Sopenharmony_ci    size_t skipFramNum = 5; // 5: skip 5 frame
116800b99b8Sopenharmony_ci
117800b99b8Sopenharmony_ci    msg = GetStacktraceHeader();
118800b99b8Sopenharmony_ci    std::function<bool(int)> func = [&](int tid) {
119800b99b8Sopenharmony_ci        if (tid <= 0) {
120800b99b8Sopenharmony_ci            return false;
121800b99b8Sopenharmony_ci        }
122800b99b8Sopenharmony_ci        std::string threadMsg;
123800b99b8Sopenharmony_ci        if (tid == gettid()) {
124800b99b8Sopenharmony_ci            ret = DoDumpCurrTid(skipFramNum, threadMsg, maxFrameNums);
125800b99b8Sopenharmony_ci        } else {
126800b99b8Sopenharmony_ci            ret = DoDumpLocalTid(tid, threadMsg, maxFrameNums);
127800b99b8Sopenharmony_ci        }
128800b99b8Sopenharmony_ci        msg += threadMsg;
129800b99b8Sopenharmony_ci        return ret;
130800b99b8Sopenharmony_ci    };
131800b99b8Sopenharmony_ci    std::vector<int> tids;
132800b99b8Sopenharmony_ci    ret = GetTidsByPidWithFunc(getpid(), tids, func);
133800b99b8Sopenharmony_ci    DFXLOGD("%{public}s :: DoDumpLocalPid :: return %{public}d.", DFXDUMPCATCHER_TAG.c_str(), ret);
134800b99b8Sopenharmony_ci    return ret;
135800b99b8Sopenharmony_ci}
136800b99b8Sopenharmony_ci
137800b99b8Sopenharmony_cibool DfxDumpCatcher::DoDumpRemoteLocked(int pid, int tid, std::string& msg, bool isJson, int timeout)
138800b99b8Sopenharmony_ci{
139800b99b8Sopenharmony_ci    return DoDumpCatchRemote(pid, tid, msg, isJson, timeout);
140800b99b8Sopenharmony_ci}
141800b99b8Sopenharmony_ci
142800b99b8Sopenharmony_cibool DfxDumpCatcher::DoDumpLocalLocked(int pid, int tid, std::string& msg, size_t maxFrameNums)
143800b99b8Sopenharmony_ci{
144800b99b8Sopenharmony_ci    bool ret = false;
145800b99b8Sopenharmony_ci    if (tid == gettid()) {
146800b99b8Sopenharmony_ci        size_t skipFramNum = 4; // 4: skip 4 frame
147800b99b8Sopenharmony_ci        ret = DoDumpCurrTid(skipFramNum, msg, maxFrameNums);
148800b99b8Sopenharmony_ci    } else if (tid == 0) {
149800b99b8Sopenharmony_ci        ret = DoDumpLocalPid(pid, msg, maxFrameNums);
150800b99b8Sopenharmony_ci    } else {
151800b99b8Sopenharmony_ci        if (!IsThreadInPid(pid, tid)) {
152800b99b8Sopenharmony_ci            msg.append("tid(" + std::to_string(tid) + ") is not in pid(" + std::to_string(pid) + ").\n");
153800b99b8Sopenharmony_ci        } else {
154800b99b8Sopenharmony_ci            ret = DoDumpLocalTid(tid, msg, maxFrameNums);
155800b99b8Sopenharmony_ci        }
156800b99b8Sopenharmony_ci    }
157800b99b8Sopenharmony_ci
158800b99b8Sopenharmony_ci    DFXLOGD("%{public}s :: DoDumpLocal :: ret(%{public}d).", DFXDUMPCATCHER_TAG.c_str(), ret);
159800b99b8Sopenharmony_ci    return ret;
160800b99b8Sopenharmony_ci}
161800b99b8Sopenharmony_ci
162800b99b8Sopenharmony_cistatic void ReportDumpCatcherStats(int32_t pid,
163800b99b8Sopenharmony_ci    uint64_t requestTime, bool ret, std::string& msg, void* retAddr)
164800b99b8Sopenharmony_ci{
165800b99b8Sopenharmony_ci    std::vector<uint8_t> buf(sizeof(struct FaultLoggerdStatsRequest), 0);
166800b99b8Sopenharmony_ci    auto stat = reinterpret_cast<struct FaultLoggerdStatsRequest*>(buf.data());
167800b99b8Sopenharmony_ci    stat->type = DUMP_CATCHER;
168800b99b8Sopenharmony_ci    stat->pid = pid;
169800b99b8Sopenharmony_ci    stat->requestTime = requestTime;
170800b99b8Sopenharmony_ci    stat->dumpCatcherFinishTime = GetTimeMilliSeconds();
171800b99b8Sopenharmony_ci    stat->result = ret ? DUMP_RES_WITH_USERSTACK : DUMP_RES_WITH_KERNELSTACK; // we need more detailed failure info
172800b99b8Sopenharmony_ci    if (!ret && g_kernelStackInfo.empty()) {
173800b99b8Sopenharmony_ci        stat->result = DUMP_RES_NO_KERNELSTACK;
174800b99b8Sopenharmony_ci    }
175800b99b8Sopenharmony_ci    size_t copyLen;
176800b99b8Sopenharmony_ci    std::string processName;
177800b99b8Sopenharmony_ci    ReadProcessName(pid, processName);
178800b99b8Sopenharmony_ci    copyLen = std::min(sizeof(stat->targetProcess) - 1, processName.size());
179800b99b8Sopenharmony_ci    if (memcpy_s(stat->targetProcess, sizeof(stat->targetProcess) - 1, processName.c_str(), copyLen) != 0) {
180800b99b8Sopenharmony_ci        DFXLOGE("%{public}s::Failed to copy target process", DFXDUMPCATCHER_TAG.c_str());
181800b99b8Sopenharmony_ci        return;
182800b99b8Sopenharmony_ci    }
183800b99b8Sopenharmony_ci
184800b99b8Sopenharmony_ci    if (!ret) {
185800b99b8Sopenharmony_ci        copyLen = std::min(sizeof(stat->summary) - 1, msg.size());
186800b99b8Sopenharmony_ci        if (memcpy_s(stat->summary, sizeof(stat->summary) - 1, msg.c_str(), copyLen) != 0) {
187800b99b8Sopenharmony_ci            DFXLOGE("%{public}s::Failed to copy dumpcatcher summary", DFXDUMPCATCHER_TAG.c_str());
188800b99b8Sopenharmony_ci            return;
189800b99b8Sopenharmony_ci        }
190800b99b8Sopenharmony_ci    }
191800b99b8Sopenharmony_ci
192800b99b8Sopenharmony_ci    Dl_info info;
193800b99b8Sopenharmony_ci    if (dladdr(retAddr, &info) != 0) {
194800b99b8Sopenharmony_ci        copyLen = std::min(sizeof(stat->callerElf) - 1, strlen(info.dli_fname));
195800b99b8Sopenharmony_ci        if (memcpy_s(stat->callerElf, sizeof(stat->callerElf) - 1, info.dli_fname, copyLen) != 0) {
196800b99b8Sopenharmony_ci            DFXLOGE("%{public}s::Failed to copy caller elf info", DFXDUMPCATCHER_TAG.c_str());
197800b99b8Sopenharmony_ci            return;
198800b99b8Sopenharmony_ci        }
199800b99b8Sopenharmony_ci        stat->offset = reinterpret_cast<uintptr_t>(retAddr) - reinterpret_cast<uintptr_t>(info.dli_fbase);
200800b99b8Sopenharmony_ci    }
201800b99b8Sopenharmony_ci
202800b99b8Sopenharmony_ci    std::string cmdline;
203800b99b8Sopenharmony_ci    if (OHOS::LoadStringFromFile("/proc/self/cmdline", cmdline)) {
204800b99b8Sopenharmony_ci        copyLen = std::min(sizeof(stat->callerProcess) - 1, cmdline.size());
205800b99b8Sopenharmony_ci        if (memcpy_s(stat->callerProcess, sizeof(stat->callerProcess) - 1,
206800b99b8Sopenharmony_ci            cmdline.c_str(), copyLen) != 0) {
207800b99b8Sopenharmony_ci            DFXLOGE("%{public}s::Failed to copy caller cmdline", DFXDUMPCATCHER_TAG.c_str());
208800b99b8Sopenharmony_ci            return;
209800b99b8Sopenharmony_ci        }
210800b99b8Sopenharmony_ci    }
211800b99b8Sopenharmony_ci
212800b99b8Sopenharmony_ci    ReportDumpStats(stat);
213800b99b8Sopenharmony_ci}
214800b99b8Sopenharmony_ci
215800b99b8Sopenharmony_ciint DfxDumpCatcher::DumpCatchProcess(int pid, std::string& msg, size_t maxFrameNums, bool isJson)
216800b99b8Sopenharmony_ci{
217800b99b8Sopenharmony_ci    if (DumpCatch(pid, 0, msg, maxFrameNums, isJson)) {
218800b99b8Sopenharmony_ci        return 0;
219800b99b8Sopenharmony_ci    }
220800b99b8Sopenharmony_ci    if (pid == g_kernelStackPid && !g_asyncThreadRunning) {
221800b99b8Sopenharmony_ci        msg.append(g_kernelStackInfo);
222800b99b8Sopenharmony_ci        g_kernelStackInfo.clear();
223800b99b8Sopenharmony_ci        g_kernelStackPid = 0;
224800b99b8Sopenharmony_ci        return 1;
225800b99b8Sopenharmony_ci    }
226800b99b8Sopenharmony_ci    return -1;
227800b99b8Sopenharmony_ci}
228800b99b8Sopenharmony_ci
229800b99b8Sopenharmony_cibool DfxDumpCatcher::DumpCatch(int pid, int tid, std::string& msg, size_t maxFrameNums, bool isJson)
230800b99b8Sopenharmony_ci{
231800b99b8Sopenharmony_ci    bool ret = false;
232800b99b8Sopenharmony_ci    if (pid <= 0 || tid < 0) {
233800b99b8Sopenharmony_ci        DFXLOGE("%{public}s :: dump_catch :: param error.", DFXDUMPCATCHER_TAG.c_str());
234800b99b8Sopenharmony_ci        return ret;
235800b99b8Sopenharmony_ci    }
236800b99b8Sopenharmony_ci    std::string statusPath = StringPrintf("/proc/%d/status", pid);
237800b99b8Sopenharmony_ci    if (access(statusPath.c_str(), F_OK) != 0 && errno != EACCES) {
238800b99b8Sopenharmony_ci        DFXLOGE("DumpCatch:: the pid(%{public}d) process has exited, errno(%{public}d)", pid, errno);
239800b99b8Sopenharmony_ci        msg.append("Result: pid(" + std::to_string(pid) + ") process has exited.\n");
240800b99b8Sopenharmony_ci        return ret;
241800b99b8Sopenharmony_ci    }
242800b99b8Sopenharmony_ci    DfxEnableTraceDlsym(true);
243800b99b8Sopenharmony_ci    ElapsedTime counter;
244800b99b8Sopenharmony_ci    std::unique_lock<std::mutex> lck(mutex_);
245800b99b8Sopenharmony_ci    int currentPid = getpid();
246800b99b8Sopenharmony_ci    bool reportStat = false;
247800b99b8Sopenharmony_ci    uint64_t requestTime = GetTimeMilliSeconds();
248800b99b8Sopenharmony_ci    DFXLOGW("Receive DumpCatch request for cPid:(%{public}d), pid(%{public}d), " \
249800b99b8Sopenharmony_ci        "tid:(%{public}d).", currentPid, pid, tid);
250800b99b8Sopenharmony_ci    if (pid == currentPid) {
251800b99b8Sopenharmony_ci        ret = DoDumpLocalLocked(pid, tid, msg, maxFrameNums);
252800b99b8Sopenharmony_ci    } else {
253800b99b8Sopenharmony_ci        if (maxFrameNums != DEFAULT_MAX_FRAME_NUM) {
254800b99b8Sopenharmony_ci            DFXLOGI("%{public}s :: dump_catch :: maxFrameNums does not support setting " \
255800b99b8Sopenharmony_ci                "when pid is not equal to caller pid", DFXDUMPCATCHER_TAG.c_str());
256800b99b8Sopenharmony_ci        }
257800b99b8Sopenharmony_ci        reportStat = true;
258800b99b8Sopenharmony_ci        int timeout = (tid == 0 ? 3 : 10) * 1000; // when tid not zero, timeout is 10s
259800b99b8Sopenharmony_ci        ret = DoDumpRemoteLocked(pid, tid, msg, isJson, timeout);
260800b99b8Sopenharmony_ci    }
261800b99b8Sopenharmony_ci
262800b99b8Sopenharmony_ci    if (reportStat) {
263800b99b8Sopenharmony_ci        void* retAddr = __builtin_return_address(0);
264800b99b8Sopenharmony_ci        ReportDumpCatcherStats(pid, requestTime, ret, msg, retAddr);
265800b99b8Sopenharmony_ci    }
266800b99b8Sopenharmony_ci
267800b99b8Sopenharmony_ci    DFXLOGW("dump_catch : pid = %{public}d, elapsed time = %{public}" PRId64 " ms, ret = %{public}d, " \
268800b99b8Sopenharmony_ci        "msgLength = %{public}zu",
269800b99b8Sopenharmony_ci        pid, counter.Elapsed<std::chrono::milliseconds>(), ret, msg.size());
270800b99b8Sopenharmony_ci    DfxEnableTraceDlsym(false);
271800b99b8Sopenharmony_ci    return ret;
272800b99b8Sopenharmony_ci}
273800b99b8Sopenharmony_ci
274800b99b8Sopenharmony_cibool DfxDumpCatcher::DumpCatchFd(int pid, int tid, std::string& msg, int fd, size_t maxFrameNums)
275800b99b8Sopenharmony_ci{
276800b99b8Sopenharmony_ci    bool ret = false;
277800b99b8Sopenharmony_ci    ret = DumpCatch(pid, tid, msg, maxFrameNums);
278800b99b8Sopenharmony_ci    if (fd > 0) {
279800b99b8Sopenharmony_ci        ret = OHOS_TEMP_FAILURE_RETRY(write(fd, msg.c_str(), msg.length()));
280800b99b8Sopenharmony_ci    }
281800b99b8Sopenharmony_ci    return ret;
282800b99b8Sopenharmony_ci}
283800b99b8Sopenharmony_ci
284800b99b8Sopenharmony_cibool DfxDumpCatcher::DoDumpCatchRemote(int pid, int tid, std::string& msg, bool isJson, int timeout)
285800b99b8Sopenharmony_ci{
286800b99b8Sopenharmony_ci    DFX_TRACE_SCOPED_DLSYM("DoDumpCatchRemote");
287800b99b8Sopenharmony_ci    bool ret = false;
288800b99b8Sopenharmony_ci    if (pid <= 0 || tid < 0) {
289800b99b8Sopenharmony_ci        msg.append("Result: pid(" + std::to_string(pid) + ") param error.\n");
290800b99b8Sopenharmony_ci        DFXLOGW("%{public}s :: %{public}s :: %{public}s", DFXDUMPCATCHER_TAG.c_str(), __func__, msg.c_str());
291800b99b8Sopenharmony_ci        return ret;
292800b99b8Sopenharmony_ci    }
293800b99b8Sopenharmony_ci    pid_ = pid;
294800b99b8Sopenharmony_ci    int sdkdumpRet = RequestSdkDumpJson(pid, tid, isJson, timeout);
295800b99b8Sopenharmony_ci    if (sdkdumpRet != static_cast<int>(FaultLoggerSdkDumpResp::SDK_DUMP_PASS)) {
296800b99b8Sopenharmony_ci        if (sdkdumpRet == static_cast<int>(FaultLoggerSdkDumpResp::SDK_DUMP_REPEAT)) {
297800b99b8Sopenharmony_ci            AsyncGetAllTidKernelStack(pid, WAIT_GET_KERNEL_STACK_TIMEOUT);
298800b99b8Sopenharmony_ci            msg.append("Result: pid(" + std::to_string(pid) + ") process is dumping.\n");
299800b99b8Sopenharmony_ci        } else if (sdkdumpRet == static_cast<int>(FaultLoggerSdkDumpResp::SDK_DUMP_REJECT)) {
300800b99b8Sopenharmony_ci            msg.append("Result: pid(" + std::to_string(pid) + ") process check permission error.\n");
301800b99b8Sopenharmony_ci        } else if (sdkdumpRet == static_cast<int>(FaultLoggerSdkDumpResp::SDK_DUMP_NOPROC)) {
302800b99b8Sopenharmony_ci            msg.append("Result: pid(" + std::to_string(pid) + ") process has exited.\n");
303800b99b8Sopenharmony_ci            RequestDelPipeFd(pid);
304800b99b8Sopenharmony_ci        } else if (sdkdumpRet == static_cast<int>(FaultLoggerSdkDumpResp::SDK_PROCESS_CRASHED)) {
305800b99b8Sopenharmony_ci            msg.append("Result: pid(" + std::to_string(pid) + ") process has been crashed.\n");
306800b99b8Sopenharmony_ci        }
307800b99b8Sopenharmony_ci        DFXLOGW("%{public}s :: %{public}s :: %{public}s", DFXDUMPCATCHER_TAG.c_str(), __func__, msg.c_str());
308800b99b8Sopenharmony_ci        return ret;
309800b99b8Sopenharmony_ci    }
310800b99b8Sopenharmony_ci
311800b99b8Sopenharmony_ci    int pollRet = DoDumpRemotePid(pid, msg, isJson, timeout);
312800b99b8Sopenharmony_ci    switch (pollRet) {
313800b99b8Sopenharmony_ci        case DUMP_POLL_OK:
314800b99b8Sopenharmony_ci            ret = true;
315800b99b8Sopenharmony_ci            break;
316800b99b8Sopenharmony_ci        case DUMP_POLL_TIMEOUT: {
317800b99b8Sopenharmony_ci            msg.append(halfProcStatus_);
318800b99b8Sopenharmony_ci            msg.append(halfProcWchan_);
319800b99b8Sopenharmony_ci            break;
320800b99b8Sopenharmony_ci        }
321800b99b8Sopenharmony_ci        default:
322800b99b8Sopenharmony_ci            if (g_kernelStackPid != pid) { // maybe not get kernel stack, try again
323800b99b8Sopenharmony_ci                AsyncGetAllTidKernelStack(pid, WAIT_GET_KERNEL_STACK_TIMEOUT);
324800b99b8Sopenharmony_ci            }
325800b99b8Sopenharmony_ci            msg.append(halfProcStatus_);
326800b99b8Sopenharmony_ci            msg.append(halfProcWchan_);
327800b99b8Sopenharmony_ci            break;
328800b99b8Sopenharmony_ci    }
329800b99b8Sopenharmony_ci    DFXLOGW("%{public}s :: %{public}s :: pid(%{public}d) ret: %{public}d", DFXDUMPCATCHER_TAG.c_str(),
330800b99b8Sopenharmony_ci        __func__, pid, ret);
331800b99b8Sopenharmony_ci    return ret;
332800b99b8Sopenharmony_ci}
333800b99b8Sopenharmony_ci
334800b99b8Sopenharmony_ciint DfxDumpCatcher::DoDumpRemotePid(int pid, std::string& msg, bool isJson, int32_t timeout)
335800b99b8Sopenharmony_ci{
336800b99b8Sopenharmony_ci    DFX_TRACE_SCOPED_DLSYM("DoDumpRemotePid");
337800b99b8Sopenharmony_ci    int readBufFd = -1;
338800b99b8Sopenharmony_ci    int readResFd = -1;
339800b99b8Sopenharmony_ci    if (isJson) {
340800b99b8Sopenharmony_ci        readBufFd = RequestPipeFd(pid, FaultLoggerPipeType::PIPE_FD_JSON_READ_BUF);
341800b99b8Sopenharmony_ci        readResFd = RequestPipeFd(pid, FaultLoggerPipeType::PIPE_FD_JSON_READ_RES);
342800b99b8Sopenharmony_ci    } else {
343800b99b8Sopenharmony_ci        readBufFd = RequestPipeFd(pid, FaultLoggerPipeType::PIPE_FD_READ_BUF);
344800b99b8Sopenharmony_ci        readResFd = RequestPipeFd(pid, FaultLoggerPipeType::PIPE_FD_READ_RES);
345800b99b8Sopenharmony_ci    }
346800b99b8Sopenharmony_ci    DFXLOGD("read res fd: %{public}d", readResFd);
347800b99b8Sopenharmony_ci    int ret = DoDumpRemotePoll(readBufFd, readResFd, timeout, msg, isJson);
348800b99b8Sopenharmony_ci    // request close fds in faultloggerd
349800b99b8Sopenharmony_ci    RequestDelPipeFd(pid);
350800b99b8Sopenharmony_ci    if (readBufFd >= 0) {
351800b99b8Sopenharmony_ci        close(readBufFd);
352800b99b8Sopenharmony_ci        readBufFd = -1;
353800b99b8Sopenharmony_ci    }
354800b99b8Sopenharmony_ci    if (readResFd >= 0) {
355800b99b8Sopenharmony_ci        close(readResFd);
356800b99b8Sopenharmony_ci        readResFd = -1;
357800b99b8Sopenharmony_ci    }
358800b99b8Sopenharmony_ci    DFXLOGI("%{public}s :: %{public}s :: pid(%{public}d) poll ret: %{public}d",
359800b99b8Sopenharmony_ci        DFXDUMPCATCHER_TAG.c_str(), __func__, pid, ret);
360800b99b8Sopenharmony_ci    return ret;
361800b99b8Sopenharmony_ci}
362800b99b8Sopenharmony_ci
363800b99b8Sopenharmony_civoid DfxDumpCatcher::CollectKernelStack(pid_t pid, int waitMilliSeconds)
364800b99b8Sopenharmony_ci{
365800b99b8Sopenharmony_ci    ElapsedTime timer;
366800b99b8Sopenharmony_ci    std::string kernelStackInfo;
367800b99b8Sopenharmony_ci    auto finishCollect = [waitMilliSeconds]() {
368800b99b8Sopenharmony_ci        if (waitMilliSeconds > 0) {
369800b99b8Sopenharmony_ci            std::unique_lock<std::mutex> lock(g_kernelStackMutex);
370800b99b8Sopenharmony_ci            g_asyncThreadRunning = false;
371800b99b8Sopenharmony_ci            lock.unlock();
372800b99b8Sopenharmony_ci            g_cv.notify_all();
373800b99b8Sopenharmony_ci        } else {
374800b99b8Sopenharmony_ci            g_asyncThreadRunning = false;
375800b99b8Sopenharmony_ci        }
376800b99b8Sopenharmony_ci    };
377800b99b8Sopenharmony_ci    std::string statusPath = StringPrintf("/proc/%d/status", pid);
378800b99b8Sopenharmony_ci    if (access(statusPath.c_str(), F_OK) != 0) {
379800b99b8Sopenharmony_ci        DFXLOGW("No process(%{public}d) status file exist!", pid);
380800b99b8Sopenharmony_ci        finishCollect();
381800b99b8Sopenharmony_ci        return;
382800b99b8Sopenharmony_ci    }
383800b99b8Sopenharmony_ci
384800b99b8Sopenharmony_ci    std::function<bool(int)> func = [&](int tid) {
385800b99b8Sopenharmony_ci        if (tid <= 0) {
386800b99b8Sopenharmony_ci            return false;
387800b99b8Sopenharmony_ci        }
388800b99b8Sopenharmony_ci        std::string tidKernelStackInfo;
389800b99b8Sopenharmony_ci        if (DfxGetKernelStack(tid, tidKernelStackInfo) == 0) {
390800b99b8Sopenharmony_ci            kernelStackInfo.append(tidKernelStackInfo);
391800b99b8Sopenharmony_ci        }
392800b99b8Sopenharmony_ci        return true;
393800b99b8Sopenharmony_ci    };
394800b99b8Sopenharmony_ci    std::vector<int> tids;
395800b99b8Sopenharmony_ci    bool ret = GetTidsByPidWithFunc(pid, tids, func);
396800b99b8Sopenharmony_ci    if (ret == false) {
397800b99b8Sopenharmony_ci        DFXLOGE("Process(%{public}d) Get Tids fail!", pid);
398800b99b8Sopenharmony_ci        finishCollect();
399800b99b8Sopenharmony_ci        return;
400800b99b8Sopenharmony_ci    }
401800b99b8Sopenharmony_ci    g_kernelStackPid = pid;
402800b99b8Sopenharmony_ci    g_kernelStackInfo = kernelStackInfo;
403800b99b8Sopenharmony_ci    finishCollect();
404800b99b8Sopenharmony_ci    DFXLOGI("finish collect all tid info for pid(%{public}d) time(%{public}" PRId64 ")ms", pid,
405800b99b8Sopenharmony_ci        timer.Elapsed<std::chrono::milliseconds>());
406800b99b8Sopenharmony_ci}
407800b99b8Sopenharmony_ci
408800b99b8Sopenharmony_civoid DfxDumpCatcher::AsyncGetAllTidKernelStack(pid_t pid, int waitMilliSeconds)
409800b99b8Sopenharmony_ci{
410800b99b8Sopenharmony_ci    ReadProcessStatus(halfProcStatus_, pid);
411800b99b8Sopenharmony_ci    ReadProcessWchan(halfProcWchan_, pid, false, true);
412800b99b8Sopenharmony_ci    if (g_asyncThreadRunning) {
413800b99b8Sopenharmony_ci        DFXLOGI("pid(%{public}d) get kernel stack thread is running, not get pid(%{public}d)", g_kernelStackPid, pid);
414800b99b8Sopenharmony_ci        return;
415800b99b8Sopenharmony_ci    }
416800b99b8Sopenharmony_ci    g_asyncThreadRunning = true;
417800b99b8Sopenharmony_ci    g_kernelStackPid = 0;
418800b99b8Sopenharmony_ci    g_kernelStackInfo.clear();
419800b99b8Sopenharmony_ci    auto func = [pid, waitMilliSeconds] {
420800b99b8Sopenharmony_ci        CollectKernelStack(pid, waitMilliSeconds);
421800b99b8Sopenharmony_ci    };
422800b99b8Sopenharmony_ci    if (waitMilliSeconds > 0) {
423800b99b8Sopenharmony_ci        std::unique_lock<std::mutex> lock(g_kernelStackMutex);
424800b99b8Sopenharmony_ci        std::thread kernelStackTask(func);
425800b99b8Sopenharmony_ci        kernelStackTask.detach();
426800b99b8Sopenharmony_ci        g_cv.wait_for(lock, std::chrono::milliseconds(WAIT_GET_KERNEL_STACK_TIMEOUT),
427800b99b8Sopenharmony_ci            [] {return !g_asyncThreadRunning;});
428800b99b8Sopenharmony_ci    } else {
429800b99b8Sopenharmony_ci        std::thread kernelStackTask(func);
430800b99b8Sopenharmony_ci        kernelStackTask.detach();
431800b99b8Sopenharmony_ci    }
432800b99b8Sopenharmony_ci}
433800b99b8Sopenharmony_ci
434800b99b8Sopenharmony_ciint DfxDumpCatcher::DoDumpRemotePoll(int bufFd, int resFd, int timeout, std::string& msg, bool isJson)
435800b99b8Sopenharmony_ci{
436800b99b8Sopenharmony_ci    DFX_TRACE_SCOPED_DLSYM("DoDumpRemotePoll");
437800b99b8Sopenharmony_ci    if (bufFd < 0 || resFd < 0) {
438800b99b8Sopenharmony_ci        if (!isJson) {
439800b99b8Sopenharmony_ci            msg = "Result: bufFd or resFd < 0.\n";
440800b99b8Sopenharmony_ci        }
441800b99b8Sopenharmony_ci        DFXLOGE("invalid bufFd or resFd");
442800b99b8Sopenharmony_ci        return DUMP_POLL_FD;
443800b99b8Sopenharmony_ci    }
444800b99b8Sopenharmony_ci    int ret = DUMP_POLL_INIT;
445800b99b8Sopenharmony_ci    std::string resMsg;
446800b99b8Sopenharmony_ci    bool res = false;
447800b99b8Sopenharmony_ci    std::string bufMsg;
448800b99b8Sopenharmony_ci    struct pollfd readfds[2];
449800b99b8Sopenharmony_ci    (void)memset_s(readfds, sizeof(readfds), 0, sizeof(readfds));
450800b99b8Sopenharmony_ci    readfds[0].fd = bufFd;
451800b99b8Sopenharmony_ci    readfds[0].events = POLLIN;
452800b99b8Sopenharmony_ci    readfds[1].fd = resFd;
453800b99b8Sopenharmony_ci    readfds[1].events = POLLIN;
454800b99b8Sopenharmony_ci    int fdsSize = sizeof(readfds) / sizeof(readfds[0]);
455800b99b8Sopenharmony_ci    bool bPipeConnect = false;
456800b99b8Sopenharmony_ci    int remainTime = DUMPCATCHER_REMOTE_P90_TIMEOUT;
457800b99b8Sopenharmony_ci    bool collectAllTidStack = false;
458800b99b8Sopenharmony_ci    uint64_t startTime = GetAbsTimeMilliSeconds();
459800b99b8Sopenharmony_ci    uint64_t endTime = startTime + static_cast<uint64_t>(timeout);
460800b99b8Sopenharmony_ci    while (true) {
461800b99b8Sopenharmony_ci        int pollRet = poll(readfds, fdsSize, remainTime);
462800b99b8Sopenharmony_ci        if (pollRet < 0 && errno == EINTR) {
463800b99b8Sopenharmony_ci            uint64_t now = GetAbsTimeMilliSeconds();
464800b99b8Sopenharmony_ci            if (now >= endTime) {
465800b99b8Sopenharmony_ci                ret = DUMP_POLL_TIMEOUT;
466800b99b8Sopenharmony_ci                resMsg.append("Result: poll timeout.\n");
467800b99b8Sopenharmony_ci                break;
468800b99b8Sopenharmony_ci            }
469800b99b8Sopenharmony_ci            if (!collectAllTidStack && (remainTime == DUMPCATCHER_REMOTE_P90_TIMEOUT)) {
470800b99b8Sopenharmony_ci                AsyncGetAllTidKernelStack(pid_);
471800b99b8Sopenharmony_ci                collectAllTidStack = true;
472800b99b8Sopenharmony_ci            }
473800b99b8Sopenharmony_ci            remainTime = static_cast<int>(endTime - now);
474800b99b8Sopenharmony_ci            continue;
475800b99b8Sopenharmony_ci        } else if (pollRet < 0) {
476800b99b8Sopenharmony_ci            ret = DUMP_POLL_FAILED;
477800b99b8Sopenharmony_ci            resMsg.append("Result: poll error, errno(" + std::to_string(errno) + ")\n");
478800b99b8Sopenharmony_ci            break;
479800b99b8Sopenharmony_ci        } else if (pollRet == 0) {
480800b99b8Sopenharmony_ci            if (!collectAllTidStack && (remainTime == DUMPCATCHER_REMOTE_P90_TIMEOUT)) {
481800b99b8Sopenharmony_ci                AsyncGetAllTidKernelStack(pid_);
482800b99b8Sopenharmony_ci                remainTime = timeout - DUMPCATCHER_REMOTE_P90_TIMEOUT;
483800b99b8Sopenharmony_ci                collectAllTidStack = true;
484800b99b8Sopenharmony_ci                continue;
485800b99b8Sopenharmony_ci            }
486800b99b8Sopenharmony_ci            ret = DUMP_POLL_TIMEOUT;
487800b99b8Sopenharmony_ci            resMsg.append("Result: poll timeout.\n");
488800b99b8Sopenharmony_ci            break;
489800b99b8Sopenharmony_ci        }
490800b99b8Sopenharmony_ci
491800b99b8Sopenharmony_ci        bool bufRet = true;
492800b99b8Sopenharmony_ci        bool resRet = false;
493800b99b8Sopenharmony_ci        bool eventRet = true;
494800b99b8Sopenharmony_ci        for (int i = 0; i < fdsSize; ++i) {
495800b99b8Sopenharmony_ci            if (!bPipeConnect && ((uint32_t)readfds[i].revents & POLLIN)) {
496800b99b8Sopenharmony_ci                bPipeConnect = true;
497800b99b8Sopenharmony_ci            }
498800b99b8Sopenharmony_ci            if (bPipeConnect &&
499800b99b8Sopenharmony_ci                (((uint32_t)readfds[i].revents & POLLERR) || ((uint32_t)readfds[i].revents & POLLHUP))) {
500800b99b8Sopenharmony_ci                eventRet = false;
501800b99b8Sopenharmony_ci                resMsg.append("Result: poll events error.\n");
502800b99b8Sopenharmony_ci                break;
503800b99b8Sopenharmony_ci            }
504800b99b8Sopenharmony_ci
505800b99b8Sopenharmony_ci            if (((uint32_t)readfds[i].revents & POLLIN) != POLLIN) {
506800b99b8Sopenharmony_ci                continue;
507800b99b8Sopenharmony_ci            }
508800b99b8Sopenharmony_ci
509800b99b8Sopenharmony_ci            if (readfds[i].fd == bufFd) {
510800b99b8Sopenharmony_ci                bufRet = DoReadBuf(bufFd, bufMsg);
511800b99b8Sopenharmony_ci                continue;
512800b99b8Sopenharmony_ci            }
513800b99b8Sopenharmony_ci
514800b99b8Sopenharmony_ci            if (readfds[i].fd == resFd) {
515800b99b8Sopenharmony_ci                resRet = DoReadRes(resFd, res, resMsg);
516800b99b8Sopenharmony_ci            }
517800b99b8Sopenharmony_ci        }
518800b99b8Sopenharmony_ci
519800b99b8Sopenharmony_ci        if ((eventRet == false) || (bufRet == false) || (resRet == true)) {
520800b99b8Sopenharmony_ci            DFXLOGI("%{public}s :: %{public}s :: eventRet(%{public}d) bufRet: %{public}d resRet: %{public}d",
521800b99b8Sopenharmony_ci                DFXDUMPCATCHER_TAG.c_str(), __func__, eventRet, bufRet, resRet);
522800b99b8Sopenharmony_ci            ret = DUMP_POLL_RETURN;
523800b99b8Sopenharmony_ci            break;
524800b99b8Sopenharmony_ci        }
525800b99b8Sopenharmony_ci        uint64_t now = GetAbsTimeMilliSeconds();
526800b99b8Sopenharmony_ci        if (now >= endTime) {
527800b99b8Sopenharmony_ci            ret = DUMP_POLL_TIMEOUT;
528800b99b8Sopenharmony_ci            resMsg.append("Result: poll timeout.\n");
529800b99b8Sopenharmony_ci            break;
530800b99b8Sopenharmony_ci        }
531800b99b8Sopenharmony_ci        remainTime = static_cast<int>(endTime - now);
532800b99b8Sopenharmony_ci    }
533800b99b8Sopenharmony_ci
534800b99b8Sopenharmony_ci    DFXLOGW("%{public}s :: %{public}s :: %{public}s", DFXDUMPCATCHER_TAG.c_str(), __func__, resMsg.c_str());
535800b99b8Sopenharmony_ci    msg = isJson && res ? bufMsg : (resMsg + bufMsg);
536800b99b8Sopenharmony_ci    return res ? DUMP_POLL_OK : ret;
537800b99b8Sopenharmony_ci}
538800b99b8Sopenharmony_ci
539800b99b8Sopenharmony_cibool DfxDumpCatcher::DoReadBuf(int fd, std::string& msg)
540800b99b8Sopenharmony_ci{
541800b99b8Sopenharmony_ci    bool ret = false;
542800b99b8Sopenharmony_ci    char *buffer = new char[MAX_PIPE_SIZE];
543800b99b8Sopenharmony_ci    do {
544800b99b8Sopenharmony_ci        ssize_t nread = OHOS_TEMP_FAILURE_RETRY(read(fd, buffer, MAX_PIPE_SIZE));
545800b99b8Sopenharmony_ci        if (nread <= 0) {
546800b99b8Sopenharmony_ci            DFXLOGW("%{public}s :: %{public}s :: read error", DFXDUMPCATCHER_TAG.c_str(), __func__);
547800b99b8Sopenharmony_ci            break;
548800b99b8Sopenharmony_ci        }
549800b99b8Sopenharmony_ci        DFXLOGD("%{public}s :: %{public}s :: nread: %{public}zu", DFXDUMPCATCHER_TAG.c_str(), __func__, nread);
550800b99b8Sopenharmony_ci        ret = true;
551800b99b8Sopenharmony_ci        msg.append(buffer);
552800b99b8Sopenharmony_ci    } while (false);
553800b99b8Sopenharmony_ci    delete []buffer;
554800b99b8Sopenharmony_ci    return ret;
555800b99b8Sopenharmony_ci}
556800b99b8Sopenharmony_ci
557800b99b8Sopenharmony_cibool DfxDumpCatcher::DoReadRes(int fd, bool &ret, std::string& msg)
558800b99b8Sopenharmony_ci{
559800b99b8Sopenharmony_ci    int32_t res = DumpErrorCode::DUMP_ESUCCESS;
560800b99b8Sopenharmony_ci    ssize_t nread = OHOS_TEMP_FAILURE_RETRY(read(fd, &res, sizeof(res)));
561800b99b8Sopenharmony_ci    if (nread <= 0 || nread != sizeof(res)) {
562800b99b8Sopenharmony_ci        DFXLOGW("%{public}s :: %{public}s :: read error", DFXDUMPCATCHER_TAG.c_str(), __func__);
563800b99b8Sopenharmony_ci        return false;
564800b99b8Sopenharmony_ci    }
565800b99b8Sopenharmony_ci    if (res == DumpErrorCode::DUMP_ESUCCESS) {
566800b99b8Sopenharmony_ci        ret = true;
567800b99b8Sopenharmony_ci    }
568800b99b8Sopenharmony_ci    msg.append("Result: " + DfxDumpRes::ToString(res) + "\n");
569800b99b8Sopenharmony_ci    return true;
570800b99b8Sopenharmony_ci}
571800b99b8Sopenharmony_ci
572800b99b8Sopenharmony_cibool DfxDumpCatcher::DumpCatchMultiPid(const std::vector<int> pidV, std::string& msg)
573800b99b8Sopenharmony_ci{
574800b99b8Sopenharmony_ci    bool ret = false;
575800b99b8Sopenharmony_ci    int pidSize = (int)pidV.size();
576800b99b8Sopenharmony_ci    if (pidSize <= 0) {
577800b99b8Sopenharmony_ci        DFXLOGE("%{public}s :: %{public}s :: param error, pidSize(%{public}d).",
578800b99b8Sopenharmony_ci            DFXDUMPCATCHER_TAG.c_str(), __func__, pidSize);
579800b99b8Sopenharmony_ci        return ret;
580800b99b8Sopenharmony_ci    }
581800b99b8Sopenharmony_ci
582800b99b8Sopenharmony_ci    std::unique_lock<std::mutex> lck(mutex_);
583800b99b8Sopenharmony_ci    int currentPid = getpid();
584800b99b8Sopenharmony_ci    int currentTid = gettid();
585800b99b8Sopenharmony_ci    DFXLOGD("%{public}s :: %{public}s :: cPid(%{public}d), cTid(%{public}d), pidSize(%{public}d).",
586800b99b8Sopenharmony_ci        DFXDUMPCATCHER_TAG.c_str(), \
587800b99b8Sopenharmony_ci        __func__, currentPid, currentTid, pidSize);
588800b99b8Sopenharmony_ci
589800b99b8Sopenharmony_ci    time_t startTime = time(nullptr);
590800b99b8Sopenharmony_ci    if (startTime > 0) {
591800b99b8Sopenharmony_ci        DFXLOGD("%{public}s :: %{public}s :: startTime(%{public}" PRId64 ").",
592800b99b8Sopenharmony_ci            DFXDUMPCATCHER_TAG.c_str(), __func__, startTime);
593800b99b8Sopenharmony_ci    }
594800b99b8Sopenharmony_ci
595800b99b8Sopenharmony_ci    for (int i = 0; i < pidSize; i++) {
596800b99b8Sopenharmony_ci        int pid = pidV[i];
597800b99b8Sopenharmony_ci        std::string pidStr;
598800b99b8Sopenharmony_ci        if (DoDumpRemoteLocked(pid, 0, pidStr)) {
599800b99b8Sopenharmony_ci            msg.append(pidStr + "\n");
600800b99b8Sopenharmony_ci        } else {
601800b99b8Sopenharmony_ci            msg.append("Failed to dump process:" + std::to_string(pid));
602800b99b8Sopenharmony_ci        }
603800b99b8Sopenharmony_ci
604800b99b8Sopenharmony_ci        time_t currentTime = time(nullptr);
605800b99b8Sopenharmony_ci        if (currentTime > 0) {
606800b99b8Sopenharmony_ci            DFXLOGD("%{public}s :: %{public}s :: startTime(%{public}" PRId64 "), currentTime(%{public}" PRId64 ").",
607800b99b8Sopenharmony_ci                DFXDUMPCATCHER_TAG.c_str(), \
608800b99b8Sopenharmony_ci                __func__, startTime, currentTime);
609800b99b8Sopenharmony_ci            if (currentTime > startTime + DUMP_CATCHE_WORK_TIME_S) {
610800b99b8Sopenharmony_ci                break;
611800b99b8Sopenharmony_ci            }
612800b99b8Sopenharmony_ci        }
613800b99b8Sopenharmony_ci    }
614800b99b8Sopenharmony_ci
615800b99b8Sopenharmony_ci    DFXLOGD("%{public}s :: %{public}s :: msg(%{public}s).", DFXDUMPCATCHER_TAG.c_str(), __func__, msg.c_str());
616800b99b8Sopenharmony_ci    if (msg.find("Tid:") != std::string::npos) {
617800b99b8Sopenharmony_ci        ret = true;
618800b99b8Sopenharmony_ci    }
619800b99b8Sopenharmony_ci    return ret;
620800b99b8Sopenharmony_ci}
621800b99b8Sopenharmony_ci} // namespace HiviewDFX
622800b99b8Sopenharmony_ci} // namespace OHOS
623