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