1800b99b8Sopenharmony_ci/*
2800b99b8Sopenharmony_ci * Copyright (c) 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#ifndef _GNU_SOURCE
16800b99b8Sopenharmony_ci#define _GNU_SOURCE 1
17800b99b8Sopenharmony_ci#endif
18800b99b8Sopenharmony_ci
19800b99b8Sopenharmony_ci#include "dfx_dumprequest.h"
20800b99b8Sopenharmony_ci
21800b99b8Sopenharmony_ci#include <fcntl.h>
22800b99b8Sopenharmony_ci#include <poll.h>
23800b99b8Sopenharmony_ci#include <pthread.h>
24800b99b8Sopenharmony_ci#include <sched.h>
25800b99b8Sopenharmony_ci#include <signal.h>
26800b99b8Sopenharmony_ci#include <sigchain.h>
27800b99b8Sopenharmony_ci#include <stdint.h>
28800b99b8Sopenharmony_ci#include <stdio.h>
29800b99b8Sopenharmony_ci#include <sys/capability.h>
30800b99b8Sopenharmony_ci#include <sys/mman.h>
31800b99b8Sopenharmony_ci#include <sys/prctl.h>
32800b99b8Sopenharmony_ci#include <sys/syscall.h>
33800b99b8Sopenharmony_ci#include <sys/time.h>
34800b99b8Sopenharmony_ci#include <sys/types.h>
35800b99b8Sopenharmony_ci#include <sys/uio.h>
36800b99b8Sopenharmony_ci#include <sys/wait.h>
37800b99b8Sopenharmony_ci#include <time.h>
38800b99b8Sopenharmony_ci#include <unistd.h>
39800b99b8Sopenharmony_ci#include "dfx_define.h"
40800b99b8Sopenharmony_ci#include "dfx_dump_request.h"
41800b99b8Sopenharmony_ci#include "dfx_signalhandler_exception.h"
42800b99b8Sopenharmony_ci#include "errno.h"
43800b99b8Sopenharmony_ci#include "linux/capability.h"
44800b99b8Sopenharmony_ci#include "stdbool.h"
45800b99b8Sopenharmony_ci#include "string.h"
46800b99b8Sopenharmony_ci#ifndef DFX_SIGNAL_LIBC
47800b99b8Sopenharmony_ci#include <securec.h>
48800b99b8Sopenharmony_ci#include "dfx_cutil.h"
49800b99b8Sopenharmony_ci#include "dfx_log.h"
50800b99b8Sopenharmony_ci#else
51800b99b8Sopenharmony_ci#include "musl_cutil.h"
52800b99b8Sopenharmony_ci#include "musl_log.h"
53800b99b8Sopenharmony_ci#endif
54800b99b8Sopenharmony_ci
55800b99b8Sopenharmony_ci#include "info/fatal_message.h"
56800b99b8Sopenharmony_ci
57800b99b8Sopenharmony_ci#ifdef LOG_DOMAIN
58800b99b8Sopenharmony_ci#undef LOG_DOMAIN
59800b99b8Sopenharmony_ci#define LOG_DOMAIN 0xD002D11
60800b99b8Sopenharmony_ci#endif
61800b99b8Sopenharmony_ci
62800b99b8Sopenharmony_ci#ifdef LOG_TAG
63800b99b8Sopenharmony_ci#undef LOG_TAG
64800b99b8Sopenharmony_ci#define LOG_TAG "DfxSignalHandler"
65800b99b8Sopenharmony_ci#endif
66800b99b8Sopenharmony_ci
67800b99b8Sopenharmony_ci#ifndef F_SETPIPE_SZ
68800b99b8Sopenharmony_ci#define F_SETPIPE_SZ 1031
69800b99b8Sopenharmony_ci#endif
70800b99b8Sopenharmony_ci
71800b99b8Sopenharmony_ci#define NUMBER_SIXTYFOUR 64
72800b99b8Sopenharmony_ci#define INHERITABLE_OFFSET 32
73800b99b8Sopenharmony_ci
74800b99b8Sopenharmony_cistatic struct ProcessDumpRequest *g_request = NULL;
75800b99b8Sopenharmony_cistatic void *g_reservedChildStack = NULL;
76800b99b8Sopenharmony_ci
77800b99b8Sopenharmony_cienum PIPE_FD_TYPE {
78800b99b8Sopenharmony_ci    WRITE_TO_DUMP,
79800b99b8Sopenharmony_ci    READ_FROM_DUMP_TO_MAIN,
80800b99b8Sopenharmony_ci    READ_FORM_DUMP_TO_VIRTUAL,
81800b99b8Sopenharmony_ci    PIPE_MAX,
82800b99b8Sopenharmony_ci};
83800b99b8Sopenharmony_ci
84800b99b8Sopenharmony_cistatic int g_pipeFds[PIPE_MAX][2] = {
85800b99b8Sopenharmony_ci    {-1, -1},
86800b99b8Sopenharmony_ci    {-1, -1},
87800b99b8Sopenharmony_ci    {-1, -1}
88800b99b8Sopenharmony_ci};
89800b99b8Sopenharmony_ci
90800b99b8Sopenharmony_cistatic const int SIGNALHANDLER_TIMEOUT = 10000; // 10000 us
91800b99b8Sopenharmony_cistatic const int ALARM_TIME_S = 10;
92800b99b8Sopenharmony_cienum DumpPreparationStage {
93800b99b8Sopenharmony_ci    CREATE_PIPE_FAIL = 1,
94800b99b8Sopenharmony_ci    SET_PIPE_LEN_FAIL,
95800b99b8Sopenharmony_ci    WRITE_PIPE_FAIL,
96800b99b8Sopenharmony_ci    INHERIT_CAP_FAIL,
97800b99b8Sopenharmony_ci    EXEC_FAIL,
98800b99b8Sopenharmony_ci};
99800b99b8Sopenharmony_ci
100800b99b8Sopenharmony_cistatic const char* GetCrashDescription(const int32_t errCode)
101800b99b8Sopenharmony_ci{
102800b99b8Sopenharmony_ci    size_t i;
103800b99b8Sopenharmony_ci
104800b99b8Sopenharmony_ci    for (i = 0; i < sizeof(g_crashExceptionMap) / sizeof(g_crashExceptionMap[0]); i++) {
105800b99b8Sopenharmony_ci        if (errCode == g_crashExceptionMap[i].errCode) {
106800b99b8Sopenharmony_ci            return g_crashExceptionMap[i].str;
107800b99b8Sopenharmony_ci        }
108800b99b8Sopenharmony_ci    }
109800b99b8Sopenharmony_ci    return g_crashExceptionMap[i - 1].str;    /* the end of map is "unknown reason" */
110800b99b8Sopenharmony_ci}
111800b99b8Sopenharmony_ci
112800b99b8Sopenharmony_cistatic void FillCrashExceptionAndReport(const int err)
113800b99b8Sopenharmony_ci{
114800b99b8Sopenharmony_ci    struct CrashDumpException exception;
115800b99b8Sopenharmony_ci    (void)memset_s(&exception, sizeof(struct CrashDumpException), 0, sizeof(struct CrashDumpException));
116800b99b8Sopenharmony_ci    exception.pid = g_request->pid;
117800b99b8Sopenharmony_ci    exception.uid = (int32_t)(g_request->uid);
118800b99b8Sopenharmony_ci    exception.error = err;
119800b99b8Sopenharmony_ci    exception.time = (int64_t)(GetTimeMilliseconds());
120800b99b8Sopenharmony_ci    if (strncpy_s(exception.message, sizeof(exception.message), GetCrashDescription(err),
121800b99b8Sopenharmony_ci        sizeof(exception.message) - 1) != 0) {
122800b99b8Sopenharmony_ci        DFXLOGE("strcpy exception message fail");
123800b99b8Sopenharmony_ci        return;
124800b99b8Sopenharmony_ci    }
125800b99b8Sopenharmony_ci    ReportException(exception);
126800b99b8Sopenharmony_ci}
127800b99b8Sopenharmony_ci
128800b99b8Sopenharmony_cistatic int32_t InheritCapabilities(void)
129800b99b8Sopenharmony_ci{
130800b99b8Sopenharmony_ci    struct __user_cap_header_struct capHeader;
131800b99b8Sopenharmony_ci    (void)memset_s(&capHeader, sizeof(capHeader), 0, sizeof(capHeader));
132800b99b8Sopenharmony_ci
133800b99b8Sopenharmony_ci    capHeader.version = _LINUX_CAPABILITY_VERSION_3;
134800b99b8Sopenharmony_ci    capHeader.pid = 0;
135800b99b8Sopenharmony_ci    struct __user_cap_data_struct capData[2];
136800b99b8Sopenharmony_ci    if (capget(&capHeader, &capData[0]) == -1) {
137800b99b8Sopenharmony_ci        DFXLOGE("Failed to get origin cap data");
138800b99b8Sopenharmony_ci        return -1;
139800b99b8Sopenharmony_ci    }
140800b99b8Sopenharmony_ci
141800b99b8Sopenharmony_ci    capData[0].inheritable = capData[0].permitted;
142800b99b8Sopenharmony_ci    capData[1].inheritable = capData[1].permitted;
143800b99b8Sopenharmony_ci    if (capset(&capHeader, &capData[0]) == -1) {
144800b99b8Sopenharmony_ci        DFXLOGE("Failed to set cap data, errno(%{public}d)", errno);
145800b99b8Sopenharmony_ci        return -1;
146800b99b8Sopenharmony_ci    }
147800b99b8Sopenharmony_ci
148800b99b8Sopenharmony_ci    uint64_t ambCap = capData[0].inheritable;
149800b99b8Sopenharmony_ci    ambCap = ambCap | (((uint64_t)capData[1].inheritable) << INHERITABLE_OFFSET);
150800b99b8Sopenharmony_ci    for (size_t i = 0; i < NUMBER_SIXTYFOUR; i++) {
151800b99b8Sopenharmony_ci        if (ambCap & ((uint64_t)1)) {
152800b99b8Sopenharmony_ci            if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, i, 0, 0) < 0) {
153800b99b8Sopenharmony_ci                DFXLOGE("Failed to change the ambient capability set, errno(%{public}d)", errno);
154800b99b8Sopenharmony_ci            }
155800b99b8Sopenharmony_ci        }
156800b99b8Sopenharmony_ci        ambCap = ambCap >> 1;
157800b99b8Sopenharmony_ci    }
158800b99b8Sopenharmony_ci    return 0;
159800b99b8Sopenharmony_ci}
160800b99b8Sopenharmony_ci
161800b99b8Sopenharmony_cistatic const int SIGCHAIN_DUMP_SIGNAL_LIST[] = {
162800b99b8Sopenharmony_ci    SIGDUMP, SIGLEAK_STACK
163800b99b8Sopenharmony_ci};
164800b99b8Sopenharmony_ci
165800b99b8Sopenharmony_cistatic const int SIGCHAIN_CRASH_SIGNAL_LIST[] = {
166800b99b8Sopenharmony_ci    SIGILL, SIGABRT, SIGBUS, SIGFPE,
167800b99b8Sopenharmony_ci    SIGSEGV, SIGSTKFLT, SIGSYS, SIGTRAP
168800b99b8Sopenharmony_ci};
169800b99b8Sopenharmony_ci
170800b99b8Sopenharmony_cistatic void SetInterestedSignalMasks(int how)
171800b99b8Sopenharmony_ci{
172800b99b8Sopenharmony_ci    sigset_t set;
173800b99b8Sopenharmony_ci    sigemptyset(&set);
174800b99b8Sopenharmony_ci    for (size_t i = 0; i < sizeof(SIGCHAIN_DUMP_SIGNAL_LIST) / sizeof(SIGCHAIN_DUMP_SIGNAL_LIST[0]); i++) {
175800b99b8Sopenharmony_ci        sigaddset(&set, SIGCHAIN_DUMP_SIGNAL_LIST[i]);
176800b99b8Sopenharmony_ci    }
177800b99b8Sopenharmony_ci    for (size_t i = 0; i < sizeof(SIGCHAIN_CRASH_SIGNAL_LIST) / sizeof(SIGCHAIN_CRASH_SIGNAL_LIST[0]); i++) {
178800b99b8Sopenharmony_ci        sigaddset(&set, SIGCHAIN_CRASH_SIGNAL_LIST[i]);
179800b99b8Sopenharmony_ci    }
180800b99b8Sopenharmony_ci    sigprocmask(how, &set, NULL);
181800b99b8Sopenharmony_ci}
182800b99b8Sopenharmony_ci
183800b99b8Sopenharmony_cistatic void CloseFds(void)
184800b99b8Sopenharmony_ci{
185800b99b8Sopenharmony_ci    const int closeFdCount = 1024;
186800b99b8Sopenharmony_ci    for (int i = 0; i < closeFdCount; i++) {
187800b99b8Sopenharmony_ci        syscall(SYS_close, i);
188800b99b8Sopenharmony_ci    }
189800b99b8Sopenharmony_ci}
190800b99b8Sopenharmony_ci
191800b99b8Sopenharmony_cistatic void DFX_SetUpEnvironment(void)
192800b99b8Sopenharmony_ci{
193800b99b8Sopenharmony_ci    // clear stdout and stderr
194800b99b8Sopenharmony_ci    int devNull = OHOS_TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR));
195800b99b8Sopenharmony_ci    if (devNull < 0) {
196800b99b8Sopenharmony_ci        DFXLOGE("Failed to open dev/null.");
197800b99b8Sopenharmony_ci        return;
198800b99b8Sopenharmony_ci    }
199800b99b8Sopenharmony_ci
200800b99b8Sopenharmony_ci    OHOS_TEMP_FAILURE_RETRY(dup2(devNull, STDOUT_FILENO));
201800b99b8Sopenharmony_ci    OHOS_TEMP_FAILURE_RETRY(dup2(devNull, STDERR_FILENO));
202800b99b8Sopenharmony_ci    syscall(SYS_close, devNull);
203800b99b8Sopenharmony_ci    SetInterestedSignalMasks(SIG_BLOCK);
204800b99b8Sopenharmony_ci}
205800b99b8Sopenharmony_ci
206800b99b8Sopenharmony_cistatic void DFX_SetUpSigAlarmAction(void)
207800b99b8Sopenharmony_ci{
208800b99b8Sopenharmony_ci    if (signal(SIGALRM, SIG_DFL) == SIG_ERR) {
209800b99b8Sopenharmony_ci        DFXLOGW("Default signal alarm error!");
210800b99b8Sopenharmony_ci    }
211800b99b8Sopenharmony_ci    sigset_t set;
212800b99b8Sopenharmony_ci    sigemptyset(&set);
213800b99b8Sopenharmony_ci    sigaddset(&set, SIGALRM);
214800b99b8Sopenharmony_ci    sigprocmask(SIG_UNBLOCK, &set, NULL);
215800b99b8Sopenharmony_ci}
216800b99b8Sopenharmony_ci
217800b99b8Sopenharmony_cistatic int DFX_ExecDump(void)
218800b99b8Sopenharmony_ci{
219800b99b8Sopenharmony_ci    DFX_SetUpEnvironment();
220800b99b8Sopenharmony_ci    DFX_SetUpSigAlarmAction();
221800b99b8Sopenharmony_ci    alarm(ALARM_TIME_S);
222800b99b8Sopenharmony_ci    int pipefd[2] = {-1, -1};
223800b99b8Sopenharmony_ci    // create pipe for passing request to processdump
224800b99b8Sopenharmony_ci    if (g_request->dumpMode == SPLIT_MODE) {
225800b99b8Sopenharmony_ci        if (syscall(SYS_pipe2, pipefd, 0) != 0) {
226800b99b8Sopenharmony_ci            DFXLOGE("Failed to create pipe for transfering context, errno(%{public}d)", errno);
227800b99b8Sopenharmony_ci            return CREATE_PIPE_FAIL;
228800b99b8Sopenharmony_ci        }
229800b99b8Sopenharmony_ci    } else {
230800b99b8Sopenharmony_ci        pipefd[0] = g_pipeFds[WRITE_TO_DUMP][0];
231800b99b8Sopenharmony_ci        pipefd[1] = g_pipeFds[WRITE_TO_DUMP][1];
232800b99b8Sopenharmony_ci    }
233800b99b8Sopenharmony_ci
234800b99b8Sopenharmony_ci    ssize_t writeLen = (long)(sizeof(struct ProcessDumpRequest));
235800b99b8Sopenharmony_ci    if (fcntl(pipefd[1], F_SETPIPE_SZ, writeLen) < writeLen) {
236800b99b8Sopenharmony_ci        DFXLOGE("Failed to set pipe buffer size, errno(%{public}d).", errno);
237800b99b8Sopenharmony_ci        return SET_PIPE_LEN_FAIL;
238800b99b8Sopenharmony_ci    }
239800b99b8Sopenharmony_ci
240800b99b8Sopenharmony_ci    struct iovec iovs[1] = {
241800b99b8Sopenharmony_ci        {
242800b99b8Sopenharmony_ci            .iov_base = g_request,
243800b99b8Sopenharmony_ci            .iov_len = sizeof(struct ProcessDumpRequest)
244800b99b8Sopenharmony_ci        },
245800b99b8Sopenharmony_ci    };
246800b99b8Sopenharmony_ci    if (OHOS_TEMP_FAILURE_RETRY(writev(pipefd[1], iovs, 1)) != writeLen) {
247800b99b8Sopenharmony_ci        DFXLOGE("Failed to write pipe, errno(%{public}d)", errno);
248800b99b8Sopenharmony_ci        return WRITE_PIPE_FAIL;
249800b99b8Sopenharmony_ci    }
250800b99b8Sopenharmony_ci    OHOS_TEMP_FAILURE_RETRY(dup2(pipefd[0], STDIN_FILENO));
251800b99b8Sopenharmony_ci    if (pipefd[0] != STDIN_FILENO) {
252800b99b8Sopenharmony_ci        syscall(SYS_close, pipefd[0]);
253800b99b8Sopenharmony_ci    }
254800b99b8Sopenharmony_ci    syscall(SYS_close, pipefd[1]);
255800b99b8Sopenharmony_ci
256800b99b8Sopenharmony_ci    if (InheritCapabilities() != 0) {
257800b99b8Sopenharmony_ci        DFXLOGE("Failed to inherit Capabilities from parent.");
258800b99b8Sopenharmony_ci        FillCrashExceptionAndReport(CRASH_SIGNAL_EINHERITCAP);
259800b99b8Sopenharmony_ci        return INHERIT_CAP_FAIL;
260800b99b8Sopenharmony_ci    }
261800b99b8Sopenharmony_ci    DFXLOGW("execl processdump.");
262800b99b8Sopenharmony_ci#ifdef DFX_LOG_HILOG_BASE
263800b99b8Sopenharmony_ci    execl("/system/bin/processdump", "processdump", "-signalhandler", NULL);
264800b99b8Sopenharmony_ci#else
265800b99b8Sopenharmony_ci    execl("/bin/processdump", "processdump", "-signalhandler", NULL);
266800b99b8Sopenharmony_ci#endif
267800b99b8Sopenharmony_ci    DFXLOGE("Failed to execl processdump, errno(%{public}d)", errno);
268800b99b8Sopenharmony_ci    FillCrashExceptionAndReport(CRASH_SIGNAL_EEXECL);
269800b99b8Sopenharmony_ci    return errno;
270800b99b8Sopenharmony_ci}
271800b99b8Sopenharmony_ci
272800b99b8Sopenharmony_cistatic pid_t ForkBySyscall(void)
273800b99b8Sopenharmony_ci{
274800b99b8Sopenharmony_ci#ifdef SYS_fork
275800b99b8Sopenharmony_ci    return syscall(SYS_fork);
276800b99b8Sopenharmony_ci#else
277800b99b8Sopenharmony_ci    return syscall(SYS_clone, SIGCHLD, 0);
278800b99b8Sopenharmony_ci#endif
279800b99b8Sopenharmony_ci}
280800b99b8Sopenharmony_ci
281800b99b8Sopenharmony_cistatic bool SetDumpState(void)
282800b99b8Sopenharmony_ci{
283800b99b8Sopenharmony_ci    if (prctl(PR_SET_DUMPABLE, 1) != 0) {
284800b99b8Sopenharmony_ci        DFXLOGE("Failed to set dumpable, errno(%{public}d).", errno);
285800b99b8Sopenharmony_ci        return false;
286800b99b8Sopenharmony_ci    }
287800b99b8Sopenharmony_ci
288800b99b8Sopenharmony_ci    if (prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY) != 0) {
289800b99b8Sopenharmony_ci        if (errno != EINVAL) {
290800b99b8Sopenharmony_ci            DFXLOGE("Failed to set ptracer, errno(%{public}d).", errno);
291800b99b8Sopenharmony_ci            return false;
292800b99b8Sopenharmony_ci        }
293800b99b8Sopenharmony_ci    }
294800b99b8Sopenharmony_ci    return true;
295800b99b8Sopenharmony_ci}
296800b99b8Sopenharmony_ci
297800b99b8Sopenharmony_cistatic void RestoreDumpState(int prevState, bool isTracerStatusModified)
298800b99b8Sopenharmony_ci{
299800b99b8Sopenharmony_ci    prctl(PR_SET_DUMPABLE, prevState);
300800b99b8Sopenharmony_ci    if (isTracerStatusModified == true) {
301800b99b8Sopenharmony_ci        prctl(PR_SET_PTRACER, 0);
302800b99b8Sopenharmony_ci    }
303800b99b8Sopenharmony_ci}
304800b99b8Sopenharmony_ci
305800b99b8Sopenharmony_cistatic void SetSelfThreadParam(const char* name, int priority)
306800b99b8Sopenharmony_ci{
307800b99b8Sopenharmony_ci    pthread_setname_np(pthread_self(), name);
308800b99b8Sopenharmony_ci    struct sched_param schedParam;
309800b99b8Sopenharmony_ci    schedParam.sched_priority = priority;
310800b99b8Sopenharmony_ci    pthread_setschedparam(pthread_self(), SCHED_FIFO, &schedParam);
311800b99b8Sopenharmony_ci}
312800b99b8Sopenharmony_ci
313800b99b8Sopenharmony_cistatic bool WaitProcessExit(int childPid, const char* name)
314800b99b8Sopenharmony_ci{
315800b99b8Sopenharmony_ci    int ret = -1;
316800b99b8Sopenharmony_ci    int status = 0;
317800b99b8Sopenharmony_ci    int startTime = (int)time(NULL);
318800b99b8Sopenharmony_ci    bool isSuccess = false;
319800b99b8Sopenharmony_ci    DFXLOGI("(%{public}ld) wait %{public}s(%{public}d) exit.", syscall(SYS_gettid), name, childPid);
320800b99b8Sopenharmony_ci    do {
321800b99b8Sopenharmony_ci        errno = 0;
322800b99b8Sopenharmony_ci        ret = waitpid(childPid, &status, WNOHANG);
323800b99b8Sopenharmony_ci        if (ret < 0) {
324800b99b8Sopenharmony_ci            DFXLOGE("Failed to wait child process terminated, errno(%{public}d)", errno);
325800b99b8Sopenharmony_ci            return isSuccess;
326800b99b8Sopenharmony_ci        }
327800b99b8Sopenharmony_ci
328800b99b8Sopenharmony_ci        if (ret == childPid) {
329800b99b8Sopenharmony_ci            isSuccess = true;
330800b99b8Sopenharmony_ci            break;
331800b99b8Sopenharmony_ci        }
332800b99b8Sopenharmony_ci
333800b99b8Sopenharmony_ci        if ((int)time(NULL) - startTime > PROCESSDUMP_TIMEOUT) {
334800b99b8Sopenharmony_ci            DFXLOGI("(%{public}ld) wait for (%{public}d) timeout", syscall(SYS_gettid), childPid);
335800b99b8Sopenharmony_ci            isSuccess = false;
336800b99b8Sopenharmony_ci            break;
337800b99b8Sopenharmony_ci        }
338800b99b8Sopenharmony_ci        usleep(SIGNALHANDLER_TIMEOUT); // sleep 10ms
339800b99b8Sopenharmony_ci    } while (1);
340800b99b8Sopenharmony_ci
341800b99b8Sopenharmony_ci    DFXLOGI("(%{public}ld) wait for %{public}s(%{public}d) return with ret(%{public}d), status(%{public}d)",
342800b99b8Sopenharmony_ci        syscall(SYS_gettid), name, childPid, ret, status);
343800b99b8Sopenharmony_ci    if (WIFEXITED(status)) {
344800b99b8Sopenharmony_ci        int exitCode = WEXITSTATUS(status);
345800b99b8Sopenharmony_ci        DFXLOGI("wait %{public}s(%{public}d) exit code: %{public}d", name, childPid, exitCode);
346800b99b8Sopenharmony_ci    } else if (WIFSIGNALED(status)) {
347800b99b8Sopenharmony_ci        int sigNum = WTERMSIG(status);
348800b99b8Sopenharmony_ci        DFXLOGI("wait %{public}s(%{public}d) exit with sig: %{public}d", name, childPid, sigNum);
349800b99b8Sopenharmony_ci    }
350800b99b8Sopenharmony_ci    return isSuccess;
351800b99b8Sopenharmony_ci}
352800b99b8Sopenharmony_ci
353800b99b8Sopenharmony_cistatic void Exit(int flag)
354800b99b8Sopenharmony_ci{
355800b99b8Sopenharmony_ci    _exit(flag); // Avoid crashes that occur when directly using the _exit()
356800b99b8Sopenharmony_ci}
357800b99b8Sopenharmony_ci
358800b99b8Sopenharmony_cistatic int ForkAndExecProcessDump(void)
359800b99b8Sopenharmony_ci{
360800b99b8Sopenharmony_ci    int childPid = -1;
361800b99b8Sopenharmony_ci    SetSelfThreadParam("dump_tmp_thread", 0);
362800b99b8Sopenharmony_ci
363800b99b8Sopenharmony_ci    // set privilege for dump ourself
364800b99b8Sopenharmony_ci    int prevDumpableStatus = prctl(PR_GET_DUMPABLE);
365800b99b8Sopenharmony_ci    bool isTracerStatusModified = SetDumpState();
366800b99b8Sopenharmony_ci    if (!isTracerStatusModified) {
367800b99b8Sopenharmony_ci        FillCrashExceptionAndReport(CRASH_SIGNAL_ESETSTATE);
368800b99b8Sopenharmony_ci        goto out;
369800b99b8Sopenharmony_ci    }
370800b99b8Sopenharmony_ci
371800b99b8Sopenharmony_ci    // fork a child process that could ptrace us
372800b99b8Sopenharmony_ci    childPid = ForkBySyscall();
373800b99b8Sopenharmony_ci    if (childPid == 0) {
374800b99b8Sopenharmony_ci        g_request->dumpMode = SPLIT_MODE;
375800b99b8Sopenharmony_ci        DFXLOGI("The exec processdump pid(%{public}ld).", syscall(SYS_getpid));
376800b99b8Sopenharmony_ci        Exit(DFX_ExecDump());
377800b99b8Sopenharmony_ci    } else if (childPid < 0) {
378800b99b8Sopenharmony_ci        DFXLOGE("[%{public}d]: Failed to fork child process, errno(%{public}d).", __LINE__, errno);
379800b99b8Sopenharmony_ci        FillCrashExceptionAndReport(CRASH_SIGNAL_EFORK);
380800b99b8Sopenharmony_ci        goto out;
381800b99b8Sopenharmony_ci    }
382800b99b8Sopenharmony_ci    WaitProcessExit(childPid, "processdump");
383800b99b8Sopenharmony_ciout:
384800b99b8Sopenharmony_ci    RestoreDumpState(prevDumpableStatus, isTracerStatusModified);
385800b99b8Sopenharmony_ci    return 0;
386800b99b8Sopenharmony_ci}
387800b99b8Sopenharmony_ci
388800b99b8Sopenharmony_cistatic int CloneAndDoProcessDump(void* arg)
389800b99b8Sopenharmony_ci{
390800b99b8Sopenharmony_ci    (void)arg;
391800b99b8Sopenharmony_ci    DFXLOGI("The clone thread(%{public}ld).", syscall(SYS_gettid));
392800b99b8Sopenharmony_ci    g_request->recycleTid = syscall(SYS_gettid);
393800b99b8Sopenharmony_ci    return ForkAndExecProcessDump();
394800b99b8Sopenharmony_ci}
395800b99b8Sopenharmony_ci
396800b99b8Sopenharmony_cistatic bool StartProcessdump(void)
397800b99b8Sopenharmony_ci{
398800b99b8Sopenharmony_ci    uint64_t startTime = GetAbsTimeMilliSeconds();
399800b99b8Sopenharmony_ci    pid_t pid = ForkBySyscall();
400800b99b8Sopenharmony_ci    if (pid < 0) {
401800b99b8Sopenharmony_ci        DFXLOGE("Failed to fork dummy processdump(%{public}d)", errno);
402800b99b8Sopenharmony_ci        return false;
403800b99b8Sopenharmony_ci    } else if (pid == 0) {
404800b99b8Sopenharmony_ci        pid_t processDumpPid = ForkBySyscall();
405800b99b8Sopenharmony_ci        if (processDumpPid < 0) {
406800b99b8Sopenharmony_ci            DFXLOGE("Failed to fork processdump(%{public}d)", errno);
407800b99b8Sopenharmony_ci            _exit(0);
408800b99b8Sopenharmony_ci        } else if (processDumpPid > 0) {
409800b99b8Sopenharmony_ci            _exit(0);
410800b99b8Sopenharmony_ci        } else {
411800b99b8Sopenharmony_ci            uint64_t endTime;
412800b99b8Sopenharmony_ci            int tid;
413800b99b8Sopenharmony_ci            ParseSiValue(&g_request->siginfo, &endTime, &tid);
414800b99b8Sopenharmony_ci            uint64_t curTime = GetAbsTimeMilliSeconds();
415800b99b8Sopenharmony_ci            DFXLOGW("start processdump, fork spend time %{public}" PRIu64 "ms", curTime - startTime);
416800b99b8Sopenharmony_ci            if (endTime != 0) {
417800b99b8Sopenharmony_ci                DFXLOGW("dump remain %{public}" PRId64 "ms", endTime - curTime);
418800b99b8Sopenharmony_ci            }
419800b99b8Sopenharmony_ci            if (endTime == 0 || endTime > curTime) {
420800b99b8Sopenharmony_ci                DFX_ExecDump();
421800b99b8Sopenharmony_ci            } else {
422800b99b8Sopenharmony_ci                DFXLOGW("current has spend all time, not execl processdump");
423800b99b8Sopenharmony_ci            }
424800b99b8Sopenharmony_ci            _exit(0);
425800b99b8Sopenharmony_ci        }
426800b99b8Sopenharmony_ci    }
427800b99b8Sopenharmony_ci
428800b99b8Sopenharmony_ci    if (waitpid(pid, NULL, 0) <= 0) {
429800b99b8Sopenharmony_ci        DFXLOGE("failed to wait dummy processdump(%{public}d)", errno);
430800b99b8Sopenharmony_ci    }
431800b99b8Sopenharmony_ci    return true;
432800b99b8Sopenharmony_ci}
433800b99b8Sopenharmony_ci
434800b99b8Sopenharmony_cistatic bool StartVMProcessUnwind(void)
435800b99b8Sopenharmony_ci{
436800b99b8Sopenharmony_ci    uint32_t startTime = GetAbsTimeMilliSeconds();
437800b99b8Sopenharmony_ci    pid_t pid = ForkBySyscall();
438800b99b8Sopenharmony_ci    if (pid < 0) {
439800b99b8Sopenharmony_ci        DFXLOGE("Failed to fork vm process(%{public}d)", errno);
440800b99b8Sopenharmony_ci        return false;
441800b99b8Sopenharmony_ci    } else if (pid == 0) {
442800b99b8Sopenharmony_ci        pid_t vmPid = ForkBySyscall();
443800b99b8Sopenharmony_ci        if (vmPid == 0) {
444800b99b8Sopenharmony_ci            DFXLOGW("start vm process, fork spend time %{public}" PRIu64 "ms", GetAbsTimeMilliSeconds() - startTime);
445800b99b8Sopenharmony_ci            syscall(SYS_close, g_pipeFds[WRITE_TO_DUMP][0]);
446800b99b8Sopenharmony_ci            pid_t pids[PID_MAX] = {0};
447800b99b8Sopenharmony_ci            pids[REAL_PROCESS_PID] = GetRealPid();
448800b99b8Sopenharmony_ci            pids[VIRTUAL_PROCESS_PID] = syscall(SYS_getpid);
449800b99b8Sopenharmony_ci            OHOS_TEMP_FAILURE_RETRY(write(g_pipeFds[WRITE_TO_DUMP][1], pids, sizeof(pids)));
450800b99b8Sopenharmony_ci            syscall(SYS_close, g_pipeFds[WRITE_TO_DUMP][1]);
451800b99b8Sopenharmony_ci
452800b99b8Sopenharmony_ci            uint32_t finishUnwind = OPE_FAIL;
453800b99b8Sopenharmony_ci            syscall(SYS_close, g_pipeFds[READ_FORM_DUMP_TO_VIRTUAL][1]);
454800b99b8Sopenharmony_ci            OHOS_TEMP_FAILURE_RETRY(read(g_pipeFds[READ_FORM_DUMP_TO_VIRTUAL][0], &finishUnwind, sizeof(finishUnwind)));
455800b99b8Sopenharmony_ci            syscall(SYS_close, g_pipeFds[READ_FORM_DUMP_TO_VIRTUAL][0]);
456800b99b8Sopenharmony_ci            DFXLOGI("processdump unwind finish, exit vm pid = %{public}d", pids[VIRTUAL_PROCESS_PID]);
457800b99b8Sopenharmony_ci            _exit(0);
458800b99b8Sopenharmony_ci        } else {
459800b99b8Sopenharmony_ci            DFXLOGI("exit dummy vm process");
460800b99b8Sopenharmony_ci            _exit(0);
461800b99b8Sopenharmony_ci        }
462800b99b8Sopenharmony_ci    }
463800b99b8Sopenharmony_ci
464800b99b8Sopenharmony_ci    if (waitpid(pid, NULL, 0) <= 0) {
465800b99b8Sopenharmony_ci        DFXLOGE("failed to wait dummy vm process(%{public}d)", errno);
466800b99b8Sopenharmony_ci    }
467800b99b8Sopenharmony_ci    return true;
468800b99b8Sopenharmony_ci}
469800b99b8Sopenharmony_ci
470800b99b8Sopenharmony_cistatic void CleanFd(int *pipeFd)
471800b99b8Sopenharmony_ci{
472800b99b8Sopenharmony_ci    if (*pipeFd != -1) {
473800b99b8Sopenharmony_ci        syscall(SYS_close, *pipeFd);
474800b99b8Sopenharmony_ci        *pipeFd = -1;
475800b99b8Sopenharmony_ci    }
476800b99b8Sopenharmony_ci}
477800b99b8Sopenharmony_ci
478800b99b8Sopenharmony_cistatic void CleanPipe(void)
479800b99b8Sopenharmony_ci{
480800b99b8Sopenharmony_ci    for (size_t i = 0; i < PIPE_MAX; i++) {
481800b99b8Sopenharmony_ci        CleanFd(&g_pipeFds[i][0]);
482800b99b8Sopenharmony_ci        CleanFd(&g_pipeFds[i][1]);
483800b99b8Sopenharmony_ci    }
484800b99b8Sopenharmony_ci}
485800b99b8Sopenharmony_ci
486800b99b8Sopenharmony_cistatic bool InitPipe(void)
487800b99b8Sopenharmony_ci{
488800b99b8Sopenharmony_ci    for (int i = 0; i < PIPE_MAX; i++) {
489800b99b8Sopenharmony_ci        if (syscall(SYS_pipe2, g_pipeFds[i], 0) == -1) {
490800b99b8Sopenharmony_ci            DFXLOGE("create pipe fail, errno(%{public}d)", errno);
491800b99b8Sopenharmony_ci            FillCrashExceptionAndReport(CRASH_SIGNAL_ECREATEPIPE);
492800b99b8Sopenharmony_ci            CleanPipe();
493800b99b8Sopenharmony_ci            return false;
494800b99b8Sopenharmony_ci        }
495800b99b8Sopenharmony_ci    }
496800b99b8Sopenharmony_ci
497800b99b8Sopenharmony_ci    g_request->pmPipeFd[0] = g_pipeFds[READ_FROM_DUMP_TO_MAIN][0];
498800b99b8Sopenharmony_ci    g_request->pmPipeFd[1] = g_pipeFds[READ_FROM_DUMP_TO_MAIN][1];
499800b99b8Sopenharmony_ci    g_request->vmPipeFd[0] = g_pipeFds[READ_FORM_DUMP_TO_VIRTUAL][0];
500800b99b8Sopenharmony_ci    g_request->vmPipeFd[1] = g_pipeFds[READ_FORM_DUMP_TO_VIRTUAL][1];
501800b99b8Sopenharmony_ci    return true;
502800b99b8Sopenharmony_ci}
503800b99b8Sopenharmony_ci
504800b99b8Sopenharmony_cistatic bool ReadPipeTimeout(int fd, uint64_t timeout, uint32_t* value)
505800b99b8Sopenharmony_ci{
506800b99b8Sopenharmony_ci    if (fd < 0 || value == NULL) {
507800b99b8Sopenharmony_ci        return false;
508800b99b8Sopenharmony_ci    }
509800b99b8Sopenharmony_ci    struct pollfd pfds[1];
510800b99b8Sopenharmony_ci    pfds[0].fd = fd;
511800b99b8Sopenharmony_ci    pfds[0].events = POLLIN;
512800b99b8Sopenharmony_ci
513800b99b8Sopenharmony_ci    uint64_t startTime = GetTimeMilliseconds();
514800b99b8Sopenharmony_ci    uint64_t endTime = startTime + timeout;
515800b99b8Sopenharmony_ci    int pollRet = -1;
516800b99b8Sopenharmony_ci    do {
517800b99b8Sopenharmony_ci        pollRet = poll(pfds, 1, timeout);
518800b99b8Sopenharmony_ci        if ((pollRet > 0) && (pfds[0].revents && POLLIN)) {
519800b99b8Sopenharmony_ci            if (OHOS_TEMP_FAILURE_RETRY(read(fd, value, sizeof(uint32_t))) ==
520800b99b8Sopenharmony_ci                (long int)(sizeof(uint32_t))) {
521800b99b8Sopenharmony_ci                return true;
522800b99b8Sopenharmony_ci            }
523800b99b8Sopenharmony_ci        }
524800b99b8Sopenharmony_ci
525800b99b8Sopenharmony_ci        uint64_t now = GetTimeMilliseconds();
526800b99b8Sopenharmony_ci        if (now >= endTime || now < startTime) {
527800b99b8Sopenharmony_ci            break;
528800b99b8Sopenharmony_ci        } else {
529800b99b8Sopenharmony_ci            timeout = endTime - now;
530800b99b8Sopenharmony_ci        }
531800b99b8Sopenharmony_ci    } while (pollRet < 0 && errno == EINTR);
532800b99b8Sopenharmony_ci    FillCrashExceptionAndReport(CRASH_SIGNAL_EREADPIPE);
533800b99b8Sopenharmony_ci    DFXLOGE("read pipe failed , errno(%{public}d)", errno);
534800b99b8Sopenharmony_ci    return false;
535800b99b8Sopenharmony_ci}
536800b99b8Sopenharmony_ci
537800b99b8Sopenharmony_cistatic bool ReadProcessDumpGetRegsMsg(void)
538800b99b8Sopenharmony_ci{
539800b99b8Sopenharmony_ci    CleanFd(&g_pipeFds[READ_FROM_DUMP_TO_MAIN][1]);
540800b99b8Sopenharmony_ci
541800b99b8Sopenharmony_ci    DFXLOGI("start wait processdump read registers");
542800b99b8Sopenharmony_ci    const uint64_t readRegsTimeout = 5000; // 5s
543800b99b8Sopenharmony_ci    uint32_t isFinishGetRegs = OPE_FAIL;
544800b99b8Sopenharmony_ci    if (ReadPipeTimeout(g_pipeFds[READ_FROM_DUMP_TO_MAIN][0], readRegsTimeout, &isFinishGetRegs)) {
545800b99b8Sopenharmony_ci        if (isFinishGetRegs == OPE_SUCCESS) {
546800b99b8Sopenharmony_ci            DFXLOGI("processdump have get all registers .");
547800b99b8Sopenharmony_ci            return true;
548800b99b8Sopenharmony_ci        }
549800b99b8Sopenharmony_ci    }
550800b99b8Sopenharmony_ci
551800b99b8Sopenharmony_ci    return false;
552800b99b8Sopenharmony_ci}
553800b99b8Sopenharmony_ci
554800b99b8Sopenharmony_cistatic void ReadUnwindFinishMsg(int sig)
555800b99b8Sopenharmony_ci{
556800b99b8Sopenharmony_ci    if (sig == SIGDUMP) {
557800b99b8Sopenharmony_ci        return;
558800b99b8Sopenharmony_ci    }
559800b99b8Sopenharmony_ci
560800b99b8Sopenharmony_ci    DFXLOGI("start wait processdump unwind");
561800b99b8Sopenharmony_ci    const uint64_t unwindTimeout = 10000; // 10s
562800b99b8Sopenharmony_ci    uint32_t isExitAfterUnwind = OPE_CONTINUE;
563800b99b8Sopenharmony_ci    if (ReadPipeTimeout(g_pipeFds[READ_FROM_DUMP_TO_MAIN][0], unwindTimeout, &isExitAfterUnwind)) {
564800b99b8Sopenharmony_ci        DFXLOGI("processdump unwind finish");
565800b99b8Sopenharmony_ci    } else {
566800b99b8Sopenharmony_ci        DFXLOGE("wait processdump unwind finish timeout");
567800b99b8Sopenharmony_ci    }
568800b99b8Sopenharmony_ci}
569800b99b8Sopenharmony_ci
570800b99b8Sopenharmony_cistatic int ProcessDump(int sig)
571800b99b8Sopenharmony_ci{
572800b99b8Sopenharmony_ci    int prevDumpableStatus = prctl(PR_GET_DUMPABLE);
573800b99b8Sopenharmony_ci    bool isTracerStatusModified = SetDumpState();
574800b99b8Sopenharmony_ci
575800b99b8Sopenharmony_ci    if (!InitPipe()) {
576800b99b8Sopenharmony_ci        return -1;
577800b99b8Sopenharmony_ci    }
578800b99b8Sopenharmony_ci    g_request->dumpMode = FUSION_MODE;
579800b99b8Sopenharmony_ci
580800b99b8Sopenharmony_ci    do {
581800b99b8Sopenharmony_ci        uint64_t endTime;
582800b99b8Sopenharmony_ci        int tid;
583800b99b8Sopenharmony_ci        ParseSiValue(&g_request->siginfo, &endTime, &tid);
584800b99b8Sopenharmony_ci        if (endTime != 0 && endTime <= GetAbsTimeMilliSeconds()) {
585800b99b8Sopenharmony_ci            DFXLOGW("enter processdump has coat all time, just exit");
586800b99b8Sopenharmony_ci            break;
587800b99b8Sopenharmony_ci        }
588800b99b8Sopenharmony_ci        if (!StartProcessdump()) {
589800b99b8Sopenharmony_ci            DFXLOGE("start processdump fail");
590800b99b8Sopenharmony_ci            break;
591800b99b8Sopenharmony_ci        }
592800b99b8Sopenharmony_ci
593800b99b8Sopenharmony_ci        if (!ReadProcessDumpGetRegsMsg()) {
594800b99b8Sopenharmony_ci            break;
595800b99b8Sopenharmony_ci        }
596800b99b8Sopenharmony_ci
597800b99b8Sopenharmony_ci        if (!StartVMProcessUnwind()) {
598800b99b8Sopenharmony_ci            DFXLOGE("start vm process unwind fail");
599800b99b8Sopenharmony_ci            break;
600800b99b8Sopenharmony_ci        }
601800b99b8Sopenharmony_ci        ReadUnwindFinishMsg(sig);
602800b99b8Sopenharmony_ci    } while (false);
603800b99b8Sopenharmony_ci
604800b99b8Sopenharmony_ci    CleanPipe();
605800b99b8Sopenharmony_ci    RestoreDumpState(prevDumpableStatus, isTracerStatusModified);
606800b99b8Sopenharmony_ci    return 0;
607800b99b8Sopenharmony_ci}
608800b99b8Sopenharmony_ci
609800b99b8Sopenharmony_cistatic void ForkAndDoProcessDump(int sig)
610800b99b8Sopenharmony_ci{
611800b99b8Sopenharmony_ci    int prevDumpableStatus = prctl(PR_GET_DUMPABLE);
612800b99b8Sopenharmony_ci    bool isTracerStatusModified = SetDumpState();
613800b99b8Sopenharmony_ci    int childPid = ForkBySyscall();
614800b99b8Sopenharmony_ci    if (childPid == 0) {
615800b99b8Sopenharmony_ci        CloseFds();
616800b99b8Sopenharmony_ci        g_request->vmNsPid = syscall(SYS_getpid);
617800b99b8Sopenharmony_ci        g_request->vmPid = GetRealPid();
618800b99b8Sopenharmony_ci        DFXLOGI("The vm pid(%{public}d:%{public}d).", g_request->vmPid, g_request->vmNsPid);
619800b99b8Sopenharmony_ci        DFX_SetUpSigAlarmAction();
620800b99b8Sopenharmony_ci        alarm(ALARM_TIME_S);
621800b99b8Sopenharmony_ci        _exit(ForkAndExecProcessDump());
622800b99b8Sopenharmony_ci    } else if (childPid < 0) {
623800b99b8Sopenharmony_ci        DFXLOGE("[%{public}d]: Failed to fork child process, errno(%{public}d).", __LINE__, errno);
624800b99b8Sopenharmony_ci        RestoreDumpState(prevDumpableStatus, isTracerStatusModified);
625800b99b8Sopenharmony_ci        ForkAndExecProcessDump();
626800b99b8Sopenharmony_ci        return;
627800b99b8Sopenharmony_ci    }
628800b99b8Sopenharmony_ci
629800b99b8Sopenharmony_ci    DFXLOGI("Start wait for VmProcess(%{public}d) exit.", childPid);
630800b99b8Sopenharmony_ci    errno = 0;
631800b99b8Sopenharmony_ci    if (!WaitProcessExit(childPid, "VmProcess") &&
632800b99b8Sopenharmony_ci        sig != SIGDUMP &&
633800b99b8Sopenharmony_ci        sig != SIGLEAK_STACK) {
634800b99b8Sopenharmony_ci        DFXLOGI("Wait VmProcess(%{public}d) exit timeout in handling critical signal.", childPid);
635800b99b8Sopenharmony_ci        FillCrashExceptionAndReport(CRASH_SIGNAL_EWAITEXIT);
636800b99b8Sopenharmony_ci        // do not left vm process
637800b99b8Sopenharmony_ci        kill(childPid, SIGKILL);
638800b99b8Sopenharmony_ci    }
639800b99b8Sopenharmony_ci
640800b99b8Sopenharmony_ci    RestoreDumpState(prevDumpableStatus, isTracerStatusModified);
641800b99b8Sopenharmony_ci}
642800b99b8Sopenharmony_ci
643800b99b8Sopenharmony_ciint DfxDumpRequest(int sig, struct ProcessDumpRequest *request, void *reservedChildStack)
644800b99b8Sopenharmony_ci{
645800b99b8Sopenharmony_ci    int ret = 0;
646800b99b8Sopenharmony_ci    if (request == NULL || reservedChildStack == NULL) {
647800b99b8Sopenharmony_ci        DFXLOGE("Failed to DumpRequest because of error parameters!");
648800b99b8Sopenharmony_ci        return ret;
649800b99b8Sopenharmony_ci    }
650800b99b8Sopenharmony_ci    g_request = request;
651800b99b8Sopenharmony_ci    g_reservedChildStack = reservedChildStack;
652800b99b8Sopenharmony_ci    if (ProcessDump(sig) == 0) {
653800b99b8Sopenharmony_ci        ret = sig == SIGDUMP || sig == SIGLEAK_STACK;
654800b99b8Sopenharmony_ci        return ret;
655800b99b8Sopenharmony_ci    }
656800b99b8Sopenharmony_ci
657800b99b8Sopenharmony_ci    if (sig != SIGDUMP) {
658800b99b8Sopenharmony_ci        ret = sig == SIGLEAK_STACK ? true : false;
659800b99b8Sopenharmony_ci        ForkAndDoProcessDump(sig);
660800b99b8Sopenharmony_ci    } else {
661800b99b8Sopenharmony_ci        ret = true;
662800b99b8Sopenharmony_ci        int recycleTid = clone(CloneAndDoProcessDump, reservedChildStack,\
663800b99b8Sopenharmony_ci            CLONE_THREAD | CLONE_SIGHAND | CLONE_VM, NULL);
664800b99b8Sopenharmony_ci        if (recycleTid == -1) {
665800b99b8Sopenharmony_ci            DFXLOGE("Failed to clone thread for recycle dump process, errno(%{public}d)", errno);
666800b99b8Sopenharmony_ci        }
667800b99b8Sopenharmony_ci    }
668800b99b8Sopenharmony_ci    return ret;
669800b99b8Sopenharmony_ci}
670