1800b99b8Sopenharmony_ci/*
2800b99b8Sopenharmony_ci * Copyright (c) 2021-2023 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_crasher.h"
17800b99b8Sopenharmony_ci
18800b99b8Sopenharmony_ci#include <cerrno>
19800b99b8Sopenharmony_ci#include <cinttypes>
20800b99b8Sopenharmony_ci#include <csignal>
21800b99b8Sopenharmony_ci#include <cstdio>
22800b99b8Sopenharmony_ci#include <cstdlib>
23800b99b8Sopenharmony_ci#include <cstring>
24800b99b8Sopenharmony_ci#include <fstream>
25800b99b8Sopenharmony_ci#include <hilog/log.h>
26800b99b8Sopenharmony_ci#include <iostream>
27800b99b8Sopenharmony_ci#include <sstream>
28800b99b8Sopenharmony_ci#include <pthread.h>
29800b99b8Sopenharmony_ci#include <sys/mman.h>
30800b99b8Sopenharmony_ci#include <sys/prctl.h>
31800b99b8Sopenharmony_ci#include <sys/resource.h>
32800b99b8Sopenharmony_ci#include <thread>
33800b99b8Sopenharmony_ci#include <unistd.h>
34800b99b8Sopenharmony_ci#include <vector>
35800b99b8Sopenharmony_ci
36800b99b8Sopenharmony_ci#include "async_stack.h"
37800b99b8Sopenharmony_ci#include "dfx_define.h"
38800b99b8Sopenharmony_ci#ifndef is_ohos_lite
39800b99b8Sopenharmony_ci#include "ffrt_inner.h"
40800b99b8Sopenharmony_ci#include "uv.h"
41800b99b8Sopenharmony_ci#endif // !is_ohos_lite
42800b99b8Sopenharmony_ci
43800b99b8Sopenharmony_ci#include "info/fatal_message.h"
44800b99b8Sopenharmony_ci#include "securec.h"
45800b99b8Sopenharmony_ci
46800b99b8Sopenharmony_ci#ifdef HAS_HITRACE
47800b99b8Sopenharmony_ci#include <hitrace/hitracechain.h>
48800b99b8Sopenharmony_ci#endif
49800b99b8Sopenharmony_ci
50800b99b8Sopenharmony_ci#ifdef HAS_CRASH_EXAMPLES
51800b99b8Sopenharmony_ci#include "faults/nullpointer_dereference.h"
52800b99b8Sopenharmony_ci#include "faults/multi_thread_container_access.h"
53800b99b8Sopenharmony_ci#include "faults/ipc_issues.h"
54800b99b8Sopenharmony_ci#endif
55800b99b8Sopenharmony_ci
56800b99b8Sopenharmony_ci#ifdef LOG_DOMAIN
57800b99b8Sopenharmony_ci#undef LOG_DOMAIN
58800b99b8Sopenharmony_ci#define LOG_DOMAIN 0xD002D11
59800b99b8Sopenharmony_ci#endif
60800b99b8Sopenharmony_ci
61800b99b8Sopenharmony_ci#ifdef LOG_TAG
62800b99b8Sopenharmony_ci#undef LOG_TAG
63800b99b8Sopenharmony_ci#define LOG_TAG "Unwind"
64800b99b8Sopenharmony_ci#endif
65800b99b8Sopenharmony_ci
66800b99b8Sopenharmony_cistatic const int ARG1024 = 1024;
67800b99b8Sopenharmony_cistatic const int ARG128 = 128;
68800b99b8Sopenharmony_cistatic const int CMD_SZ = 32;
69800b99b8Sopenharmony_cistatic const int CMD_DESC_SZ = 128;
70800b99b8Sopenharmony_ci
71800b99b8Sopenharmony_cistatic const int NUMBER_TWO = 2;
72800b99b8Sopenharmony_cistatic const int NUMBER_ONE = 1;
73800b99b8Sopenharmony_ci
74800b99b8Sopenharmony_ciusing namespace OHOS::HiviewDFX;
75800b99b8Sopenharmony_ciusing CommandFunc = int(*)();
76800b99b8Sopenharmony_ciusing CommandFuncParam = int(*)(const std::string &);
77800b99b8Sopenharmony_cistruct CrasherCommandLine {
78800b99b8Sopenharmony_ci    char cmdline[CMD_SZ];
79800b99b8Sopenharmony_ci    char description[CMD_DESC_SZ];
80800b99b8Sopenharmony_ci    CommandFunc func;
81800b99b8Sopenharmony_ci};
82800b99b8Sopenharmony_ci
83800b99b8Sopenharmony_cistruct CrasherCommandLineParam {
84800b99b8Sopenharmony_ci    char cmdline[CMD_SZ];
85800b99b8Sopenharmony_ci    char description[CMD_DESC_SZ];
86800b99b8Sopenharmony_ci    CommandFuncParam func;
87800b99b8Sopenharmony_ci};
88800b99b8Sopenharmony_ci
89800b99b8Sopenharmony_ciconstexpr static CrasherCommandLine CMDLINE_TABLE[] = {
90800b99b8Sopenharmony_ci    {"SIGFPE", "raise a SIGFPE", &DfxCrasher::RaiseFloatingPointException},
91800b99b8Sopenharmony_ci    {"SIGILL", "raise a SIGILL", &DfxCrasher::RaiseIllegalInstructionException},
92800b99b8Sopenharmony_ci    {"SIGSEGV", "raise a SIGSEGV", &DfxCrasher::RaiseSegmentFaultException},
93800b99b8Sopenharmony_ci    {"SIGTRAP", "raise a SIGTRAP", &DfxCrasher::RaiseTrapException},
94800b99b8Sopenharmony_ci    {"SIGABRT", "raise a SIGABRT", &DfxCrasher::RaiseAbort},
95800b99b8Sopenharmony_ci    {"SIGBUS", "raise a SIGBUS", &DfxCrasher::RaiseBusError},
96800b99b8Sopenharmony_ci
97800b99b8Sopenharmony_ci    {"triSIGILL", "trigger a SIGILL", &DfxCrasher::IllegalInstructionException},
98800b99b8Sopenharmony_ci    {"triSIGSEGV", "trigger a SIGSEGV", &DfxCrasher::SegmentFaultException},
99800b99b8Sopenharmony_ci    {"triSIGTRAP", "trigger a SIGTRAP", &DfxCrasher::TriggerTrapException},
100800b99b8Sopenharmony_ci    {"triSIGABRT", "trigger a SIGABRT", &DfxCrasher::Abort},
101800b99b8Sopenharmony_ci
102800b99b8Sopenharmony_ci    {"Loop", "trigger a ForeverLoop", &DfxCrasher::Loop},
103800b99b8Sopenharmony_ci    {"MaxStack", "trigger SIGSEGV after 64 function call", &DfxCrasher::MaxStackDepth},
104800b99b8Sopenharmony_ci    {"MaxMethod", "trigger SIGSEGV after call a function with longer name",
105800b99b8Sopenharmony_ci        &DfxCrasher::MaxMethodNameTest12345678901234567890123456789012345678901234567890ABC},
106800b99b8Sopenharmony_ci
107800b99b8Sopenharmony_ci    {"STACKOF", "trigger a stack overflow", &DfxCrasher::StackOverflow},
108800b99b8Sopenharmony_ci    {"OOM", "trigger out of memory", &DfxCrasher::Oom},
109800b99b8Sopenharmony_ci    {"PCZero", "trigger a crash with pc equal zero", &DfxCrasher::ProgramCounterZero},
110800b99b8Sopenharmony_ci    {"MTCrash", "trigger a multi-thread crash", &DfxCrasher::MultiThreadCrash},
111800b99b8Sopenharmony_ci    {"StackOver64", "trigger SIGSEGV after 70 function call", &DfxCrasher::StackOver64},
112800b99b8Sopenharmony_ci    {"StackTop", "trigger SIGSEGV to make sure stack top", &DfxCrasher::StackTop},
113800b99b8Sopenharmony_ci    {"DumpCrash", "trigger a SIGDUMP", &DfxCrasher::DoDumpCrash},
114800b99b8Sopenharmony_ci    {"CrashInLambda", "trigger a crash in lambda", &DfxCrasher::CrashInLambda},
115800b99b8Sopenharmony_ci    {"ExitHook", "trigger a process exit using exit(0)", &DfxCrasher::TestExitHook},
116800b99b8Sopenharmony_ci    {"SigHook", "register sigsegv signal handler", &DfxCrasher::TestSigHook},
117800b99b8Sopenharmony_ci    {"StackCorruption", "reset values stored on stack", &DfxCrasher::StackCorruption},
118800b99b8Sopenharmony_ci    {"StackCorruption2", "reset values stored in the middle of the stack", &DfxCrasher::StackCorruption2},
119800b99b8Sopenharmony_ci
120800b99b8Sopenharmony_ci#ifdef HAS_CRASH_EXAMPLES
121800b99b8Sopenharmony_ci    {"NullPointerDeref0", "nullpointer fault testcase 0", &TestNullPointerDereferenceCrash0},
122800b99b8Sopenharmony_ci    {"NullPointerDeref1", "nullpointer fault testcase 1", &TestNullPointerDereferenceCrash1},
123800b99b8Sopenharmony_ci    {"NullPointerDeref2", "nullpointer fault testcase 2", &TestNullPointerDereferenceCrash2},
124800b99b8Sopenharmony_ci    {"NullPointerDeref3", "nullpointer fault testcase 3", &TestNullPointerDereferenceCrash3},
125800b99b8Sopenharmony_ci
126800b99b8Sopenharmony_ci    {"MultiThreadList", "manipulate list without lock in multithread case", &MultiThreadListAccess},
127800b99b8Sopenharmony_ci    {"MultiThreadVector", "manipulate vector without lock in multithread case", &MultiThreadVectorAccess},
128800b99b8Sopenharmony_ci    {"MultiThreadMap", "manipulate map without lock in multithread case", &MultiThreadMapAccess},
129800b99b8Sopenharmony_ci
130800b99b8Sopenharmony_ci    {"SptrMismatch", "mix use sptr and raw pointer", &IPCIssues::SptrMismatch},
131800b99b8Sopenharmony_ci    {"SptrAndSharedPtrMixUsage", "miss match parcel marshalling and unmarshalling",
132800b99b8Sopenharmony_ci        &IPCIssues::SptrAndSharedPtrMixUsage},
133800b99b8Sopenharmony_ci    {"ParcelReadWriteMismatch", "miss match parcel marshalling and unmarshalling",
134800b99b8Sopenharmony_ci        &IPCIssues::ParcelReadWriteMismatch},
135800b99b8Sopenharmony_ci#endif
136800b99b8Sopenharmony_ci    {"FatalMessage", "PrintFatalMessageInLibc",
137800b99b8Sopenharmony_ci        &DfxCrasher::PrintFatalMessageInLibc},
138800b99b8Sopenharmony_ci    {"TestGetCrashObj", "Test get object when crash",
139800b99b8Sopenharmony_ci        &DfxCrasher::TestGetCrashObj},
140800b99b8Sopenharmony_ci#ifndef is_ohos_lite
141800b99b8Sopenharmony_ci    {"AsyncStack", "Test async stacktrace in nomal thread crash case",
142800b99b8Sopenharmony_ci        &DfxCrasher::AsyncStacktrace},
143800b99b8Sopenharmony_ci#endif
144800b99b8Sopenharmony_ci    {"Deadlock", "Test deadlock and parse lock owner",
145800b99b8Sopenharmony_ci        &DfxCrasher::TestDeadlock},
146800b99b8Sopenharmony_ci};
147800b99b8Sopenharmony_ci
148800b99b8Sopenharmony_ciconstexpr static CrasherCommandLineParam CMDLINE_TABLE_PARAM[] = {
149800b99b8Sopenharmony_ci#ifndef is_ohos_lite
150800b99b8Sopenharmony_ci    {"CrashInFFRT", "Test async-stacktrace api in ffrt crash case",
151800b99b8Sopenharmony_ci        &DfxCrasher::CrashInFFRT},
152800b99b8Sopenharmony_ci    {"CrashInLibuvWork", "Test async-stacktrace api in work callback crash case",
153800b99b8Sopenharmony_ci        &DfxCrasher::CrashInLibuvWork},
154800b99b8Sopenharmony_ci    {"CrashInLibuvTimer", "Test async-stacktrace api in timer callback crash case",
155800b99b8Sopenharmony_ci        &DfxCrasher::CrashInLibuvTimer},
156800b99b8Sopenharmony_ci    {"CrashInLibuvWorkDone", "Test async-stacktrace api in work callback done crash case",
157800b99b8Sopenharmony_ci        &DfxCrasher::CrashInLibuvWorkDone},
158800b99b8Sopenharmony_ci#endif
159800b99b8Sopenharmony_ci};
160800b99b8Sopenharmony_ci
161800b99b8Sopenharmony_ciextern "C" uintptr_t DFX_SetCrashObj(uint8_t type, uintptr_t addr) __attribute__((weak));
162800b99b8Sopenharmony_ciextern "C" void DFX_ResetCrashObj(uintptr_t crashObj) __attribute__((weak));
163800b99b8Sopenharmony_ci
164800b99b8Sopenharmony_ciDfxCrasher::DfxCrasher() {}
165800b99b8Sopenharmony_ciDfxCrasher::~DfxCrasher() {}
166800b99b8Sopenharmony_ci
167800b99b8Sopenharmony_ciDfxCrasher &DfxCrasher::GetInstance()
168800b99b8Sopenharmony_ci{
169800b99b8Sopenharmony_ci    static DfxCrasher instance;
170800b99b8Sopenharmony_ci    return instance;
171800b99b8Sopenharmony_ci}
172800b99b8Sopenharmony_ci
173800b99b8Sopenharmony_ciint DfxCrasher::TestDeadlock()
174800b99b8Sopenharmony_ci{
175800b99b8Sopenharmony_ci    pthread_mutexattr_t mutexAttr;
176800b99b8Sopenharmony_ci    pthread_mutexattr_init(&mutexAttr);
177800b99b8Sopenharmony_ci    pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_ERRORCHECK);
178800b99b8Sopenharmony_ci
179800b99b8Sopenharmony_ci    pthread_mutex_t mutex;
180800b99b8Sopenharmony_ci    pthread_mutex_init(&mutex, &mutexAttr);
181800b99b8Sopenharmony_ci    pthread_mutexattr_destroy(&mutexAttr);
182800b99b8Sopenharmony_ci
183800b99b8Sopenharmony_ci    int lockOnwerIdx = 1;
184800b99b8Sopenharmony_ci    int lockOwnerMask = 0x3fffffff;
185800b99b8Sopenharmony_ci    auto mutexInt = reinterpret_cast<int*>(&mutex);
186800b99b8Sopenharmony_ci    printf("mutex address:%llx\n", reinterpret_cast<long long>(&mutex));
187800b99b8Sopenharmony_ci    printf("mutex owner before lock:%d\n", mutexInt[lockOnwerIdx] & lockOwnerMask);
188800b99b8Sopenharmony_ci    pthread_mutex_lock(&mutex);
189800b99b8Sopenharmony_ci    printf("mutex owner after lock:%d\n", mutexInt[lockOnwerIdx] & lockOwnerMask);
190800b99b8Sopenharmony_ci    std::thread t1([&mutex] {
191800b99b8Sopenharmony_ci        pthread_mutex_lock(&mutex);
192800b99b8Sopenharmony_ci    });
193800b99b8Sopenharmony_ci    t1.join();
194800b99b8Sopenharmony_ci    return 0;
195800b99b8Sopenharmony_ci}
196800b99b8Sopenharmony_ci
197800b99b8Sopenharmony_cistatic NOINLINE int RecursiveHelperFunction(int curLevel, int targetLevel, int midLevel)
198800b99b8Sopenharmony_ci{
199800b99b8Sopenharmony_ci    auto top = __builtin_frame_address(0);
200800b99b8Sopenharmony_ci    uintptr_t size = 256;
201800b99b8Sopenharmony_ci    if (curLevel == targetLevel) {
202800b99b8Sopenharmony_ci        if (midLevel != 0) {
203800b99b8Sopenharmony_ci            abort();
204800b99b8Sopenharmony_ci        }
205800b99b8Sopenharmony_ci        printf("RecursiveHelperFunction top:%p\n", top);
206800b99b8Sopenharmony_ci        // crash in return address
207800b99b8Sopenharmony_ci        (void)memset_s(top, size, 0, size);
208800b99b8Sopenharmony_ci        return 0;
209800b99b8Sopenharmony_ci    }
210800b99b8Sopenharmony_ci
211800b99b8Sopenharmony_ci    if (midLevel != 0 && curLevel == midLevel) {
212800b99b8Sopenharmony_ci        // crash in return address
213800b99b8Sopenharmony_ci        (void)memset_s(top, size, 0, size);
214800b99b8Sopenharmony_ci    }
215800b99b8Sopenharmony_ci
216800b99b8Sopenharmony_ci    int nextLevel = curLevel + 1;
217800b99b8Sopenharmony_ci    if (midLevel != 0 || targetLevel != 0) {
218800b99b8Sopenharmony_ci        RecursiveHelperFunction(nextLevel, targetLevel, midLevel);
219800b99b8Sopenharmony_ci    }
220800b99b8Sopenharmony_ci
221800b99b8Sopenharmony_ci    printf("RecursiveHelperFunction curLevel:%d targetLevel:%d top:%p\n", curLevel, targetLevel, top);
222800b99b8Sopenharmony_ci    return nextLevel + 1;
223800b99b8Sopenharmony_ci}
224800b99b8Sopenharmony_ci
225800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::StackCorruption()
226800b99b8Sopenharmony_ci{
227800b99b8Sopenharmony_ci    constexpr int targetLevel = 64;
228800b99b8Sopenharmony_ci    constexpr int midLevel = 0;
229800b99b8Sopenharmony_ci    return RecursiveHelperFunction(1, targetLevel, midLevel);
230800b99b8Sopenharmony_ci}
231800b99b8Sopenharmony_ci
232800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::StackCorruption2()
233800b99b8Sopenharmony_ci{
234800b99b8Sopenharmony_ci    constexpr int targetLevel = 64;
235800b99b8Sopenharmony_ci    constexpr int midLevel = 32;
236800b99b8Sopenharmony_ci    return RecursiveHelperFunction(1, targetLevel, midLevel);
237800b99b8Sopenharmony_ci}
238800b99b8Sopenharmony_ci
239800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::RaiseFloatingPointException()
240800b99b8Sopenharmony_ci{
241800b99b8Sopenharmony_ci    raise(SIGFPE);
242800b99b8Sopenharmony_ci    return 0;
243800b99b8Sopenharmony_ci}
244800b99b8Sopenharmony_ci
245800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::RaiseIllegalInstructionException()
246800b99b8Sopenharmony_ci{
247800b99b8Sopenharmony_ci    raise(SIGILL);
248800b99b8Sopenharmony_ci    return 0;
249800b99b8Sopenharmony_ci}
250800b99b8Sopenharmony_ci
251800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::RaiseSegmentFaultException()
252800b99b8Sopenharmony_ci{
253800b99b8Sopenharmony_ci    std::cout << "call RaiseSegmentFaultException" << std::endl;
254800b99b8Sopenharmony_ci    raise(SIGSEGV);
255800b99b8Sopenharmony_ci    return 0;
256800b99b8Sopenharmony_ci}
257800b99b8Sopenharmony_ci
258800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::RaiseTrapException()
259800b99b8Sopenharmony_ci{
260800b99b8Sopenharmony_ci    raise(SIGTRAP);
261800b99b8Sopenharmony_ci    return 0;
262800b99b8Sopenharmony_ci}
263800b99b8Sopenharmony_ci
264800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::RaiseAbort()
265800b99b8Sopenharmony_ci{
266800b99b8Sopenharmony_ci    HILOG_FATAL(LOG_CORE, "Test Trigger ABORT!");
267800b99b8Sopenharmony_ci    raise(SIGABRT);
268800b99b8Sopenharmony_ci    return 0;
269800b99b8Sopenharmony_ci}
270800b99b8Sopenharmony_ci
271800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::RaiseBusError()
272800b99b8Sopenharmony_ci{
273800b99b8Sopenharmony_ci    raise(SIGBUS);
274800b99b8Sopenharmony_ci    return 0;
275800b99b8Sopenharmony_ci}
276800b99b8Sopenharmony_ci
277800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::IllegalInstructionException(void)
278800b99b8Sopenharmony_ci{
279800b99b8Sopenharmony_ci#if defined(__aarch64__)
280800b99b8Sopenharmony_ci    __asm__ volatile(".word 0\n");
281800b99b8Sopenharmony_ci#elif defined(__arm__)
282800b99b8Sopenharmony_ci    __asm__ volatile(".word 0xe7f0def0\n");
283800b99b8Sopenharmony_ci#elif defined(__x86_64__)
284800b99b8Sopenharmony_ci    __asm__ volatile("ud2\n");
285800b99b8Sopenharmony_ci#else
286800b99b8Sopenharmony_ci#error
287800b99b8Sopenharmony_ci#endif
288800b99b8Sopenharmony_ci    return 0;
289800b99b8Sopenharmony_ci}
290800b99b8Sopenharmony_ci
291800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::TriggerSegmentFaultException()
292800b99b8Sopenharmony_ci{
293800b99b8Sopenharmony_ci    std::cout << "test TriggerSegmentFaultException" << std::endl;
294800b99b8Sopenharmony_ci    // for crash test force cast the type
295800b99b8Sopenharmony_ci    int *a = reinterpret_cast<int *>(&TestFunc70);
296800b99b8Sopenharmony_ci    *a = SIGSEGV;
297800b99b8Sopenharmony_ci    return 0;
298800b99b8Sopenharmony_ci}
299800b99b8Sopenharmony_ci
300800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::TriggerTrapException()
301800b99b8Sopenharmony_ci{
302800b99b8Sopenharmony_ci#ifndef __x86_64__
303800b99b8Sopenharmony_ci    __asm__ volatile(".inst 0xde01");
304800b99b8Sopenharmony_ci#endif
305800b99b8Sopenharmony_ci    return 0;
306800b99b8Sopenharmony_ci}
307800b99b8Sopenharmony_ci
308800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::Abort(void)
309800b99b8Sopenharmony_ci{
310800b99b8Sopenharmony_ci    HILOG_FATAL(LOG_CORE, "Test Trigger ABORT!");
311800b99b8Sopenharmony_ci    abort();
312800b99b8Sopenharmony_ci    return 0;
313800b99b8Sopenharmony_ci}
314800b99b8Sopenharmony_ci
315800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::SegmentFaultException(void)
316800b99b8Sopenharmony_ci{
317800b99b8Sopenharmony_ci    volatile char *ptr = nullptr;
318800b99b8Sopenharmony_ci    *ptr;
319800b99b8Sopenharmony_ci    return 0;
320800b99b8Sopenharmony_ci}
321800b99b8Sopenharmony_ci
322800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::MaxStackDepth()
323800b99b8Sopenharmony_ci{
324800b99b8Sopenharmony_ci    return TestFunc1();
325800b99b8Sopenharmony_ci}
326800b99b8Sopenharmony_ci
327800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::MaxMethodNameTest12345678901234567890123456789012345678901234567890ABC()
328800b99b8Sopenharmony_ci{
329800b99b8Sopenharmony_ci    std::cout << "call MaxMethodNameTest12345678901234567890123456789012345678901234567890ABC" << std::endl;
330800b99b8Sopenharmony_ci    raise(SIGSEGV);
331800b99b8Sopenharmony_ci    return 0;
332800b99b8Sopenharmony_ci}
333800b99b8Sopenharmony_ci
334800b99b8Sopenharmony_cistatic void *DoStackOverflow(void * inputArg)
335800b99b8Sopenharmony_ci{
336800b99b8Sopenharmony_ci    int b[10] = {1};
337800b99b8Sopenharmony_ci    int *c = nullptr;
338800b99b8Sopenharmony_ci    (void)memcpy_s(c, sizeof(int), b, sizeof(int));
339800b99b8Sopenharmony_ci    if (b[0] == 0) {
340800b99b8Sopenharmony_ci        return static_cast<void*>(b + 9); // 9: last element of array
341800b99b8Sopenharmony_ci    }
342800b99b8Sopenharmony_ci    DoStackOverflow(inputArg);
343800b99b8Sopenharmony_ci    return static_cast<void*>(b + 9); // 9: last element of array
344800b99b8Sopenharmony_ci}
345800b99b8Sopenharmony_ci
346800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::StackOverflow()
347800b99b8Sopenharmony_ci{
348800b99b8Sopenharmony_ci    pthread_t tid;
349800b99b8Sopenharmony_ci    pthread_attr_t attr;
350800b99b8Sopenharmony_ci    int err = pthread_attr_init(&attr);
351800b99b8Sopenharmony_ci    if (err != 0) {
352800b99b8Sopenharmony_ci        return err;
353800b99b8Sopenharmony_ci    }
354800b99b8Sopenharmony_ci
355800b99b8Sopenharmony_ci    constexpr int maxStackSize = 1024 * 10;
356800b99b8Sopenharmony_ci    if (pthread_attr_setstacksize(&attr, maxStackSize) == 0) {
357800b99b8Sopenharmony_ci        pthread_create(&tid, &attr, DoStackOverflow, nullptr);
358800b99b8Sopenharmony_ci        pthread_join(tid, nullptr);
359800b99b8Sopenharmony_ci    } else {
360800b99b8Sopenharmony_ci        std::cout << "failed" << std::endl;
361800b99b8Sopenharmony_ci    }
362800b99b8Sopenharmony_ci    return 0;
363800b99b8Sopenharmony_ci}
364800b99b8Sopenharmony_ci
365800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::Oom()
366800b99b8Sopenharmony_ci{
367800b99b8Sopenharmony_ci    std::cout << "test oom" << std::endl;
368800b99b8Sopenharmony_ci    struct rlimit oldRlimit;
369800b99b8Sopenharmony_ci    if (getrlimit(RLIMIT_AS, &oldRlimit) != 0) {
370800b99b8Sopenharmony_ci        std::cout << "getrlimit failed" << std::endl;
371800b99b8Sopenharmony_ci        raise(SIGINT);
372800b99b8Sopenharmony_ci    }
373800b99b8Sopenharmony_ci    std::cout << std::hex << "old rlimit, cur:0x" << oldRlimit.rlim_cur << std::endl;
374800b99b8Sopenharmony_ci    std::cout << std::hex << "old rlimit, max:0x" << oldRlimit.rlim_max << std::endl;
375800b99b8Sopenharmony_ci
376800b99b8Sopenharmony_ci    struct rlimit rlim = {
377800b99b8Sopenharmony_ci        .rlim_cur = ARG128 * ARG1024 * ARG1024,
378800b99b8Sopenharmony_ci        .rlim_max = ARG128 * ARG1024 * ARG1024,
379800b99b8Sopenharmony_ci    };
380800b99b8Sopenharmony_ci
381800b99b8Sopenharmony_ci    if (setrlimit(RLIMIT_AS, &rlim) != 0) {
382800b99b8Sopenharmony_ci        std::cout << "setrlimit failed" << std::endl;
383800b99b8Sopenharmony_ci        raise(SIGINT);
384800b99b8Sopenharmony_ci    }
385800b99b8Sopenharmony_ci
386800b99b8Sopenharmony_ci    std::vector<void*> vec;
387800b99b8Sopenharmony_ci    for (int i = 0; i < ARG128; i++) {
388800b99b8Sopenharmony_ci        char* buf = static_cast<char*>(mmap(nullptr, (ARG1024 * ARG1024), PROT_READ | PROT_WRITE,
389800b99b8Sopenharmony_ci                                            MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
390800b99b8Sopenharmony_ci        if (buf == (char*)MAP_FAILED) {
391800b99b8Sopenharmony_ci            std::cout << "malloc return null" << std::endl;
392800b99b8Sopenharmony_ci            if (setrlimit(RLIMIT_AS, &oldRlimit) != 0) {
393800b99b8Sopenharmony_ci                std::cout << "restore rlimit failed" << std::endl;
394800b99b8Sopenharmony_ci            }
395800b99b8Sopenharmony_ci            std::cout << "restore rlimit ok" << std::endl;
396800b99b8Sopenharmony_ci            abort();
397800b99b8Sopenharmony_ci        }
398800b99b8Sopenharmony_ci
399800b99b8Sopenharmony_ci        (void)memset_s(buf, ARG1024 * ARG1024, 0xff, ARG1024 * ARG1024);
400800b99b8Sopenharmony_ci        vec.push_back(buf);
401800b99b8Sopenharmony_ci    }
402800b99b8Sopenharmony_ci    return 0;
403800b99b8Sopenharmony_ci}
404800b99b8Sopenharmony_ci
405800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::ProgramCounterZero()
406800b99b8Sopenharmony_ci{
407800b99b8Sopenharmony_ci    std::cout << "test PCZero" << std::endl;
408800b99b8Sopenharmony_ci#if defined(__arm__)
409800b99b8Sopenharmony_ci    __asm__ volatile (
410800b99b8Sopenharmony_ci        "mov r0, #0x00\n mov lr, pc\n bx r0\n"
411800b99b8Sopenharmony_ci    );
412800b99b8Sopenharmony_ci#elif defined(__aarch64__)
413800b99b8Sopenharmony_ci    __asm__ volatile (
414800b99b8Sopenharmony_ci        "movz x0, #0x0\n"
415800b99b8Sopenharmony_ci        "adr x30, .\n"
416800b99b8Sopenharmony_ci        "br x0\n"
417800b99b8Sopenharmony_ci    );
418800b99b8Sopenharmony_ci#endif
419800b99b8Sopenharmony_ci    return 0;
420800b99b8Sopenharmony_ci}
421800b99b8Sopenharmony_ci
422800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::MultiThreadCrash()
423800b99b8Sopenharmony_ci{
424800b99b8Sopenharmony_ci    std::cout << "test MultiThreadCrash" << std::endl;
425800b99b8Sopenharmony_ci
426800b99b8Sopenharmony_ci    std::thread ([] {
427800b99b8Sopenharmony_ci        SleepThread(NUMBER_ONE);
428800b99b8Sopenharmony_ci    }).detach();
429800b99b8Sopenharmony_ci    std::thread ([] {
430800b99b8Sopenharmony_ci        SleepThread(NUMBER_TWO);
431800b99b8Sopenharmony_ci    }).detach();
432800b99b8Sopenharmony_ci    sleep(1);
433800b99b8Sopenharmony_ci
434800b99b8Sopenharmony_ci    raise(SIGSEGV);
435800b99b8Sopenharmony_ci
436800b99b8Sopenharmony_ci    return 0;
437800b99b8Sopenharmony_ci}
438800b99b8Sopenharmony_ci
439800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::StackOver64()
440800b99b8Sopenharmony_ci{
441800b99b8Sopenharmony_ci    std::cout << "test StackOver64" << std::endl;
442800b99b8Sopenharmony_ci
443800b99b8Sopenharmony_ci    return TestFunc1();
444800b99b8Sopenharmony_ci}
445800b99b8Sopenharmony_ci
446800b99b8Sopenharmony_ciint SleepThread(int threadID)
447800b99b8Sopenharmony_ci{
448800b99b8Sopenharmony_ci    std::cout << "create MultiThread " <<  threadID << std::endl;
449800b99b8Sopenharmony_ci
450800b99b8Sopenharmony_ci    int sleepTime = 10;
451800b99b8Sopenharmony_ci    sleep(sleepTime);
452800b99b8Sopenharmony_ci
453800b99b8Sopenharmony_ci    return 0;
454800b99b8Sopenharmony_ci}
455800b99b8Sopenharmony_ci
456800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::StackTop()
457800b99b8Sopenharmony_ci{
458800b99b8Sopenharmony_ci    std::cout << "test StackTop" << std::endl;
459800b99b8Sopenharmony_ci#if defined(__arm__)
460800b99b8Sopenharmony_ci    unsigned int stackTop;
461800b99b8Sopenharmony_ci    __asm__ volatile ("mov %0, sp":"=r"(stackTop)::);
462800b99b8Sopenharmony_ci#elif defined(__aarch64__)
463800b99b8Sopenharmony_ci    uint64_t stackTop;
464800b99b8Sopenharmony_ci    __asm__ volatile ("mov %0, sp":"=r"(stackTop)::);
465800b99b8Sopenharmony_ci#else
466800b99b8Sopenharmony_ci    uint64_t stackTop = 0; // for fixing compile error on x64
467800b99b8Sopenharmony_ci#endif
468800b99b8Sopenharmony_ci    std::cout << "crasher_c: stack top is = " << std::hex << stackTop << std::endl;
469800b99b8Sopenharmony_ci
470800b99b8Sopenharmony_ci    std::ofstream fout;
471800b99b8Sopenharmony_ci    fout.open("/data/sp");
472800b99b8Sopenharmony_ci    fout << std::hex << stackTop << std::endl;
473800b99b8Sopenharmony_ci    fout.close();
474800b99b8Sopenharmony_ci
475800b99b8Sopenharmony_ci#if defined(__arm__)
476800b99b8Sopenharmony_ci    __asm__ volatile ("mov r1, #0\nldr r2, [r1]\n");
477800b99b8Sopenharmony_ci#elif defined(__aarch64__)
478800b99b8Sopenharmony_ci    __asm__ volatile ("mov x1, #0\nldr x2, [x1]\n");
479800b99b8Sopenharmony_ci#endif
480800b99b8Sopenharmony_ci
481800b99b8Sopenharmony_ci    return 0;
482800b99b8Sopenharmony_ci}
483800b99b8Sopenharmony_ci
484800b99b8Sopenharmony_civoid DfxCrasher::PrintUsage() const
485800b99b8Sopenharmony_ci{
486800b99b8Sopenharmony_ci    std::cout << "  usage: crasher CMD" << std::endl;
487800b99b8Sopenharmony_ci    std::cout << "\n";
488800b99b8Sopenharmony_ci    std::cout << "  where CMD support:" << std::endl;
489800b99b8Sopenharmony_ci    for (auto& item : CMDLINE_TABLE) {
490800b99b8Sopenharmony_ci        std::cout << "  " << item.cmdline << " : " << item.description << std::endl;
491800b99b8Sopenharmony_ci    }
492800b99b8Sopenharmony_ci    std::cout << "  if you want the command execute in a sub thread" << std::endl;
493800b99b8Sopenharmony_ci    std::cout << "  add thread Prefix, e.g crasher thread-SIGFPE" << std::endl;
494800b99b8Sopenharmony_ci    std::cout << "\n";
495800b99b8Sopenharmony_ci}
496800b99b8Sopenharmony_ci
497800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::CrashInLambda()
498800b99b8Sopenharmony_ci{
499800b99b8Sopenharmony_ci    std::function<void()> lambda = TestFunc50;
500800b99b8Sopenharmony_ci    lambda();
501800b99b8Sopenharmony_ci    return 0;
502800b99b8Sopenharmony_ci}
503800b99b8Sopenharmony_ci
504800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::DoDumpCrash()
505800b99b8Sopenharmony_ci{
506800b99b8Sopenharmony_ci    std::thread t([] {
507800b99b8Sopenharmony_ci        TestFunc1();
508800b99b8Sopenharmony_ci    });
509800b99b8Sopenharmony_ci    raise(SIGDUMP);
510800b99b8Sopenharmony_ci    t.join();
511800b99b8Sopenharmony_ci    return 0;
512800b99b8Sopenharmony_ci}
513800b99b8Sopenharmony_ci
514800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::TestExitHook()
515800b99b8Sopenharmony_ci{
516800b99b8Sopenharmony_ci    exit(1);
517800b99b8Sopenharmony_ci    return 0;
518800b99b8Sopenharmony_ci}
519800b99b8Sopenharmony_ci
520800b99b8Sopenharmony_cistatic void SigHookHandler(int signo)
521800b99b8Sopenharmony_ci{
522800b99b8Sopenharmony_ci    printf("SigHookHandler:%d\n", signo);
523800b99b8Sopenharmony_ci}
524800b99b8Sopenharmony_ci
525800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::TestSigHook()
526800b99b8Sopenharmony_ci{
527800b99b8Sopenharmony_ci    signal(SIGSEGV, SigHookHandler);
528800b99b8Sopenharmony_ci    return 0;
529800b99b8Sopenharmony_ci}
530800b99b8Sopenharmony_ci
531800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::PrintFatalMessageInLibc()
532800b99b8Sopenharmony_ci{
533800b99b8Sopenharmony_ci    set_fatal_message("TestPrintFatalMessageInLibc");
534800b99b8Sopenharmony_ci    RaiseAbort();
535800b99b8Sopenharmony_ci    return 0;
536800b99b8Sopenharmony_ci}
537800b99b8Sopenharmony_ci
538800b99b8Sopenharmony_ciNOINLINE static void TestGetCrashObjInner()
539800b99b8Sopenharmony_ci{
540800b99b8Sopenharmony_ci    uintptr_t val = 0;
541800b99b8Sopenharmony_ci    if (DFX_SetCrashObj != nullptr) {
542800b99b8Sopenharmony_ci        uintptr_t type = 0;
543800b99b8Sopenharmony_ci        std::string msg = "test get crashObjectInner.";
544800b99b8Sopenharmony_ci        val = DFX_SetCrashObj(type, reinterpret_cast<uintptr_t>(msg.c_str()));
545800b99b8Sopenharmony_ci    }
546800b99b8Sopenharmony_ci    if (DFX_ResetCrashObj != nullptr) {
547800b99b8Sopenharmony_ci        DFX_ResetCrashObj(val);
548800b99b8Sopenharmony_ci    }
549800b99b8Sopenharmony_ci}
550800b99b8Sopenharmony_ci
551800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::TestGetCrashObj()
552800b99b8Sopenharmony_ci{
553800b99b8Sopenharmony_ci    uintptr_t crashObj = 0;
554800b99b8Sopenharmony_ci    if (DFX_SetCrashObj != nullptr) {
555800b99b8Sopenharmony_ci        uint8_t type = 0;
556800b99b8Sopenharmony_ci        std::string msg = "test get crashObject.";
557800b99b8Sopenharmony_ci        crashObj = DFX_SetCrashObj(type, reinterpret_cast<uintptr_t>(msg.c_str()));
558800b99b8Sopenharmony_ci    }
559800b99b8Sopenharmony_ci    TestGetCrashObjInner();
560800b99b8Sopenharmony_ci    RaiseAbort();
561800b99b8Sopenharmony_ci    if (DFX_ResetCrashObj != nullptr) {
562800b99b8Sopenharmony_ci        DFX_ResetCrashObj(crashObj);
563800b99b8Sopenharmony_ci    }
564800b99b8Sopenharmony_ci    return 0;
565800b99b8Sopenharmony_ci}
566800b99b8Sopenharmony_ci
567800b99b8Sopenharmony_cistatic void* CrashInSubThread(void* stackIdPtr)
568800b99b8Sopenharmony_ci{
569800b99b8Sopenharmony_ci    uint64_t value = *reinterpret_cast<uint64_t *>(stackIdPtr);
570800b99b8Sopenharmony_ci    SetStackId(value);
571800b99b8Sopenharmony_ci    printf("CrashInSubThread stackId:%p value:%p.\n", stackIdPtr, reinterpret_cast<void*>(value));
572800b99b8Sopenharmony_ci    raise(SIGSEGV);
573800b99b8Sopenharmony_ci    return nullptr;
574800b99b8Sopenharmony_ci}
575800b99b8Sopenharmony_ci
576800b99b8Sopenharmony_ci#ifndef is_ohos_lite
577800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::AsyncStacktrace()
578800b99b8Sopenharmony_ci{
579800b99b8Sopenharmony_ci#ifdef __aarch64__
580800b99b8Sopenharmony_ci    uint64_t stackId = CollectAsyncStack();
581800b99b8Sopenharmony_ci    printf("Current stackId:%p.\n", (void*)stackId);
582800b99b8Sopenharmony_ci    pthread_t thread;
583800b99b8Sopenharmony_ci    pthread_create(&thread, NULL, CrashInSubThread, (void*)&stackId);
584800b99b8Sopenharmony_ci    void *result = nullptr;
585800b99b8Sopenharmony_ci    pthread_join(thread, &result);
586800b99b8Sopenharmony_ci    return (uint64_t)(result);
587800b99b8Sopenharmony_ci#else
588800b99b8Sopenharmony_ci    printf("Unsupported arch.\n");
589800b99b8Sopenharmony_ci    return 0;
590800b99b8Sopenharmony_ci#endif
591800b99b8Sopenharmony_ci}
592800b99b8Sopenharmony_ci
593800b99b8Sopenharmony_ciNOINLINE static int FFRTTaskSubmit1(int i)
594800b99b8Sopenharmony_ci{
595800b99b8Sopenharmony_ci    int inner = i + 1;
596800b99b8Sopenharmony_ci    printf("FFRTTaskSubmit1:current %d\n", inner);
597800b99b8Sopenharmony_ci    ffrt::submit(
598800b99b8Sopenharmony_ci        [&]() {
599800b99b8Sopenharmony_ci            inner = 2; // 2 : inner count
600800b99b8Sopenharmony_ci            raise(SIGSEGV);
601800b99b8Sopenharmony_ci        },
602800b99b8Sopenharmony_ci        {},
603800b99b8Sopenharmony_ci        {&inner});
604800b99b8Sopenharmony_ci    return inner;
605800b99b8Sopenharmony_ci}
606800b99b8Sopenharmony_ci
607800b99b8Sopenharmony_ciNOINLINE static int FFRTTaskSubmit0(int i)
608800b99b8Sopenharmony_ci{
609800b99b8Sopenharmony_ci    int inner = i + 1;
610800b99b8Sopenharmony_ci    printf("FFRTTaskSubmit0:current %d\n", inner);
611800b99b8Sopenharmony_ci    return FFRTTaskSubmit1(i);
612800b99b8Sopenharmony_ci}
613800b99b8Sopenharmony_ci
614800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::CrashInFFRT(const std::string &debug)
615800b99b8Sopenharmony_ci{
616800b99b8Sopenharmony_ci    if (debug == "true") {
617800b99b8Sopenharmony_ci        setenv("HAP_DEBUGGABLE", "true", 1);
618800b99b8Sopenharmony_ci    }
619800b99b8Sopenharmony_ci    int i = FFRTTaskSubmit0(10);
620800b99b8Sopenharmony_ci    ffrt::wait();
621800b99b8Sopenharmony_ci    return i;
622800b99b8Sopenharmony_ci}
623800b99b8Sopenharmony_ci
624800b99b8Sopenharmony_cistatic bool g_done = 0;
625800b99b8Sopenharmony_cistatic unsigned g_events = 0;
626800b99b8Sopenharmony_cistatic unsigned g_result;
627800b99b8Sopenharmony_ci
628800b99b8Sopenharmony_ciNOINLINE static void WorkCallback(uv_work_t* req)
629800b99b8Sopenharmony_ci{
630800b99b8Sopenharmony_ci    req->data = &g_result;
631800b99b8Sopenharmony_ci    raise(SIGSEGV);
632800b99b8Sopenharmony_ci}
633800b99b8Sopenharmony_ci
634800b99b8Sopenharmony_ciNOINLINE static void AfterWorkCallback(uv_work_t* req, int status)
635800b99b8Sopenharmony_ci{
636800b99b8Sopenharmony_ci    g_events++;
637800b99b8Sopenharmony_ci    if (!g_done) {
638800b99b8Sopenharmony_ci        uv_queue_work(req->loop, req, WorkCallback, AfterWorkCallback);
639800b99b8Sopenharmony_ci    }
640800b99b8Sopenharmony_ci}
641800b99b8Sopenharmony_ci
642800b99b8Sopenharmony_cistatic void TimerCallback(uv_timer_t* handle)
643800b99b8Sopenharmony_ci{
644800b99b8Sopenharmony_ci    g_done = true;
645800b99b8Sopenharmony_ci}
646800b99b8Sopenharmony_ci
647800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::CrashInLibuvWork(const std::string &debug)
648800b99b8Sopenharmony_ci{
649800b99b8Sopenharmony_ci    if (debug == "true") {
650800b99b8Sopenharmony_ci        setenv("HAP_DEBUGGABLE", "true", 1);
651800b99b8Sopenharmony_ci    }
652800b99b8Sopenharmony_ci    uv_timer_t timerHandle;
653800b99b8Sopenharmony_ci    uv_work_t work;
654800b99b8Sopenharmony_ci    uv_loop_t* loop = uv_default_loop();
655800b99b8Sopenharmony_ci    int timeout = 5000;
656800b99b8Sopenharmony_ci    uv_timer_init(loop, &timerHandle);
657800b99b8Sopenharmony_ci    uv_timer_start(&timerHandle, TimerCallback, timeout, 0);
658800b99b8Sopenharmony_ci    uv_queue_work(loop, &work, WorkCallback, AfterWorkCallback);
659800b99b8Sopenharmony_ci    uv_run(loop, UV_RUN_DEFAULT);
660800b99b8Sopenharmony_ci    printf("END in CrashInLibuvWork\n");
661800b99b8Sopenharmony_ci    return 0;
662800b99b8Sopenharmony_ci}
663800b99b8Sopenharmony_ci
664800b99b8Sopenharmony_cistatic void TimerCallback2(uv_timer_t* handle)
665800b99b8Sopenharmony_ci{
666800b99b8Sopenharmony_ci    raise(SIGSEGV);
667800b99b8Sopenharmony_ci}
668800b99b8Sopenharmony_ci
669800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::CrashInLibuvTimer(const std::string &debug)
670800b99b8Sopenharmony_ci{
671800b99b8Sopenharmony_ci    if (debug == "true") {
672800b99b8Sopenharmony_ci        setenv("HAP_DEBUGGABLE", "true", 1);
673800b99b8Sopenharmony_ci    }
674800b99b8Sopenharmony_ci    uv_timer_t timerHandle;
675800b99b8Sopenharmony_ci    uv_work_t work;
676800b99b8Sopenharmony_ci    uv_loop_t* loop = uv_default_loop();
677800b99b8Sopenharmony_ci    int timeout = 5000;
678800b99b8Sopenharmony_ci    uv_timer_init(loop, &timerHandle);
679800b99b8Sopenharmony_ci    uv_timer_start(&timerHandle, TimerCallback2, timeout, 0);
680800b99b8Sopenharmony_ci    uv_queue_work(loop, &work, WorkCallback, AfterWorkCallback);
681800b99b8Sopenharmony_ci    uv_run(loop, UV_RUN_DEFAULT);
682800b99b8Sopenharmony_ci    printf("END in CrashInLibuvTimer\n");
683800b99b8Sopenharmony_ci    return 0;
684800b99b8Sopenharmony_ci}
685800b99b8Sopenharmony_ci
686800b99b8Sopenharmony_ciNOINLINE static void WorkCallback2(uv_work_t* req)
687800b99b8Sopenharmony_ci{
688800b99b8Sopenharmony_ci    req->data = &g_result;
689800b99b8Sopenharmony_ci}
690800b99b8Sopenharmony_ci
691800b99b8Sopenharmony_ciNOINLINE static void CrashAfterWorkCallback(uv_work_t* req, int status)
692800b99b8Sopenharmony_ci{
693800b99b8Sopenharmony_ci    raise(SIGSEGV);
694800b99b8Sopenharmony_ci}
695800b99b8Sopenharmony_ci
696800b99b8Sopenharmony_ciNOINLINE int DfxCrasher::CrashInLibuvWorkDone(const std::string &debug)
697800b99b8Sopenharmony_ci{
698800b99b8Sopenharmony_ci    if (debug == "true") {
699800b99b8Sopenharmony_ci        setenv("HAP_DEBUGGABLE", "true", 1);
700800b99b8Sopenharmony_ci    }
701800b99b8Sopenharmony_ci    uv_work_t work;
702800b99b8Sopenharmony_ci    uv_loop_t* loop = uv_default_loop();
703800b99b8Sopenharmony_ci    uv_queue_work(loop, &work, WorkCallback2, CrashAfterWorkCallback);
704800b99b8Sopenharmony_ci    uv_run(loop, UV_RUN_DEFAULT);
705800b99b8Sopenharmony_ci    printf("END in CrashInLibuvWorkDone\n");
706800b99b8Sopenharmony_ci    return 0;
707800b99b8Sopenharmony_ci}
708800b99b8Sopenharmony_ci#endif
709800b99b8Sopenharmony_ci
710800b99b8Sopenharmony_civoid* DfxCrasher::DoCrashInThread(void * inputArg)
711800b99b8Sopenharmony_ci{
712800b99b8Sopenharmony_ci    prctl(PR_SET_NAME, "SubTestThread");
713800b99b8Sopenharmony_ci    const char* arg = (const char *)(inputArg);
714800b99b8Sopenharmony_ci    return reinterpret_cast<void*>(DfxCrasher::GetInstance().ParseAndDoCrash(arg));
715800b99b8Sopenharmony_ci}
716800b99b8Sopenharmony_ci
717800b99b8Sopenharmony_ciuint64_t DfxCrasher::DoActionOnSubThread(const char *arg) const
718800b99b8Sopenharmony_ci{
719800b99b8Sopenharmony_ci    pthread_t t;
720800b99b8Sopenharmony_ci    pthread_create(&t, nullptr, DfxCrasher::DoCrashInThread, const_cast<char*>(arg));
721800b99b8Sopenharmony_ci    void *result = nullptr;
722800b99b8Sopenharmony_ci    pthread_join(t, &result);
723800b99b8Sopenharmony_ci    return (uint64_t)(result);
724800b99b8Sopenharmony_ci}
725800b99b8Sopenharmony_ci
726800b99b8Sopenharmony_ciint DfxCrasher::Loop()
727800b99b8Sopenharmony_ci{
728800b99b8Sopenharmony_ci    int i = 0;
729800b99b8Sopenharmony_ci    while (1) {
730800b99b8Sopenharmony_ci        usleep(10000); // 10000:sleep 0.01 second
731800b99b8Sopenharmony_ci        i++;
732800b99b8Sopenharmony_ci    }
733800b99b8Sopenharmony_ci    return 0;
734800b99b8Sopenharmony_ci}
735800b99b8Sopenharmony_ci
736800b99b8Sopenharmony_ciuint64_t DfxCrasher::ParseAndDoCrash(const char *arg) const
737800b99b8Sopenharmony_ci{
738800b99b8Sopenharmony_ci    // Prefix
739800b99b8Sopenharmony_ci    if (!strncmp(arg, "thread-", strlen("thread-"))) {
740800b99b8Sopenharmony_ci        return DoActionOnSubThread(arg + strlen("thread-"));
741800b99b8Sopenharmony_ci    }
742800b99b8Sopenharmony_ci#ifdef HAS_HITRACE
743800b99b8Sopenharmony_ci    auto beginId = HiTraceChain::Begin("test", HITRACE_FLAG_NO_BE_INFO);
744800b99b8Sopenharmony_ci#endif
745800b99b8Sopenharmony_ci    std::istringstream str(arg);
746800b99b8Sopenharmony_ci    std::string out;
747800b99b8Sopenharmony_ci    str >> out;
748800b99b8Sopenharmony_ci    // Actions
749800b99b8Sopenharmony_ci    for (auto& item : CMDLINE_TABLE) {
750800b99b8Sopenharmony_ci        if (!strcasecmp(out.c_str(), item.cmdline)) {
751800b99b8Sopenharmony_ci            return item.func();
752800b99b8Sopenharmony_ci        }
753800b99b8Sopenharmony_ci    }
754800b99b8Sopenharmony_ci    for (auto& item : CMDLINE_TABLE_PARAM) {
755800b99b8Sopenharmony_ci        if (!strcasecmp(out.c_str(), item.cmdline)) {
756800b99b8Sopenharmony_ci            if (str >> out) {
757800b99b8Sopenharmony_ci                return item.func(out);
758800b99b8Sopenharmony_ci            }
759800b99b8Sopenharmony_ci        }
760800b99b8Sopenharmony_ci    }
761800b99b8Sopenharmony_ci#ifdef HAS_HITRACE
762800b99b8Sopenharmony_ci    HiTraceChain::End(beginId);
763800b99b8Sopenharmony_ci#endif
764800b99b8Sopenharmony_ci    return 0;
765800b99b8Sopenharmony_ci}
766800b99b8Sopenharmony_ci
767800b99b8Sopenharmony_ciNOINLINE int TestFunc70()
768800b99b8Sopenharmony_ci{
769800b99b8Sopenharmony_ci    raise(SIGSEGV);
770800b99b8Sopenharmony_ci    return 0;
771800b99b8Sopenharmony_ci}
772800b99b8Sopenharmony_ci
773800b99b8Sopenharmony_ciint main(int argc, char *argv[])
774800b99b8Sopenharmony_ci{
775800b99b8Sopenharmony_ci    DfxCrasher::GetInstance().PrintUsage();
776800b99b8Sopenharmony_ci    if (argc <= 1) {
777800b99b8Sopenharmony_ci        std::cout << "wrong usage!";
778800b99b8Sopenharmony_ci        DfxCrasher::GetInstance().PrintUsage();
779800b99b8Sopenharmony_ci        return 0;
780800b99b8Sopenharmony_ci    }
781800b99b8Sopenharmony_ci
782800b99b8Sopenharmony_ci    std::cout << "ParseAndDoCrash done:" << DfxCrasher::GetInstance().ParseAndDoCrash(argv[1]) << "!\n";
783800b99b8Sopenharmony_ci    return 0;
784800b99b8Sopenharmony_ci}
785800b99b8Sopenharmony_ci
786800b99b8Sopenharmony_ci// auto gen function
787800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(0, 1)
788800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(1, 2)
789800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(2, 3)
790800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(3, 4)
791800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(4, 5)
792800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(5, 6)
793800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(6, 7)
794800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(7, 8)
795800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(8, 9)
796800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(9, 10)
797800b99b8Sopenharmony_ci
798800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(10, 11)
799800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(11, 12)
800800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(12, 13)
801800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(13, 14)
802800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(14, 15)
803800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(15, 16)
804800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(16, 17)
805800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(17, 18)
806800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(18, 19)
807800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(19, 20)
808800b99b8Sopenharmony_ci
809800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(20, 21)
810800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(21, 22)
811800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(22, 23)
812800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(23, 24)
813800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(24, 25)
814800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(25, 26)
815800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(26, 27)
816800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(27, 28)
817800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(28, 29)
818800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(29, 30)
819800b99b8Sopenharmony_ci
820800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(30, 31)
821800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(31, 32)
822800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(32, 33)
823800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(33, 34)
824800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(34, 35)
825800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(35, 36)
826800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(36, 37)
827800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(37, 38)
828800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(38, 39)
829800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(39, 40)
830800b99b8Sopenharmony_ci
831800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(40, 41)
832800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(41, 42)
833800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(42, 43)
834800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(43, 44)
835800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(44, 45)
836800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(45, 46)
837800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(46, 47)
838800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(47, 48)
839800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(48, 49)
840800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(49, 50)
841800b99b8Sopenharmony_ci
842800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(50, 51)
843800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(51, 52)
844800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(52, 53)
845800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(53, 54)
846800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(54, 55)
847800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(55, 56)
848800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(56, 57)
849800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(57, 58)
850800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(58, 59)
851800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(59, 60)
852800b99b8Sopenharmony_ci
853800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(60, 61)
854800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(61, 62)
855800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(62, 63)
856800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(63, 64)
857800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(64, 65)
858800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(65, 66)
859800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(66, 67)
860800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(67, 68)
861800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(68, 69)
862800b99b8Sopenharmony_ciGEN_TEST_FUNCTION(69, 70)
863