1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 2022-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 <gtest/gtest.h> 17800b99b8Sopenharmony_ci#include <csignal> 18800b99b8Sopenharmony_ci#include <map> 19800b99b8Sopenharmony_ci#include <securec.h> 20800b99b8Sopenharmony_ci#include <string> 21800b99b8Sopenharmony_ci#include <thread> 22800b99b8Sopenharmony_ci#include <unistd.h> 23800b99b8Sopenharmony_ci#include <vector> 24800b99b8Sopenharmony_ci#include <sys/prctl.h> 25800b99b8Sopenharmony_ci 26800b99b8Sopenharmony_ci#include "dfx_define.h" 27800b99b8Sopenharmony_ci#include "dfx_signal_handler.h" 28800b99b8Sopenharmony_ci#include "dfx_signalhandler_exception.h" 29800b99b8Sopenharmony_ci#include "dfx_test_util.h" 30800b99b8Sopenharmony_ci 31800b99b8Sopenharmony_ciusing namespace testing; 32800b99b8Sopenharmony_ciusing namespace testing::ext; 33800b99b8Sopenharmony_ciusing namespace std; 34800b99b8Sopenharmony_ci 35800b99b8Sopenharmony_cinamespace OHOS { 36800b99b8Sopenharmony_cinamespace HiviewDFX { 37800b99b8Sopenharmony_ciclass SignalHandlerTest : public testing::Test { 38800b99b8Sopenharmony_cipublic: 39800b99b8Sopenharmony_ci static void SetUpTestCase(); 40800b99b8Sopenharmony_ci static void TearDownTestCase(); 41800b99b8Sopenharmony_ci void SetUp(); 42800b99b8Sopenharmony_ci void TearDown(); 43800b99b8Sopenharmony_ci}; 44800b99b8Sopenharmony_ci 45800b99b8Sopenharmony_civoid SignalHandlerTest::SetUpTestCase() 46800b99b8Sopenharmony_ci{} 47800b99b8Sopenharmony_ci 48800b99b8Sopenharmony_civoid SignalHandlerTest::TearDownTestCase() 49800b99b8Sopenharmony_ci{} 50800b99b8Sopenharmony_ci 51800b99b8Sopenharmony_civoid SignalHandlerTest::SetUp() 52800b99b8Sopenharmony_ci{} 53800b99b8Sopenharmony_ci 54800b99b8Sopenharmony_civoid SignalHandlerTest::TearDown() 55800b99b8Sopenharmony_ci{} 56800b99b8Sopenharmony_ci 57800b99b8Sopenharmony_ciextern "C" void SetThreadInfoCallback(ThreadInfoCallBack func) __attribute__((weak)); 58800b99b8Sopenharmony_ciextern "C" void DFX_InstallSignalHandler(void) __attribute__((weak)); 59800b99b8Sopenharmony_ciextern "C" void SetAsyncStackCallbackFunc(void* func) __attribute__((weak)); 60800b99b8Sopenharmony_ciextern "C" int DFX_SetAppRunningUniqueId(const char* appRunningId, size_t len) __attribute__((weak)); 61800b99b8Sopenharmony_cistatic bool CheckThreadCrashKeyWords(const string& filePath, pid_t pid, int sig) 62800b99b8Sopenharmony_ci{ 63800b99b8Sopenharmony_ci if (filePath.empty() || pid <= 0) { 64800b99b8Sopenharmony_ci return false; 65800b99b8Sopenharmony_ci } 66800b99b8Sopenharmony_ci map<int, string> sigKey = { 67800b99b8Sopenharmony_ci { SIGILL, string("SIGILL") }, 68800b99b8Sopenharmony_ci { SIGBUS, string("SIGBUS") }, 69800b99b8Sopenharmony_ci { SIGSEGV, string("SIGSEGV") }, 70800b99b8Sopenharmony_ci }; 71800b99b8Sopenharmony_ci string sigKeyword = ""; 72800b99b8Sopenharmony_ci map<int, string>::iterator iter = sigKey.find(sig); 73800b99b8Sopenharmony_ci if (iter != sigKey.end()) { 74800b99b8Sopenharmony_ci sigKeyword = iter->second; 75800b99b8Sopenharmony_ci } 76800b99b8Sopenharmony_ci string keywords[] = { 77800b99b8Sopenharmony_ci "Pid:" + to_string(pid), "Uid:", "name:./test_signalhandler", sigKeyword, 78800b99b8Sopenharmony_ci "Tid:", "#00", "Registers:", "FaultStack:", "Maps:", "test_signalhandler" 79800b99b8Sopenharmony_ci }; 80800b99b8Sopenharmony_ci int length = sizeof(keywords) / sizeof(keywords[0]); 81800b99b8Sopenharmony_ci int minRegIdx = -1; 82800b99b8Sopenharmony_ci return CheckKeyWords(filePath, keywords, length, minRegIdx) == length; 83800b99b8Sopenharmony_ci} 84800b99b8Sopenharmony_cistatic bool CheckCrashKeyWords(const string& filePath, pid_t pid, int sig) 85800b99b8Sopenharmony_ci{ 86800b99b8Sopenharmony_ci if (filePath.empty() || pid <= 0) { 87800b99b8Sopenharmony_ci return false; 88800b99b8Sopenharmony_ci } 89800b99b8Sopenharmony_ci map<int, string> sigKey = { 90800b99b8Sopenharmony_ci { SIGILL, string("SIGILL") }, 91800b99b8Sopenharmony_ci { SIGBUS, string("SIGBUS") }, 92800b99b8Sopenharmony_ci { SIGSEGV, string("SIGSEGV") }, 93800b99b8Sopenharmony_ci { SIGABRT, string("SIGABRT") }, 94800b99b8Sopenharmony_ci { SIGFPE, string("SIGFPE") }, 95800b99b8Sopenharmony_ci { SIGSTKFLT, string("SIGSTKFLT") }, 96800b99b8Sopenharmony_ci { SIGSYS, string("SIGSYS") }, 97800b99b8Sopenharmony_ci { SIGTRAP, string("SIGTRAP") }, 98800b99b8Sopenharmony_ci }; 99800b99b8Sopenharmony_ci string sigKeyword = ""; 100800b99b8Sopenharmony_ci map<int, string>::iterator iter = sigKey.find(sig); 101800b99b8Sopenharmony_ci if (iter != sigKey.end()) { 102800b99b8Sopenharmony_ci sigKeyword = iter->second; 103800b99b8Sopenharmony_ci } 104800b99b8Sopenharmony_ci string keywords[] = { 105800b99b8Sopenharmony_ci "Pid:" + to_string(pid), "Uid:", "name:./test_signalhandler", sigKeyword, 106800b99b8Sopenharmony_ci "Tid:", "#00", "Registers:", "FaultStack:", "Maps:", "test_signalhandler" 107800b99b8Sopenharmony_ci }; 108800b99b8Sopenharmony_ci int length = sizeof(keywords) / sizeof(keywords[0]); 109800b99b8Sopenharmony_ci int minRegIdx = -1; 110800b99b8Sopenharmony_ci return CheckKeyWords(filePath, keywords, length, minRegIdx) == length; 111800b99b8Sopenharmony_ci} 112800b99b8Sopenharmony_ci 113800b99b8Sopenharmony_civoid ThreadInfo(char* buf, size_t len, void* context __attribute__((unused))) 114800b99b8Sopenharmony_ci{ 115800b99b8Sopenharmony_ci char mes[] = "this is cash information of test thread"; 116800b99b8Sopenharmony_ci if (memcpy_s(buf, len, mes, sizeof(mes)) != 0) { 117800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "Failed to set thread info"; 118800b99b8Sopenharmony_ci } 119800b99b8Sopenharmony_ci} 120800b99b8Sopenharmony_ci 121800b99b8Sopenharmony_ciint TestThread(int threadId, int sig) 122800b99b8Sopenharmony_ci{ 123800b99b8Sopenharmony_ci std::string subThreadName = "SubTestThread" + to_string(threadId); 124800b99b8Sopenharmony_ci prctl(PR_SET_NAME, subThreadName.c_str()); 125800b99b8Sopenharmony_ci if (SetThreadInfoCallback != nullptr) { 126800b99b8Sopenharmony_ci SetThreadInfoCallback(ThreadInfo); 127800b99b8Sopenharmony_ci } 128800b99b8Sopenharmony_ci int cashThreadId = 2; 129800b99b8Sopenharmony_ci if (threadId == cashThreadId) { 130800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << subThreadName << " is ready to raise signo(" << sig <<")"; 131800b99b8Sopenharmony_ci raise(sig); 132800b99b8Sopenharmony_ci } 133800b99b8Sopenharmony_ci return 0; 134800b99b8Sopenharmony_ci} 135800b99b8Sopenharmony_ci 136800b99b8Sopenharmony_ci/** 137800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest001 138800b99b8Sopenharmony_ci * @tc.desc: test thread cash SignalHandler signo(SIGILL) 139800b99b8Sopenharmony_ci * @tc.type: FUNC 140800b99b8Sopenharmony_ci */ 141800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest001, TestSize.Level2) 142800b99b8Sopenharmony_ci{ 143800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest001: start."; 144800b99b8Sopenharmony_ci pid_t pid = fork(); 145800b99b8Sopenharmony_ci if (pid < 0) { 146800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 147800b99b8Sopenharmony_ci } else if (pid == 0) { 148800b99b8Sopenharmony_ci if (SetThreadInfoCallback != nullptr) { 149800b99b8Sopenharmony_ci SetThreadInfoCallback(ThreadInfo); 150800b99b8Sopenharmony_ci } 151800b99b8Sopenharmony_ci sleep(1); 152800b99b8Sopenharmony_ci } else { 153800b99b8Sopenharmony_ci usleep(10000); // 10000 : sleep 10ms 154800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "process(" << getpid() << ") is ready to kill process(" << pid << ")"; 155800b99b8Sopenharmony_ci kill(pid, SIGILL); 156800b99b8Sopenharmony_ci sleep(2); // 2 : wait for cppcrash generating 157800b99b8Sopenharmony_ci bool ret = CheckThreadCrashKeyWords(GetCppCrashFileName(pid), pid, SIGILL); 158800b99b8Sopenharmony_ci ASSERT_TRUE(ret); 159800b99b8Sopenharmony_ci } 160800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest001: end."; 161800b99b8Sopenharmony_ci} 162800b99b8Sopenharmony_ci 163800b99b8Sopenharmony_ci/** 164800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest002 165800b99b8Sopenharmony_ci * @tc.desc: test thread cash SignalHandler signo(SIGBUS) 166800b99b8Sopenharmony_ci * @tc.type: FUNC 167800b99b8Sopenharmony_ci */ 168800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest002, TestSize.Level2) 169800b99b8Sopenharmony_ci{ 170800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest002: start."; 171800b99b8Sopenharmony_ci pid_t pid = fork(); 172800b99b8Sopenharmony_ci if (pid < 0) { 173800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 174800b99b8Sopenharmony_ci } else if (pid == 0) { 175800b99b8Sopenharmony_ci if (SetThreadInfoCallback != nullptr) { 176800b99b8Sopenharmony_ci SetThreadInfoCallback(ThreadInfo); 177800b99b8Sopenharmony_ci } 178800b99b8Sopenharmony_ci sleep(1); 179800b99b8Sopenharmony_ci } else { 180800b99b8Sopenharmony_ci usleep(10000); // 10000 : sleep 10ms 181800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "process(" << getpid() << ") is ready to kill process(" << pid << ")"; 182800b99b8Sopenharmony_ci kill(pid, SIGBUS); 183800b99b8Sopenharmony_ci sleep(2); // 2 : wait for cppcrash generating 184800b99b8Sopenharmony_ci bool ret = CheckThreadCrashKeyWords(GetCppCrashFileName(pid), pid, SIGBUS); 185800b99b8Sopenharmony_ci ASSERT_TRUE(ret); 186800b99b8Sopenharmony_ci } 187800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest002: end."; 188800b99b8Sopenharmony_ci} 189800b99b8Sopenharmony_ci 190800b99b8Sopenharmony_ci/** 191800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest003 192800b99b8Sopenharmony_ci * @tc.desc: test thread cash SignalHandler signo(SIGSEGV) 193800b99b8Sopenharmony_ci * @tc.type: FUNC 194800b99b8Sopenharmony_ci */ 195800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest003, TestSize.Level2) 196800b99b8Sopenharmony_ci{ 197800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest003: start."; 198800b99b8Sopenharmony_ci pid_t pid = fork(); 199800b99b8Sopenharmony_ci if (pid < 0) { 200800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 201800b99b8Sopenharmony_ci } else if (pid == 0) { 202800b99b8Sopenharmony_ci if (SetThreadInfoCallback != nullptr) { 203800b99b8Sopenharmony_ci SetThreadInfoCallback(ThreadInfo); 204800b99b8Sopenharmony_ci } 205800b99b8Sopenharmony_ci sleep(1); 206800b99b8Sopenharmony_ci } else { 207800b99b8Sopenharmony_ci usleep(10000); // 10000 : sleep 10ms 208800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "process(" << getpid() << ") is ready to kill process(" << pid << ")"; 209800b99b8Sopenharmony_ci kill(pid, SIGSEGV); 210800b99b8Sopenharmony_ci sleep(2); // 2 : wait for cppcrash generating 211800b99b8Sopenharmony_ci bool ret = CheckThreadCrashKeyWords(GetCppCrashFileName(pid), pid, SIGSEGV); 212800b99b8Sopenharmony_ci ASSERT_TRUE(ret); 213800b99b8Sopenharmony_ci } 214800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest003: end."; 215800b99b8Sopenharmony_ci} 216800b99b8Sopenharmony_ci 217800b99b8Sopenharmony_ci/** 218800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest004 219800b99b8Sopenharmony_ci * @tc.desc: test thread crash SignalHandler in multi-thread situation signo(SIGILL) 220800b99b8Sopenharmony_ci * @tc.type: FUNC 221800b99b8Sopenharmony_ci */ 222800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest004, TestSize.Level2) 223800b99b8Sopenharmony_ci{ 224800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest004: start."; 225800b99b8Sopenharmony_ci pid_t pid = fork(); 226800b99b8Sopenharmony_ci if (pid < 0) { 227800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 228800b99b8Sopenharmony_ci } else if (pid == 0) { 229800b99b8Sopenharmony_ci std::thread (TestThread, 1, SIGILL).join(); // 1 : first thread 230800b99b8Sopenharmony_ci std::thread (TestThread, 2, SIGILL).join(); // 2 : second thread 231800b99b8Sopenharmony_ci _exit(0); 232800b99b8Sopenharmony_ci } else { 233800b99b8Sopenharmony_ci sleep(2); // 2 : wait for cppcrash generating 234800b99b8Sopenharmony_ci bool ret = CheckThreadCrashKeyWords(GetCppCrashFileName(pid), pid, SIGILL); 235800b99b8Sopenharmony_ci ASSERT_TRUE(ret); 236800b99b8Sopenharmony_ci } 237800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest004: end."; 238800b99b8Sopenharmony_ci} 239800b99b8Sopenharmony_ci 240800b99b8Sopenharmony_ci/** 241800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest005 242800b99b8Sopenharmony_ci * @tc.desc: test thread crash SignalHandler in multi-thread situation signo(SIGBUS) 243800b99b8Sopenharmony_ci * @tc.type: FUNC 244800b99b8Sopenharmony_ci */ 245800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest005, TestSize.Level2) 246800b99b8Sopenharmony_ci{ 247800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest005: start."; 248800b99b8Sopenharmony_ci pid_t pid = fork(); 249800b99b8Sopenharmony_ci if (pid < 0) { 250800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 251800b99b8Sopenharmony_ci } else if (pid == 0) { 252800b99b8Sopenharmony_ci std::thread (TestThread, 1, SIGBUS).join(); // 1 : first thread 253800b99b8Sopenharmony_ci std::thread (TestThread, 2, SIGBUS).join(); // 2 : second thread 254800b99b8Sopenharmony_ci _exit(0); 255800b99b8Sopenharmony_ci } else { 256800b99b8Sopenharmony_ci sleep(2); // 2 : wait for cppcrash generating 257800b99b8Sopenharmony_ci bool ret = CheckThreadCrashKeyWords(GetCppCrashFileName(pid), pid, SIGBUS); 258800b99b8Sopenharmony_ci ASSERT_TRUE(ret); 259800b99b8Sopenharmony_ci } 260800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest005: end."; 261800b99b8Sopenharmony_ci} 262800b99b8Sopenharmony_ci 263800b99b8Sopenharmony_ci/** 264800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest006 265800b99b8Sopenharmony_ci * @tc.desc: test thread crash SignalHandler in multi-thread situation signo(SIGSEGV) 266800b99b8Sopenharmony_ci * @tc.type: FUNC 267800b99b8Sopenharmony_ci */ 268800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest006, TestSize.Level2) 269800b99b8Sopenharmony_ci{ 270800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest006: start."; 271800b99b8Sopenharmony_ci pid_t pid = fork(); 272800b99b8Sopenharmony_ci if (pid < 0) { 273800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 274800b99b8Sopenharmony_ci } else if (pid == 0) { 275800b99b8Sopenharmony_ci std::thread (TestThread, 1, SIGSEGV).join(); // 1 : first thread 276800b99b8Sopenharmony_ci std::thread (TestThread, 2, SIGSEGV).join(); // 2 : second thread 277800b99b8Sopenharmony_ci _exit(0); 278800b99b8Sopenharmony_ci } else { 279800b99b8Sopenharmony_ci sleep(2); // 2 : wait for cppcrash generating 280800b99b8Sopenharmony_ci bool ret = CheckThreadCrashKeyWords(GetCppCrashFileName(pid), pid, SIGSEGV); 281800b99b8Sopenharmony_ci ASSERT_TRUE(ret); 282800b99b8Sopenharmony_ci } 283800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest006: end."; 284800b99b8Sopenharmony_ci} 285800b99b8Sopenharmony_ci 286800b99b8Sopenharmony_ci/** 287800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest007 288800b99b8Sopenharmony_ci * @tc.desc: test DFX_InstallSignalHandler interface 289800b99b8Sopenharmony_ci * @tc.type: FUNC 290800b99b8Sopenharmony_ci */ 291800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest007, TestSize.Level2) 292800b99b8Sopenharmony_ci{ 293800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest007: start."; 294800b99b8Sopenharmony_ci int interestedSignalList[] = { 295800b99b8Sopenharmony_ci SIGABRT, SIGBUS, SIGFPE, 296800b99b8Sopenharmony_ci SIGSEGV, SIGSTKFLT, SIGSYS, SIGTRAP 297800b99b8Sopenharmony_ci }; 298800b99b8Sopenharmony_ci for (int sig : interestedSignalList) { 299800b99b8Sopenharmony_ci pid_t pid = fork(); 300800b99b8Sopenharmony_ci if (pid < 0) { 301800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 302800b99b8Sopenharmony_ci } else if (pid == 0) { 303800b99b8Sopenharmony_ci if (DFX_InstallSignalHandler != nullptr) { 304800b99b8Sopenharmony_ci DFX_InstallSignalHandler(); 305800b99b8Sopenharmony_ci } 306800b99b8Sopenharmony_ci sleep(1); 307800b99b8Sopenharmony_ci } else { 308800b99b8Sopenharmony_ci usleep(10000); // 10000 : sleep 10ms 309800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "process(" << getpid() << ") is ready to kill << process(" << pid << ")"; 310800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "signal:" << sig; 311800b99b8Sopenharmony_ci kill(pid, sig); 312800b99b8Sopenharmony_ci sleep(2); // 2 : wait for cppcrash generating 313800b99b8Sopenharmony_ci bool ret = CheckCrashKeyWords(GetCppCrashFileName(pid), pid, sig); 314800b99b8Sopenharmony_ci ASSERT_TRUE(ret); 315800b99b8Sopenharmony_ci } 316800b99b8Sopenharmony_ci } 317800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest007: end."; 318800b99b8Sopenharmony_ci} 319800b99b8Sopenharmony_ci 320800b99b8Sopenharmony_ciint TestThread2(int threadId, int sig, int total, bool exitEarly) 321800b99b8Sopenharmony_ci{ 322800b99b8Sopenharmony_ci std::string subThreadName = "SubTestThread" + to_string(threadId); 323800b99b8Sopenharmony_ci prctl(PR_SET_NAME, subThreadName.c_str()); 324800b99b8Sopenharmony_ci if (SetThreadInfoCallback != nullptr) { 325800b99b8Sopenharmony_ci SetThreadInfoCallback(ThreadInfo); 326800b99b8Sopenharmony_ci } 327800b99b8Sopenharmony_ci if (threadId == total - 1) { 328800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << subThreadName << " is ready to raise signo(" << sig <<")"; 329800b99b8Sopenharmony_ci raise(sig); 330800b99b8Sopenharmony_ci } 331800b99b8Sopenharmony_ci 332800b99b8Sopenharmony_ci if (!exitEarly) { 333800b99b8Sopenharmony_ci sleep(total - threadId); 334800b99b8Sopenharmony_ci } 335800b99b8Sopenharmony_ci if (SetThreadInfoCallback != nullptr) { 336800b99b8Sopenharmony_ci SetThreadInfoCallback(ThreadInfo); 337800b99b8Sopenharmony_ci } 338800b99b8Sopenharmony_ci return 0; 339800b99b8Sopenharmony_ci} 340800b99b8Sopenharmony_ci 341800b99b8Sopenharmony_ci/** 342800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest008 343800b99b8Sopenharmony_ci * @tc.desc: test add 36 thread info callback and crash thread has no callback 344800b99b8Sopenharmony_ci * @tc.type: FUNC 345800b99b8Sopenharmony_ci */ 346800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest008, TestSize.Level2) 347800b99b8Sopenharmony_ci{ 348800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest008: start."; 349800b99b8Sopenharmony_ci pid_t pid = fork(); 350800b99b8Sopenharmony_ci if (pid < 0) { 351800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 352800b99b8Sopenharmony_ci } else if (pid == 0) { 353800b99b8Sopenharmony_ci std::vector<std::thread> threads; 354800b99b8Sopenharmony_ci const int testThreadCount = 36; 355800b99b8Sopenharmony_ci for (int i = 0; i < testThreadCount; i++) { 356800b99b8Sopenharmony_ci threads.push_back(std::thread(TestThread2, i, SIGSEGV, testThreadCount, false)); 357800b99b8Sopenharmony_ci } 358800b99b8Sopenharmony_ci 359800b99b8Sopenharmony_ci for (auto& thread : threads) { 360800b99b8Sopenharmony_ci thread.join(); 361800b99b8Sopenharmony_ci } 362800b99b8Sopenharmony_ci _exit(0); 363800b99b8Sopenharmony_ci } else { 364800b99b8Sopenharmony_ci sleep(2); // 2 : wait for cppcrash generating 365800b99b8Sopenharmony_ci auto file = GetCppCrashFileName(pid); 366800b99b8Sopenharmony_ci ASSERT_FALSE(file.empty()); 367800b99b8Sopenharmony_ci } 368800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest008: end."; 369800b99b8Sopenharmony_ci} 370800b99b8Sopenharmony_ci 371800b99b8Sopenharmony_ci/** 372800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest009 373800b99b8Sopenharmony_ci * @tc.desc: test add 36 thread info callback and crash thread has the callback 374800b99b8Sopenharmony_ci * @tc.type: FUNC 375800b99b8Sopenharmony_ci */ 376800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest009, TestSize.Level2) 377800b99b8Sopenharmony_ci{ 378800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest009: start."; 379800b99b8Sopenharmony_ci pid_t pid = fork(); 380800b99b8Sopenharmony_ci if (pid < 0) { 381800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 382800b99b8Sopenharmony_ci } else if (pid == 0) { 383800b99b8Sopenharmony_ci std::vector<std::thread> threads; 384800b99b8Sopenharmony_ci const int testThreadCount = 36; 385800b99b8Sopenharmony_ci for (int i = 0; i < testThreadCount; i++) { 386800b99b8Sopenharmony_ci bool exitEarly = false; 387800b99b8Sopenharmony_ci if (i % 2 == 0) { 388800b99b8Sopenharmony_ci exitEarly = true; 389800b99b8Sopenharmony_ci } 390800b99b8Sopenharmony_ci threads.push_back(std::thread (TestThread2, i, SIGSEGV, testThreadCount, exitEarly)); 391800b99b8Sopenharmony_ci } 392800b99b8Sopenharmony_ci 393800b99b8Sopenharmony_ci for (auto& thread : threads) { 394800b99b8Sopenharmony_ci thread.join(); 395800b99b8Sopenharmony_ci } 396800b99b8Sopenharmony_ci _exit(0); 397800b99b8Sopenharmony_ci } else { 398800b99b8Sopenharmony_ci sleep(2); // 2 : wait for cppcrash generating 399800b99b8Sopenharmony_ci auto file = GetCppCrashFileName(pid); 400800b99b8Sopenharmony_ci ASSERT_FALSE(file.empty()); 401800b99b8Sopenharmony_ci } 402800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest009: end."; 403800b99b8Sopenharmony_ci} 404800b99b8Sopenharmony_ci 405800b99b8Sopenharmony_ci/** 406800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest010 407800b99b8Sopenharmony_ci * @tc.desc: test crash when free a invalid address 408800b99b8Sopenharmony_ci * @tc.type: FUNC 409800b99b8Sopenharmony_ci */ 410800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest010, TestSize.Level2) 411800b99b8Sopenharmony_ci{ 412800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest010: start."; 413800b99b8Sopenharmony_ci pid_t pid = fork(); 414800b99b8Sopenharmony_ci if (pid < 0) { 415800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 416800b99b8Sopenharmony_ci } else if (pid == 0) { 417800b99b8Sopenharmony_ci if (SetThreadInfoCallback != nullptr) { 418800b99b8Sopenharmony_ci SetThreadInfoCallback(ThreadInfo); 419800b99b8Sopenharmony_ci } 420800b99b8Sopenharmony_ci int32_t freeAddr = 0x111; 421800b99b8Sopenharmony_ci // trigger crash 422800b99b8Sopenharmony_ci free(reinterpret_cast<void*>(freeAddr)); 423800b99b8Sopenharmony_ci // force crash if not crash in free 424800b99b8Sopenharmony_ci abort(); 425800b99b8Sopenharmony_ci } else { 426800b99b8Sopenharmony_ci sleep(2); // 2 : wait for cppcrash generating 427800b99b8Sopenharmony_ci auto file = GetCppCrashFileName(pid); 428800b99b8Sopenharmony_ci ASSERT_FALSE(file.empty()); 429800b99b8Sopenharmony_ci } 430800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest010: end."; 431800b99b8Sopenharmony_ci} 432800b99b8Sopenharmony_ci 433800b99b8Sopenharmony_ci/** 434800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest011 435800b99b8Sopenharmony_ci * @tc.desc: test crash when realloc a invalid address 436800b99b8Sopenharmony_ci * @tc.type: FUNC 437800b99b8Sopenharmony_ci */ 438800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest011, TestSize.Level2) 439800b99b8Sopenharmony_ci{ 440800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest011: start."; 441800b99b8Sopenharmony_ci pid_t pid = fork(); 442800b99b8Sopenharmony_ci if (pid < 0) { 443800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 444800b99b8Sopenharmony_ci } else if (pid == 0) { 445800b99b8Sopenharmony_ci int32_t initAllocSz = 10; 446800b99b8Sopenharmony_ci int32_t reallocSz = 20; 447800b99b8Sopenharmony_ci if (SetThreadInfoCallback != nullptr) { 448800b99b8Sopenharmony_ci SetThreadInfoCallback(ThreadInfo); 449800b99b8Sopenharmony_ci } 450800b99b8Sopenharmony_ci // alloc a buffer 451800b99b8Sopenharmony_ci int8_t* addr = reinterpret_cast<int8_t*>(malloc(initAllocSz)); 452800b99b8Sopenharmony_ci // overwrite the control block 453800b99b8Sopenharmony_ci int8_t* newAddr = addr - initAllocSz; 454800b99b8Sopenharmony_ci (void)memset_s(newAddr, initAllocSz, 0, initAllocSz); 455800b99b8Sopenharmony_ci addr = reinterpret_cast<int8_t*>(realloc(reinterpret_cast<void*>(addr), reallocSz)); 456800b99b8Sopenharmony_ci free(addr); 457800b99b8Sopenharmony_ci // force crash if not crash in realloc 458800b99b8Sopenharmony_ci abort(); 459800b99b8Sopenharmony_ci } else { 460800b99b8Sopenharmony_ci sleep(2); // 2 : wait for cppcrash generating 461800b99b8Sopenharmony_ci auto file = GetCppCrashFileName(pid); 462800b99b8Sopenharmony_ci ASSERT_FALSE(file.empty()); 463800b99b8Sopenharmony_ci } 464800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest011: end."; 465800b99b8Sopenharmony_ci} 466800b99b8Sopenharmony_ci 467800b99b8Sopenharmony_ci/** 468800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest012 469800b99b8Sopenharmony_ci * @tc.desc: test crash when realloc a invalid address without threadInfo callback 470800b99b8Sopenharmony_ci * @tc.type: FUNC 471800b99b8Sopenharmony_ci */ 472800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest012, TestSize.Level2) 473800b99b8Sopenharmony_ci{ 474800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest012: start."; 475800b99b8Sopenharmony_ci pid_t pid = fork(); 476800b99b8Sopenharmony_ci if (pid < 0) { 477800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 478800b99b8Sopenharmony_ci } else if (pid == 0) { 479800b99b8Sopenharmony_ci int32_t initAllocSz = 10; 480800b99b8Sopenharmony_ci int32_t reallocSz = 20; 481800b99b8Sopenharmony_ci // alloc a buffer 482800b99b8Sopenharmony_ci int8_t* addr = reinterpret_cast<int8_t*>(malloc(initAllocSz)); 483800b99b8Sopenharmony_ci // overwrite the control block 484800b99b8Sopenharmony_ci int8_t* newAddr = addr - initAllocSz; 485800b99b8Sopenharmony_ci (void)memset_s(newAddr, initAllocSz, 0, initAllocSz); 486800b99b8Sopenharmony_ci addr = reinterpret_cast<int8_t*>(realloc(reinterpret_cast<void*>(addr), reallocSz)); 487800b99b8Sopenharmony_ci free(addr); 488800b99b8Sopenharmony_ci // force crash if not crash in realloc 489800b99b8Sopenharmony_ci abort(); 490800b99b8Sopenharmony_ci } else { 491800b99b8Sopenharmony_ci sleep(2); // 2 : wait for cppcrash generating 492800b99b8Sopenharmony_ci auto file = GetCppCrashFileName(pid); 493800b99b8Sopenharmony_ci ASSERT_FALSE(file.empty()); 494800b99b8Sopenharmony_ci } 495800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest012: end."; 496800b99b8Sopenharmony_ci} 497800b99b8Sopenharmony_ci 498800b99b8Sopenharmony_ci/** 499800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest013 500800b99b8Sopenharmony_ci * @tc.desc: test add 100 thread info callback and do nothing 501800b99b8Sopenharmony_ci * @tc.type: FUNC 502800b99b8Sopenharmony_ci */ 503800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest013, TestSize.Level2) 504800b99b8Sopenharmony_ci{ 505800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest013: start."; 506800b99b8Sopenharmony_ci std::vector<std::thread> threads; 507800b99b8Sopenharmony_ci const int testThreadCount = 100; 508800b99b8Sopenharmony_ci for (int i = 0; i < testThreadCount - 1; i++) { 509800b99b8Sopenharmony_ci threads.push_back(std::thread (TestThread2, i, SIGSEGV, testThreadCount, true)); 510800b99b8Sopenharmony_ci } 511800b99b8Sopenharmony_ci 512800b99b8Sopenharmony_ci for (auto& thread : threads) { 513800b99b8Sopenharmony_ci if (thread.joinable()) { 514800b99b8Sopenharmony_ci thread.join(); 515800b99b8Sopenharmony_ci } 516800b99b8Sopenharmony_ci } 517800b99b8Sopenharmony_ci auto file = GetCppCrashFileName(getpid()); 518800b99b8Sopenharmony_ci ASSERT_TRUE(file.empty()); 519800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest013: end."; 520800b99b8Sopenharmony_ci} 521800b99b8Sopenharmony_ci 522800b99b8Sopenharmony_civoid TestCallbackFunc() 523800b99b8Sopenharmony_ci{} 524800b99b8Sopenharmony_ci 525800b99b8Sopenharmony_ci/** 526800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest015 527800b99b8Sopenharmony_ci * @tc.desc: test DFX_SetAppRunningUniqueId 528800b99b8Sopenharmony_ci * @tc.type: FUNC 529800b99b8Sopenharmony_ci */ 530800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest015, TestSize.Level2) 531800b99b8Sopenharmony_ci{ 532800b99b8Sopenharmony_ci bool isSuccess = DFX_SetAppRunningUniqueId != nullptr; 533800b99b8Sopenharmony_ci if (!isSuccess) { 534800b99b8Sopenharmony_ci ASSERT_FALSE(isSuccess); 535800b99b8Sopenharmony_ci return; 536800b99b8Sopenharmony_ci } 537800b99b8Sopenharmony_ci /** 538800b99b8Sopenharmony_ci * @tc.steps: step1. 539800b99b8Sopenharmony_ci * case: appRunningId == nullptr, len= 0 540800b99b8Sopenharmony_ci * @tc.expected: ret == -1 541800b99b8Sopenharmony_ci * */ 542800b99b8Sopenharmony_ci int ret = DFX_SetAppRunningUniqueId(nullptr, 0); 543800b99b8Sopenharmony_ci ASSERT_EQ(ret, -1); 544800b99b8Sopenharmony_ci 545800b99b8Sopenharmony_ci /** 546800b99b8Sopenharmony_ci * @tc.steps: step2. 547800b99b8Sopenharmony_ci * case: appRunningId == nullptr, len= MAX_APP_RUNNING_UNIQUE_ID_LEN 548800b99b8Sopenharmony_ci * @tc.expected: ret == -1 549800b99b8Sopenharmony_ci * */ 550800b99b8Sopenharmony_ci ret = DFX_SetAppRunningUniqueId(nullptr, MAX_APP_RUNNING_UNIQUE_ID_LEN); 551800b99b8Sopenharmony_ci ASSERT_EQ(ret, -1); 552800b99b8Sopenharmony_ci 553800b99b8Sopenharmony_ci /** 554800b99b8Sopenharmony_ci * @tc.steps: step3. 555800b99b8Sopenharmony_ci * case: appRunningId != nullptr, len= 0 556800b99b8Sopenharmony_ci * @tc.expected: ret == 0 557800b99b8Sopenharmony_ci * */ 558800b99b8Sopenharmony_ci constexpr char testId1[] = "App running unique test id"; 559800b99b8Sopenharmony_ci ret = DFX_SetAppRunningUniqueId(testId1, 0); 560800b99b8Sopenharmony_ci ASSERT_EQ(ret, 0); 561800b99b8Sopenharmony_ci 562800b99b8Sopenharmony_ci /** 563800b99b8Sopenharmony_ci * @tc.steps: step4. 564800b99b8Sopenharmony_ci * case: appRunningId != nullptr, len= strleng(appRunningId) 565800b99b8Sopenharmony_ci * @tc.expected: ret == 0 566800b99b8Sopenharmony_ci * */ 567800b99b8Sopenharmony_ci ret = DFX_SetAppRunningUniqueId(testId1, strlen(testId1)); 568800b99b8Sopenharmony_ci ASSERT_EQ(ret, 0); 569800b99b8Sopenharmony_ci 570800b99b8Sopenharmony_ci /** 571800b99b8Sopenharmony_ci * @tc.steps: step5. 572800b99b8Sopenharmony_ci * case: appRunningId != nullptr, len= MAX_APP_RUNNING_UNIQUE_ID_LEN + 1 573800b99b8Sopenharmony_ci * @tc.expected: ret == -1 574800b99b8Sopenharmony_ci * */ 575800b99b8Sopenharmony_ci constexpr size_t testLen = MAX_APP_RUNNING_UNIQUE_ID_LEN + 1; 576800b99b8Sopenharmony_ci ret = DFX_SetAppRunningUniqueId(testId1, testLen); 577800b99b8Sopenharmony_ci ASSERT_EQ(ret, -1); 578800b99b8Sopenharmony_ci 579800b99b8Sopenharmony_ci /** 580800b99b8Sopenharmony_ci * @tc.steps: step6. 581800b99b8Sopenharmony_ci * case: appRunningId != nullptr, len= MAX_APP_RUNNING_UNIQUE_ID_LEN 582800b99b8Sopenharmony_ci * @tc.expected: ret == 0 583800b99b8Sopenharmony_ci * */ 584800b99b8Sopenharmony_ci constexpr char testId2[MAX_APP_RUNNING_UNIQUE_ID_LEN] = "App running unique test id"; 585800b99b8Sopenharmony_ci ret = DFX_SetAppRunningUniqueId(testId2, MAX_APP_RUNNING_UNIQUE_ID_LEN); 586800b99b8Sopenharmony_ci ASSERT_EQ(ret, -1); 587800b99b8Sopenharmony_ci} 588800b99b8Sopenharmony_ci 589800b99b8Sopenharmony_ci/** 590800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest016 591800b99b8Sopenharmony_ci * @tc.desc: test ReportException 592800b99b8Sopenharmony_ci * @tc.type: FUNC 593800b99b8Sopenharmony_ci */ 594800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest016, TestSize.Level2) 595800b99b8Sopenharmony_ci{ 596800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest016: start."; 597800b99b8Sopenharmony_ci if (SetAsyncStackCallbackFunc != nullptr) { 598800b99b8Sopenharmony_ci SetAsyncStackCallbackFunc(reinterpret_cast<void*>(TestCallbackFunc)); 599800b99b8Sopenharmony_ci } 600800b99b8Sopenharmony_ci 601800b99b8Sopenharmony_ci struct CrashDumpException exception; 602800b99b8Sopenharmony_ci exception.pid = 1; 603800b99b8Sopenharmony_ci exception.uid = 1; 604800b99b8Sopenharmony_ci exception.error = CRASH_SIGNAL_EMASKED; 605800b99b8Sopenharmony_ci int ret = ReportException(exception); 606800b99b8Sopenharmony_ci ASSERT_NE(ret, -1); 607800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalHandlerTest016: end."; 608800b99b8Sopenharmony_ci} 609800b99b8Sopenharmony_ci} // namespace HiviewDFX 610800b99b8Sopenharmony_ci} // namepsace OHOS 611