1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 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 <sigchain.h> 18800b99b8Sopenharmony_ci 19800b99b8Sopenharmony_ci#include "dfx_define.h" 20800b99b8Sopenharmony_ci 21800b99b8Sopenharmony_ciusing namespace testing; 22800b99b8Sopenharmony_ciusing namespace testing::ext; 23800b99b8Sopenharmony_ciusing namespace std; 24800b99b8Sopenharmony_ci 25800b99b8Sopenharmony_cinamespace OHOS { 26800b99b8Sopenharmony_cinamespace HiviewDFX { 27800b99b8Sopenharmony_ciclass SignalChainTest : public testing::Test { 28800b99b8Sopenharmony_cipublic: 29800b99b8Sopenharmony_ci static void SetUpTestCase() {} 30800b99b8Sopenharmony_ci static void TearDownTestCase() {} 31800b99b8Sopenharmony_ci void SetUp() {} 32800b99b8Sopenharmony_ci void TearDown() {} 33800b99b8Sopenharmony_ci}; 34800b99b8Sopenharmony_ci 35800b99b8Sopenharmony_ci#define SIGCHIAN_TEST_SIGNAL_NUM_1 1 36800b99b8Sopenharmony_ci#define SIGCHIAN_TEST_SIGNAL_NUM_2 2 37800b99b8Sopenharmony_ci 38800b99b8Sopenharmony_cistatic const int TEST_PTR_VALUE = 10; 39800b99b8Sopenharmony_cistatic const int SLEEP_10_MS = 10000; 40800b99b8Sopenharmony_cistatic const int SLEEP_1000_MS = 1000000; 41800b99b8Sopenharmony_cistatic const int SLEEP_2000_MS = 2000000; 42800b99b8Sopenharmony_ci 43800b99b8Sopenharmony_cistatic int g_count = 0; 44800b99b8Sopenharmony_cistatic bool g_testLastFlag = false; 45800b99b8Sopenharmony_cistatic bool g_signalDumpFlag = false; 46800b99b8Sopenharmony_cistatic bool g_signalSegvFlag = false; 47800b99b8Sopenharmony_cistatic bool g_sigactionDumpFlag = false; 48800b99b8Sopenharmony_cistatic bool g_sigactionSegvFlag = false; 49800b99b8Sopenharmony_cistatic bool g_sigactionIllFlag = false; 50800b99b8Sopenharmony_cistatic bool g_sigchainDumpFlag = false; 51800b99b8Sopenharmony_cistatic bool g_sigchainDump1Flag = false; 52800b99b8Sopenharmony_cistatic bool g_sigchainDump2Flag = false; 53800b99b8Sopenharmony_cistatic bool g_sigchainSegvFlag = false; 54800b99b8Sopenharmony_cistatic bool g_sigchainSegv1Flag = false; 55800b99b8Sopenharmony_cistatic bool g_sigchainSegv2Flag = false; 56800b99b8Sopenharmony_ci 57800b99b8Sopenharmony_cistatic void ResetCount() 58800b99b8Sopenharmony_ci{ 59800b99b8Sopenharmony_ci g_count = 0; 60800b99b8Sopenharmony_ci g_testLastFlag = true; 61800b99b8Sopenharmony_ci} 62800b99b8Sopenharmony_ci 63800b99b8Sopenharmony_cistatic void SignalInit() 64800b99b8Sopenharmony_ci{ 65800b99b8Sopenharmony_ci g_testLastFlag = false; 66800b99b8Sopenharmony_ci g_signalDumpFlag = false; 67800b99b8Sopenharmony_ci g_signalSegvFlag = false; 68800b99b8Sopenharmony_ci g_sigactionDumpFlag = false; 69800b99b8Sopenharmony_ci g_sigactionSegvFlag = false; 70800b99b8Sopenharmony_ci g_sigactionIllFlag = false; 71800b99b8Sopenharmony_ci g_sigchainDumpFlag = false; 72800b99b8Sopenharmony_ci g_sigchainDump1Flag = false; 73800b99b8Sopenharmony_ci g_sigchainDump2Flag = false; 74800b99b8Sopenharmony_ci g_sigchainSegvFlag = false; 75800b99b8Sopenharmony_ci g_sigchainSegv1Flag = false; 76800b99b8Sopenharmony_ci g_sigchainSegv2Flag = false; 77800b99b8Sopenharmony_ci} 78800b99b8Sopenharmony_ci 79800b99b8Sopenharmony_ciAT_UNUSED static void SignalDumpHandler(int signo) 80800b99b8Sopenharmony_ci{ 81800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalDumpHandler"; 82800b99b8Sopenharmony_ci g_signalDumpFlag = true; 83800b99b8Sopenharmony_ci EXPECT_EQ(signo, SIGDUMP) << "SignalDumpHandler Failed"; 84800b99b8Sopenharmony_ci} 85800b99b8Sopenharmony_ci 86800b99b8Sopenharmony_ciAT_UNUSED static void SignalSegvHandler(int signo) 87800b99b8Sopenharmony_ci{ 88800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalSegvHandler"; 89800b99b8Sopenharmony_ci g_signalSegvFlag = true; 90800b99b8Sopenharmony_ci EXPECT_EQ(signo, SIGSEGV) << "SignalSegvHandler Failed"; 91800b99b8Sopenharmony_ci} 92800b99b8Sopenharmony_ci 93800b99b8Sopenharmony_ciAT_UNUSED static void SignalDumpSigaction(int signo) 94800b99b8Sopenharmony_ci{ 95800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalDumpSigaction"; 96800b99b8Sopenharmony_ci g_sigactionDumpFlag = true; 97800b99b8Sopenharmony_ci EXPECT_EQ(signo, SIGDUMP) << "SignalDumpSigaction Failed"; 98800b99b8Sopenharmony_ci} 99800b99b8Sopenharmony_ci 100800b99b8Sopenharmony_ciAT_UNUSED static void SignalSegvSigaction(int signo) 101800b99b8Sopenharmony_ci{ 102800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalSegvSigaction"; 103800b99b8Sopenharmony_ci g_sigactionSegvFlag = true; 104800b99b8Sopenharmony_ci EXPECT_EQ(signo, SIGSEGV) << "SignalSegvSigaction Failed"; 105800b99b8Sopenharmony_ci} 106800b99b8Sopenharmony_ci 107800b99b8Sopenharmony_ciAT_UNUSED static void SignalIllSigaction(int signo) 108800b99b8Sopenharmony_ci{ 109800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalIllSigaction"; 110800b99b8Sopenharmony_ci g_sigactionIllFlag = true; 111800b99b8Sopenharmony_ci EXPECT_EQ(signo, SIGILL) << "SignalIllSigaction Failed"; 112800b99b8Sopenharmony_ci} 113800b99b8Sopenharmony_ci 114800b99b8Sopenharmony_ciAT_UNUSED static bool SigchainSpecialHandlerDumpTrue(int signo, siginfo_t *si, void *ucontext) 115800b99b8Sopenharmony_ci{ 116800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SigchainSpecialHandlerDumpTrue"; 117800b99b8Sopenharmony_ci g_sigchainDumpFlag = true; 118800b99b8Sopenharmony_ci EXPECT_EQ(signo, SIGDUMP) << "SigchainSpecialHandlerDumpTrue Failed"; 119800b99b8Sopenharmony_ci if (g_testLastFlag) { 120800b99b8Sopenharmony_ci g_count++; 121800b99b8Sopenharmony_ci EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SigchainSpecialHandlerDumpTrue: g_count."; 122800b99b8Sopenharmony_ci } 123800b99b8Sopenharmony_ci return true; 124800b99b8Sopenharmony_ci} 125800b99b8Sopenharmony_ci 126800b99b8Sopenharmony_ciAT_UNUSED static bool SigchainSpecialHandlerDump1(int signo, siginfo_t *si, void *ucontext) 127800b99b8Sopenharmony_ci{ 128800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SigchainSpecialHandlerDump1"; 129800b99b8Sopenharmony_ci g_sigchainDump1Flag = true; 130800b99b8Sopenharmony_ci EXPECT_EQ(signo, SIGDUMP) << "SigchainSpecialHandlerDump1 Failed"; 131800b99b8Sopenharmony_ci if (g_testLastFlag) { 132800b99b8Sopenharmony_ci g_count++; 133800b99b8Sopenharmony_ci EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_1) << "SigchainSpecialHandlerDump1: g_count."; 134800b99b8Sopenharmony_ci } 135800b99b8Sopenharmony_ci return false; 136800b99b8Sopenharmony_ci} 137800b99b8Sopenharmony_ci 138800b99b8Sopenharmony_ciAT_UNUSED static bool SigchainSpecialHandlerDump2(int signo, siginfo_t *si, void *ucontext) 139800b99b8Sopenharmony_ci{ 140800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SigchainSpecialHandlerDump2"; 141800b99b8Sopenharmony_ci g_sigchainDump2Flag = true; 142800b99b8Sopenharmony_ci EXPECT_EQ(signo, SIGDUMP) << "SigchainSpecialHandlerDump2 Failed"; 143800b99b8Sopenharmony_ci if (g_testLastFlag) { 144800b99b8Sopenharmony_ci g_count++; 145800b99b8Sopenharmony_ci EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SigchainSpecialHandlerDump2: g_count."; 146800b99b8Sopenharmony_ci } 147800b99b8Sopenharmony_ci return false; 148800b99b8Sopenharmony_ci} 149800b99b8Sopenharmony_ci 150800b99b8Sopenharmony_ciAT_UNUSED static bool SigchainSpecialHandlerSegvTrue(int signo, siginfo_t *si, void *ucontext) 151800b99b8Sopenharmony_ci{ 152800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SigchainSpecialHandlerSegvTrue"; 153800b99b8Sopenharmony_ci g_sigchainSegvFlag = true; 154800b99b8Sopenharmony_ci EXPECT_EQ(signo, SIGSEGV) << "SigchainSpecialHandlerSegvTrue Failed"; 155800b99b8Sopenharmony_ci if (g_testLastFlag) { 156800b99b8Sopenharmony_ci g_count++; 157800b99b8Sopenharmony_ci EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SigchainSpecialHandlerSegvTrue: g_count."; 158800b99b8Sopenharmony_ci } 159800b99b8Sopenharmony_ci return true; 160800b99b8Sopenharmony_ci} 161800b99b8Sopenharmony_ci 162800b99b8Sopenharmony_ciAT_UNUSED static bool SigchainSpecialHandlerSegv1(int signo, siginfo_t *si, void *ucontext) 163800b99b8Sopenharmony_ci{ 164800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SigchainSpecialHandlerSegv1"; 165800b99b8Sopenharmony_ci g_sigchainSegv1Flag = true; 166800b99b8Sopenharmony_ci EXPECT_EQ(signo, SIGSEGV) << "SigchainSpecialHandlerSegv1 Failed"; 167800b99b8Sopenharmony_ci if (g_testLastFlag) { 168800b99b8Sopenharmony_ci g_count++; 169800b99b8Sopenharmony_ci EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_1) << "SigchainSpecialHandlerSegv1: g_count."; 170800b99b8Sopenharmony_ci } 171800b99b8Sopenharmony_ci return false; 172800b99b8Sopenharmony_ci} 173800b99b8Sopenharmony_ci 174800b99b8Sopenharmony_ciAT_UNUSED static bool SigchainSpecialHandlerSegv2(int signo, siginfo_t *si, void *ucontext) 175800b99b8Sopenharmony_ci{ 176800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SigchainSpecialHandlerSegv2"; 177800b99b8Sopenharmony_ci g_sigchainSegv2Flag = true; 178800b99b8Sopenharmony_ci EXPECT_EQ(signo, SIGSEGV) << "SigchainSpecialHandlerSegv2 Failed"; 179800b99b8Sopenharmony_ci if (g_testLastFlag) { 180800b99b8Sopenharmony_ci g_count++; 181800b99b8Sopenharmony_ci EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SigchainSpecialHandlerSegv2: g_count."; 182800b99b8Sopenharmony_ci } 183800b99b8Sopenharmony_ci return false; 184800b99b8Sopenharmony_ci} 185800b99b8Sopenharmony_ci 186800b99b8Sopenharmony_ciclass MixStackDumper { 187800b99b8Sopenharmony_cipublic: 188800b99b8Sopenharmony_ci MixStackDumper() = default; 189800b99b8Sopenharmony_ci ~MixStackDumper() = default; 190800b99b8Sopenharmony_ci AT_UNUSED static bool DumpSignalHandler(int signo, siginfo_t *si, void *ucontext) 191800b99b8Sopenharmony_ci { 192800b99b8Sopenharmony_ci std::shared_ptr<int> ptr = std::make_shared<int>(TEST_PTR_VALUE); 193800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DumpSignalHandler: " << ptr.use_count(); 194800b99b8Sopenharmony_ci g_sigchainDump2Flag = true; 195800b99b8Sopenharmony_ci EXPECT_EQ(signo, SIGDUMP) << "DumpSignalHandler Failed"; 196800b99b8Sopenharmony_ci return true; 197800b99b8Sopenharmony_ci } 198800b99b8Sopenharmony_ci 199800b99b8Sopenharmony_ci AT_UNUSED static bool SegvSignalHandler(int signo, siginfo_t *si, void *ucontext) 200800b99b8Sopenharmony_ci { 201800b99b8Sopenharmony_ci std::shared_ptr<int> ptr = std::make_shared<int>(TEST_PTR_VALUE); 202800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SegvSignalHandler: " << ptr.use_count(); 203800b99b8Sopenharmony_ci g_sigchainSegv2Flag = true; 204800b99b8Sopenharmony_ci EXPECT_EQ(signo, SIGSEGV) << "SegvSignalHandler Failed"; 205800b99b8Sopenharmony_ci return false; 206800b99b8Sopenharmony_ci } 207800b99b8Sopenharmony_ci}; 208800b99b8Sopenharmony_ci 209800b99b8Sopenharmony_cistatic int KillAndWaitPid(int pid) 210800b99b8Sopenharmony_ci{ 211800b99b8Sopenharmony_ci usleep(SLEEP_10_MS); 212800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "kill SIGDUMP pid: " << pid; 213800b99b8Sopenharmony_ci kill(pid, SIGDUMP); 214800b99b8Sopenharmony_ci usleep(SLEEP_10_MS); 215800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "kill SIGSEGV pid: " << pid; 216800b99b8Sopenharmony_ci kill(pid, SIGSEGV); 217800b99b8Sopenharmony_ci usleep(SLEEP_2000_MS); 218800b99b8Sopenharmony_ci int status; 219800b99b8Sopenharmony_ci int ret = waitpid(pid, &status, 0); 220800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "waitpid: " << pid << ", ret: "<< ret << std::endl; 221800b99b8Sopenharmony_ci return ret; 222800b99b8Sopenharmony_ci} 223800b99b8Sopenharmony_ci 224800b99b8Sopenharmony_ci/** 225800b99b8Sopenharmony_ci * @tc.name: SignalChainTest001 226800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler signal 227800b99b8Sopenharmony_ci * @tc.type: FUNC 228800b99b8Sopenharmony_ci */ 229800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest001, TestSize.Level2) 230800b99b8Sopenharmony_ci{ 231800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest001: start."; 232800b99b8Sopenharmony_ci SignalInit(); 233800b99b8Sopenharmony_ci pid_t pid = fork(); 234800b99b8Sopenharmony_ci if (pid < 0) { 235800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 236800b99b8Sopenharmony_ci } else if (pid == 0) { 237800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest001: pid:" << getpid(); 238800b99b8Sopenharmony_ci signal(SIGSEGV, SignalSegvHandler); 239800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 240800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 241800b99b8Sopenharmony_ci ASSERT_EQ(g_signalSegvFlag, true) << "SignalChainTest001: g_signalSegvFlag."; 242800b99b8Sopenharmony_ci _exit(0); 243800b99b8Sopenharmony_ci } else { 244800b99b8Sopenharmony_ci KillAndWaitPid(pid); 245800b99b8Sopenharmony_ci } 246800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest001: end."; 247800b99b8Sopenharmony_ci} 248800b99b8Sopenharmony_ci 249800b99b8Sopenharmony_ci/** 250800b99b8Sopenharmony_ci * @tc.name: SignalChainTest002 251800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler sigaction 252800b99b8Sopenharmony_ci * @tc.type: FUNC 253800b99b8Sopenharmony_ci */ 254800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest002, TestSize.Level2) 255800b99b8Sopenharmony_ci{ 256800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest002: start."; 257800b99b8Sopenharmony_ci SignalInit(); 258800b99b8Sopenharmony_ci pid_t pid = fork(); 259800b99b8Sopenharmony_ci if (pid < 0) { 260800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 261800b99b8Sopenharmony_ci } else if (pid == 0) { 262800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest002: pid:" << getpid(); 263800b99b8Sopenharmony_ci struct sigaction sigsegv = { 264800b99b8Sopenharmony_ci .sa_handler = SignalSegvSigaction, 265800b99b8Sopenharmony_ci }; 266800b99b8Sopenharmony_ci sigaction(SIGSEGV, &sigsegv, NULL); 267800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 268800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 269800b99b8Sopenharmony_ci ASSERT_EQ(g_sigactionSegvFlag, true) << "SignalChainTest002: g_sigactionSegvFlag."; 270800b99b8Sopenharmony_ci _exit(0); 271800b99b8Sopenharmony_ci } else { 272800b99b8Sopenharmony_ci KillAndWaitPid(pid); 273800b99b8Sopenharmony_ci } 274800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest002: end."; 275800b99b8Sopenharmony_ci} 276800b99b8Sopenharmony_ci 277800b99b8Sopenharmony_ci/** 278800b99b8Sopenharmony_ci * @tc.name: SignalChainTest003 279800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler add sigchain no else signal or sigaction 280800b99b8Sopenharmony_ci * @tc.type: FUNC 281800b99b8Sopenharmony_ci */ 282800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest003, TestSize.Level2) 283800b99b8Sopenharmony_ci{ 284800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest003: start."; 285800b99b8Sopenharmony_ci SignalInit(); 286800b99b8Sopenharmony_ci pid_t pid = fork(); 287800b99b8Sopenharmony_ci if (pid < 0) { 288800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 289800b99b8Sopenharmony_ci } else if (pid == 0) { 290800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest003: pid:" << getpid(); 291800b99b8Sopenharmony_ci struct signal_chain_action sigchain1 = { 292800b99b8Sopenharmony_ci .sca_sigaction = SigchainSpecialHandlerDumpTrue, 293800b99b8Sopenharmony_ci .sca_mask = {}, 294800b99b8Sopenharmony_ci .sca_flags = 0, 295800b99b8Sopenharmony_ci }; 296800b99b8Sopenharmony_ci add_special_signal_handler(SIGDUMP, &sigchain1); 297800b99b8Sopenharmony_ci struct signal_chain_action sigsegv1 = { 298800b99b8Sopenharmony_ci .sca_sigaction = SigchainSpecialHandlerSegvTrue, 299800b99b8Sopenharmony_ci .sca_mask = {}, 300800b99b8Sopenharmony_ci .sca_flags = 0, 301800b99b8Sopenharmony_ci }; 302800b99b8Sopenharmony_ci add_special_signal_handler(SIGSEGV, &sigsegv1); 303800b99b8Sopenharmony_ci 304800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 305800b99b8Sopenharmony_ci ASSERT_EQ(g_sigchainDumpFlag, true) << "SignalChainTest003: g_sigchainDumpFlag."; 306800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 307800b99b8Sopenharmony_ci ASSERT_EQ(g_sigchainSegvFlag, true) << "SignalChainTest003: g_sigchainSegvFlag."; 308800b99b8Sopenharmony_ci _exit(0); 309800b99b8Sopenharmony_ci } else { 310800b99b8Sopenharmony_ci KillAndWaitPid(pid); 311800b99b8Sopenharmony_ci } 312800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest003: end."; 313800b99b8Sopenharmony_ci} 314800b99b8Sopenharmony_ci 315800b99b8Sopenharmony_ci/** 316800b99b8Sopenharmony_ci * @tc.name: SignalChainTest004 317800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler add sigchain and have signal handler 318800b99b8Sopenharmony_ci * @tc.type: FUNC 319800b99b8Sopenharmony_ci */ 320800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest004, TestSize.Level2) 321800b99b8Sopenharmony_ci{ 322800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest004: start."; 323800b99b8Sopenharmony_ci SignalInit(); 324800b99b8Sopenharmony_ci pid_t pid = fork(); 325800b99b8Sopenharmony_ci if (pid < 0) { 326800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 327800b99b8Sopenharmony_ci } else if (pid == 0) { 328800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest004: pid:" << getpid(); 329800b99b8Sopenharmony_ci signal(SIGSEGV, SignalSegvHandler); 330800b99b8Sopenharmony_ci 331800b99b8Sopenharmony_ci struct signal_chain_action sigchain1 = { 332800b99b8Sopenharmony_ci .sca_sigaction = SigchainSpecialHandlerDump1, 333800b99b8Sopenharmony_ci .sca_mask = {}, 334800b99b8Sopenharmony_ci .sca_flags = 0, 335800b99b8Sopenharmony_ci }; 336800b99b8Sopenharmony_ci add_special_signal_handler(SIGDUMP, &sigchain1); 337800b99b8Sopenharmony_ci struct signal_chain_action sigsegv1 = { 338800b99b8Sopenharmony_ci .sca_sigaction = SigchainSpecialHandlerSegv1, 339800b99b8Sopenharmony_ci .sca_mask = {}, 340800b99b8Sopenharmony_ci .sca_flags = 0, 341800b99b8Sopenharmony_ci }; 342800b99b8Sopenharmony_ci add_special_signal_handler(SIGSEGV, &sigsegv1); 343800b99b8Sopenharmony_ci 344800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 345800b99b8Sopenharmony_ci ASSERT_EQ(g_sigchainDump1Flag, true) << "SignalChainTest004: g_sigchainDump1Flag."; 346800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 347800b99b8Sopenharmony_ci ASSERT_EQ(g_signalSegvFlag, true) << "SignalChainTest004: g_signalSegvFlag."; 348800b99b8Sopenharmony_ci ASSERT_EQ(g_sigchainSegv1Flag, true) << "SignalChainTest004: g_sigchainSegv1Flag."; 349800b99b8Sopenharmony_ci _exit(0); 350800b99b8Sopenharmony_ci } else { 351800b99b8Sopenharmony_ci KillAndWaitPid(pid); 352800b99b8Sopenharmony_ci } 353800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest004: end."; 354800b99b8Sopenharmony_ci} 355800b99b8Sopenharmony_ci 356800b99b8Sopenharmony_ci/** 357800b99b8Sopenharmony_ci * @tc.name: SignalChainTest005 358800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler remove sigchain 359800b99b8Sopenharmony_ci * @tc.type: FUNC 360800b99b8Sopenharmony_ci */ 361800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest005, TestSize.Level2) 362800b99b8Sopenharmony_ci{ 363800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest005: start."; 364800b99b8Sopenharmony_ci SignalInit(); 365800b99b8Sopenharmony_ci pid_t pid = fork(); 366800b99b8Sopenharmony_ci if (pid < 0) { 367800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 368800b99b8Sopenharmony_ci } else if (pid == 0) { 369800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest005: pid:" << getpid(); 370800b99b8Sopenharmony_ci struct signal_chain_action sigchain1 = { 371800b99b8Sopenharmony_ci .sca_sigaction = SigchainSpecialHandlerDump1, 372800b99b8Sopenharmony_ci .sca_mask = {}, 373800b99b8Sopenharmony_ci .sca_flags = 0, 374800b99b8Sopenharmony_ci }; 375800b99b8Sopenharmony_ci add_special_signal_handler(SIGDUMP, &sigchain1); 376800b99b8Sopenharmony_ci struct signal_chain_action sigsegv1 = { 377800b99b8Sopenharmony_ci .sca_sigaction = SigchainSpecialHandlerSegv1, 378800b99b8Sopenharmony_ci .sca_mask = {}, 379800b99b8Sopenharmony_ci .sca_flags = 0, 380800b99b8Sopenharmony_ci }; 381800b99b8Sopenharmony_ci add_special_signal_handler(SIGSEGV, &sigsegv1); 382800b99b8Sopenharmony_ci 383800b99b8Sopenharmony_ci remove_special_signal_handler(SIGDUMP, SigchainSpecialHandlerDump1); 384800b99b8Sopenharmony_ci remove_special_signal_handler(SIGSEGV, SigchainSpecialHandlerSegv1); 385800b99b8Sopenharmony_ci 386800b99b8Sopenharmony_ci struct signal_chain_action sigchain2 = { 387800b99b8Sopenharmony_ci .sca_sigaction = SigchainSpecialHandlerDumpTrue, 388800b99b8Sopenharmony_ci .sca_mask = {}, 389800b99b8Sopenharmony_ci .sca_flags = 0, 390800b99b8Sopenharmony_ci }; 391800b99b8Sopenharmony_ci add_special_signal_handler(SIGDUMP, &sigchain2); 392800b99b8Sopenharmony_ci struct signal_chain_action sigsegv2 = { 393800b99b8Sopenharmony_ci .sca_sigaction = SigchainSpecialHandlerSegvTrue, 394800b99b8Sopenharmony_ci .sca_mask = {}, 395800b99b8Sopenharmony_ci .sca_flags = 0, 396800b99b8Sopenharmony_ci }; 397800b99b8Sopenharmony_ci add_special_signal_handler(SIGSEGV, &sigsegv2); 398800b99b8Sopenharmony_ci 399800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 400800b99b8Sopenharmony_ci ASSERT_NE(g_sigchainDump1Flag, true) << "SignalChainTest005: g_sigchainDump1Flag."; 401800b99b8Sopenharmony_ci ASSERT_EQ(g_sigchainDumpFlag, true) << "SignalChainTest005: g_sigchainDumpFlag."; 402800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 403800b99b8Sopenharmony_ci ASSERT_NE(g_sigchainSegv1Flag, true) << "SignalChainTest005: g_sigchainSegv1Flag."; 404800b99b8Sopenharmony_ci ASSERT_EQ(g_sigchainSegvFlag, true) << "SignalChainTest005: g_sigchainSegvFlag."; 405800b99b8Sopenharmony_ci _exit(0); 406800b99b8Sopenharmony_ci } else { 407800b99b8Sopenharmony_ci KillAndWaitPid(pid); 408800b99b8Sopenharmony_ci } 409800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest005: end."; 410800b99b8Sopenharmony_ci} 411800b99b8Sopenharmony_ci 412800b99b8Sopenharmony_ci/** 413800b99b8Sopenharmony_ci * @tc.name: SignalChainTest006 414800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler remove all sigchain 415800b99b8Sopenharmony_ci * @tc.type: FUNC 416800b99b8Sopenharmony_ci */ 417800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest006, TestSize.Level2) 418800b99b8Sopenharmony_ci{ 419800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest006: start."; 420800b99b8Sopenharmony_ci SignalInit(); 421800b99b8Sopenharmony_ci pid_t pid = fork(); 422800b99b8Sopenharmony_ci if (pid < 0) { 423800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 424800b99b8Sopenharmony_ci } else if (pid == 0) { 425800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest006: pid:" << getpid(); 426800b99b8Sopenharmony_ci signal(SIGDUMP, SignalDumpHandler); 427800b99b8Sopenharmony_ci signal(SIGSEGV, SignalSegvHandler); 428800b99b8Sopenharmony_ci 429800b99b8Sopenharmony_ci struct signal_chain_action sigchain1 = { 430800b99b8Sopenharmony_ci .sca_sigaction = SigchainSpecialHandlerDump1, 431800b99b8Sopenharmony_ci .sca_mask = {}, 432800b99b8Sopenharmony_ci .sca_flags = 0, 433800b99b8Sopenharmony_ci }; 434800b99b8Sopenharmony_ci add_special_signal_handler(SIGDUMP, &sigchain1); 435800b99b8Sopenharmony_ci 436800b99b8Sopenharmony_ci struct signal_chain_action sigsegv1 = { 437800b99b8Sopenharmony_ci .sca_sigaction = SigchainSpecialHandlerSegv1, 438800b99b8Sopenharmony_ci .sca_mask = {}, 439800b99b8Sopenharmony_ci .sca_flags = 0, 440800b99b8Sopenharmony_ci }; 441800b99b8Sopenharmony_ci add_special_signal_handler(SIGSEGV, &sigsegv1); 442800b99b8Sopenharmony_ci 443800b99b8Sopenharmony_ci remove_all_special_handler(SIGDUMP); 444800b99b8Sopenharmony_ci remove_all_special_handler(SIGSEGV); 445800b99b8Sopenharmony_ci 446800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 447800b99b8Sopenharmony_ci ASSERT_NE(g_sigchainDump1Flag, true) << "SignalChainTest006: g_sigchainDump1Flag."; 448800b99b8Sopenharmony_ci ASSERT_NE(g_sigchainDump2Flag, true) << "SignalChainTest006: g_sigchainDump2Flag."; 449800b99b8Sopenharmony_ci ASSERT_EQ(g_signalDumpFlag, true) << "SignalChainTest006: g_signalDumpFlag."; 450800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 451800b99b8Sopenharmony_ci ASSERT_NE(g_sigchainSegv1Flag, true) << "SignalChainTest006: g_sigchainSegv1Flag."; 452800b99b8Sopenharmony_ci ASSERT_NE(g_sigchainSegv2Flag, true) << "SignalChainTest006: g_sigchainSegv2Flag."; 453800b99b8Sopenharmony_ci ASSERT_EQ(g_signalSegvFlag, true) << "SignalChainTest006: g_signalSegvFlag."; 454800b99b8Sopenharmony_ci _exit(0); 455800b99b8Sopenharmony_ci } else { 456800b99b8Sopenharmony_ci KillAndWaitPid(pid); 457800b99b8Sopenharmony_ci } 458800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest006: end."; 459800b99b8Sopenharmony_ci} 460800b99b8Sopenharmony_ci 461800b99b8Sopenharmony_ci/** 462800b99b8Sopenharmony_ci * @tc.name: SignalChainTest007 463800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler run C++ code in sigchain handler 464800b99b8Sopenharmony_ci * @tc.type: FUNC 465800b99b8Sopenharmony_ci */ 466800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest007, TestSize.Level2) 467800b99b8Sopenharmony_ci{ 468800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest007: start."; 469800b99b8Sopenharmony_ci SignalInit(); 470800b99b8Sopenharmony_ci pid_t pid = fork(); 471800b99b8Sopenharmony_ci if (pid < 0) { 472800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 473800b99b8Sopenharmony_ci } else if (pid == 0) { 474800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest007: pid:" << getpid(); 475800b99b8Sopenharmony_ci remove_all_special_handler(SIGDUMP); 476800b99b8Sopenharmony_ci remove_all_special_handler(SIGSEGV); 477800b99b8Sopenharmony_ci 478800b99b8Sopenharmony_ci struct signal_chain_action sigchain1 = { 479800b99b8Sopenharmony_ci .sca_sigaction = SigchainSpecialHandlerDump1, 480800b99b8Sopenharmony_ci .sca_mask = {}, 481800b99b8Sopenharmony_ci .sca_flags = 0, 482800b99b8Sopenharmony_ci }; 483800b99b8Sopenharmony_ci add_special_signal_handler(SIGDUMP, &sigchain1); 484800b99b8Sopenharmony_ci struct signal_chain_action sigchain2 = { 485800b99b8Sopenharmony_ci .sca_sigaction = &(MixStackDumper::DumpSignalHandler), 486800b99b8Sopenharmony_ci .sca_mask = {}, 487800b99b8Sopenharmony_ci .sca_flags = 0, 488800b99b8Sopenharmony_ci }; 489800b99b8Sopenharmony_ci add_special_signal_handler(SIGDUMP, &sigchain2); 490800b99b8Sopenharmony_ci 491800b99b8Sopenharmony_ci struct signal_chain_action sigsegv1 = { 492800b99b8Sopenharmony_ci .sca_sigaction = SigchainSpecialHandlerSegv1, 493800b99b8Sopenharmony_ci .sca_mask = {}, 494800b99b8Sopenharmony_ci .sca_flags = 0, 495800b99b8Sopenharmony_ci }; 496800b99b8Sopenharmony_ci add_special_signal_handler(SIGSEGV, &sigsegv1); 497800b99b8Sopenharmony_ci struct signal_chain_action sigsegv2 = { 498800b99b8Sopenharmony_ci .sca_sigaction = MixStackDumper::SegvSignalHandler, 499800b99b8Sopenharmony_ci .sca_mask = {}, 500800b99b8Sopenharmony_ci .sca_flags = 0, 501800b99b8Sopenharmony_ci }; 502800b99b8Sopenharmony_ci add_special_signal_handler(SIGSEGV, &sigsegv2); 503800b99b8Sopenharmony_ci 504800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 505800b99b8Sopenharmony_ci ASSERT_EQ(g_sigchainDump1Flag, true) << "SignalChainTest007: g_sigchainDump1Flag."; 506800b99b8Sopenharmony_ci ASSERT_EQ(g_sigchainDump2Flag, true) << "SignalChainTest007: g_sigchainDump2Flag."; 507800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 508800b99b8Sopenharmony_ci ASSERT_EQ(g_sigchainSegv1Flag, true) << "SignalChainTest007: g_sigchainSegv1Flag."; 509800b99b8Sopenharmony_ci ASSERT_EQ(g_sigchainSegv2Flag, true) << "SignalChainTest007: g_sigchainSegv2Flag."; 510800b99b8Sopenharmony_ci _exit(0); 511800b99b8Sopenharmony_ci } else { 512800b99b8Sopenharmony_ci KillAndWaitPid(pid); 513800b99b8Sopenharmony_ci } 514800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest007: end."; 515800b99b8Sopenharmony_ci} 516800b99b8Sopenharmony_ci 517800b99b8Sopenharmony_ci/** 518800b99b8Sopenharmony_ci * @tc.name: SignalChainTest008 519800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler add_special_handler_at_last 520800b99b8Sopenharmony_ci * @tc.type: FUNC 521800b99b8Sopenharmony_ci */ 522800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest008, TestSize.Level2) 523800b99b8Sopenharmony_ci{ 524800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest008: start."; 525800b99b8Sopenharmony_ci SignalInit(); 526800b99b8Sopenharmony_ci pid_t pid = fork(); 527800b99b8Sopenharmony_ci if (pid < 0) { 528800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 529800b99b8Sopenharmony_ci } else if (pid == 0) { 530800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest008: pid:" << getpid(); 531800b99b8Sopenharmony_ci remove_all_special_handler(SIGDUMP); 532800b99b8Sopenharmony_ci remove_all_special_handler(SIGSEGV); 533800b99b8Sopenharmony_ci 534800b99b8Sopenharmony_ci struct signal_chain_action sigchain2 = { 535800b99b8Sopenharmony_ci .sca_sigaction = SigchainSpecialHandlerDumpTrue, 536800b99b8Sopenharmony_ci .sca_mask = {}, 537800b99b8Sopenharmony_ci .sca_flags = 0, 538800b99b8Sopenharmony_ci }; 539800b99b8Sopenharmony_ci add_special_handler_at_last(SIGDUMP, &sigchain2); 540800b99b8Sopenharmony_ci 541800b99b8Sopenharmony_ci struct signal_chain_action sigchain1 = { 542800b99b8Sopenharmony_ci .sca_sigaction = SigchainSpecialHandlerDump1, 543800b99b8Sopenharmony_ci .sca_mask = {}, 544800b99b8Sopenharmony_ci .sca_flags = 0, 545800b99b8Sopenharmony_ci }; 546800b99b8Sopenharmony_ci add_special_signal_handler(SIGDUMP, &sigchain1); 547800b99b8Sopenharmony_ci 548800b99b8Sopenharmony_ci struct signal_chain_action sigsegv2 = { 549800b99b8Sopenharmony_ci .sca_sigaction = SigchainSpecialHandlerSegvTrue, 550800b99b8Sopenharmony_ci .sca_mask = {}, 551800b99b8Sopenharmony_ci .sca_flags = 0, 552800b99b8Sopenharmony_ci }; 553800b99b8Sopenharmony_ci add_special_handler_at_last(SIGSEGV, &sigsegv2); 554800b99b8Sopenharmony_ci struct signal_chain_action sigsegv1 = { 555800b99b8Sopenharmony_ci .sca_sigaction = SigchainSpecialHandlerSegv1, 556800b99b8Sopenharmony_ci .sca_mask = {}, 557800b99b8Sopenharmony_ci .sca_flags = 0, 558800b99b8Sopenharmony_ci }; 559800b99b8Sopenharmony_ci add_special_signal_handler(SIGSEGV, &sigsegv1); 560800b99b8Sopenharmony_ci 561800b99b8Sopenharmony_ci ResetCount(); 562800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 563800b99b8Sopenharmony_ci ASSERT_EQ(g_sigchainDump1Flag, true) << "SignalChainTest008: g_sigchainDump1Flag."; 564800b99b8Sopenharmony_ci ASSERT_EQ(g_sigchainDumpFlag, true) << "SignalChainTest008: g_sigchainDumpFlag."; 565800b99b8Sopenharmony_ci ASSERT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SignalChainTest008: dump g_count."; 566800b99b8Sopenharmony_ci ResetCount(); 567800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 568800b99b8Sopenharmony_ci ASSERT_EQ(g_sigchainSegv1Flag, true) << "SignalChainTest008: g_sigchainSegv1Flag."; 569800b99b8Sopenharmony_ci ASSERT_EQ(g_sigchainSegvFlag, true) << "SignalChainTest008: g_sigchainSegvFlag."; 570800b99b8Sopenharmony_ci ASSERT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SignalChainTest008: segv g_count."; 571800b99b8Sopenharmony_ci _exit(0); 572800b99b8Sopenharmony_ci } else { 573800b99b8Sopenharmony_ci KillAndWaitPid(pid); 574800b99b8Sopenharmony_ci } 575800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest008: end."; 576800b99b8Sopenharmony_ci} 577800b99b8Sopenharmony_ci 578800b99b8Sopenharmony_ci/** 579800b99b8Sopenharmony_ci * @tc.name: SignalChainTest009 580800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler special signal(SIGILL) 581800b99b8Sopenharmony_ci * @tc.type: FUNC 582800b99b8Sopenharmony_ci */ 583800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest009, TestSize.Level2) 584800b99b8Sopenharmony_ci{ 585800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest009: start."; 586800b99b8Sopenharmony_ci SignalInit(); 587800b99b8Sopenharmony_ci pid_t pid = fork(); 588800b99b8Sopenharmony_ci if (pid < 0) { 589800b99b8Sopenharmony_ci GTEST_LOG_(ERROR) << "Failed to fork new test process."; 590800b99b8Sopenharmony_ci } else if (pid == 0) { 591800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest009: pid:" << getpid(); 592800b99b8Sopenharmony_ci struct sigaction sigill = { 593800b99b8Sopenharmony_ci .sa_handler = SignalIllSigaction, 594800b99b8Sopenharmony_ci }; 595800b99b8Sopenharmony_ci sigaction(SIGILL, &sigill, NULL); 596800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 597800b99b8Sopenharmony_ci ASSERT_EQ(g_sigactionIllFlag, true) << "SignalChainTest009: g_sigactionIllFlag."; 598800b99b8Sopenharmony_ci _exit(0); 599800b99b8Sopenharmony_ci } else { 600800b99b8Sopenharmony_ci usleep(SLEEP_10_MS); 601800b99b8Sopenharmony_ci kill(pid, SIGILL); 602800b99b8Sopenharmony_ci usleep(SLEEP_1000_MS); 603800b99b8Sopenharmony_ci int status; 604800b99b8Sopenharmony_ci waitpid(pid, &status, 0); 605800b99b8Sopenharmony_ci } 606800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "SignalChainTest009: end."; 607800b99b8Sopenharmony_ci} 608800b99b8Sopenharmony_ci} // namespace HiviewDFX 609800b99b8Sopenharmony_ci} // namepsace OHOS 610