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 <map> 18800b99b8Sopenharmony_ci#include <memory> 19800b99b8Sopenharmony_ci#include <securec.h> 20800b99b8Sopenharmony_ci#include <csignal> 21800b99b8Sopenharmony_ci#include <string> 22800b99b8Sopenharmony_ci 23800b99b8Sopenharmony_ci#include "dfx_signal.h" 24800b99b8Sopenharmony_ci 25800b99b8Sopenharmony_ciusing namespace OHOS::HiviewDFX; 26800b99b8Sopenharmony_ciusing namespace testing::ext; 27800b99b8Sopenharmony_ciusing namespace std; 28800b99b8Sopenharmony_ci 29800b99b8Sopenharmony_cinamespace OHOS { 30800b99b8Sopenharmony_cinamespace HiviewDFX { 31800b99b8Sopenharmony_ciclass DfxSignalTest : public testing::Test { 32800b99b8Sopenharmony_cipublic: 33800b99b8Sopenharmony_ci static void SetUpTestCase(void) {} 34800b99b8Sopenharmony_ci static void TearDownTestCase(void) {} 35800b99b8Sopenharmony_ci void SetUp() {} 36800b99b8Sopenharmony_ci void TearDown() {} 37800b99b8Sopenharmony_ci}; 38800b99b8Sopenharmony_ci} // namespace HiviewDFX 39800b99b8Sopenharmony_ci} // namespace OHOS 40800b99b8Sopenharmony_ci 41800b99b8Sopenharmony_cinamespace { 42800b99b8Sopenharmony_ci/** 43800b99b8Sopenharmony_ci * @tc.name: DfxSignalTest001 44800b99b8Sopenharmony_ci * @tc.desc: test DfxSignal functions 45800b99b8Sopenharmony_ci * @tc.type: FUNC 46800b99b8Sopenharmony_ci */ 47800b99b8Sopenharmony_ciHWTEST_F(DfxSignalTest, DfxSignalTest001, TestSize.Level2) 48800b99b8Sopenharmony_ci{ 49800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest001: start."; 50800b99b8Sopenharmony_ci siginfo_t si = { 51800b99b8Sopenharmony_ci .si_signo = SIGSEGV, 52800b99b8Sopenharmony_ci .si_errno = 0, 53800b99b8Sopenharmony_ci .si_code = -1, 54800b99b8Sopenharmony_ci .si_value.sival_int = static_cast<int>(gettid()) 55800b99b8Sopenharmony_ci }; 56800b99b8Sopenharmony_ci std::map<int, std::string> sigKey = { 57800b99b8Sopenharmony_ci { SIGILL, string("SIGILL") }, 58800b99b8Sopenharmony_ci { SIGTRAP, string("SIGTRAP") }, 59800b99b8Sopenharmony_ci { SIGABRT, string("SIGABRT") }, 60800b99b8Sopenharmony_ci { SIGBUS, string("SIGBUS") }, 61800b99b8Sopenharmony_ci { SIGFPE, string("SIGFPE") }, 62800b99b8Sopenharmony_ci { SIGSEGV, string("SIGSEGV") }, 63800b99b8Sopenharmony_ci { SIGSTKFLT, string("SIGSTKFLT") }, 64800b99b8Sopenharmony_ci { SIGSYS, string("SIGSYS") }, 65800b99b8Sopenharmony_ci }; 66800b99b8Sopenharmony_ci for (auto sigKey : sigKey) { 67800b99b8Sopenharmony_ci std::string sigKeyword = "Signal:"; 68800b99b8Sopenharmony_ci si.si_signo = sigKey.first; 69800b99b8Sopenharmony_ci sigKeyword += sigKey.second; 70800b99b8Sopenharmony_ci std::string sigStr = DfxSignal::PrintSignal(si) + "\n"; 71800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << sigStr; 72800b99b8Sopenharmony_ci ASSERT_TRUE(sigStr.find(sigKeyword) != std::string::npos); 73800b99b8Sopenharmony_ci } 74800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest001: end."; 75800b99b8Sopenharmony_ci} 76800b99b8Sopenharmony_ci 77800b99b8Sopenharmony_ci/** 78800b99b8Sopenharmony_ci * @tc.name: DfxSignalTest002 79800b99b8Sopenharmony_ci * @tc.desc: test if signal info is available 80800b99b8Sopenharmony_ci * @tc.type: FUNC 81800b99b8Sopenharmony_ci */ 82800b99b8Sopenharmony_ciHWTEST_F(DfxSignalTest, DfxSignalTest002, TestSize.Level2) 83800b99b8Sopenharmony_ci{ 84800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest002: start."; 85800b99b8Sopenharmony_ci int32_t input = 1; 86800b99b8Sopenharmony_ci std::shared_ptr<DfxSignal> signal = std::make_shared<DfxSignal>(input); 87800b99b8Sopenharmony_ci bool ret = signal->IsAvailable(); 88800b99b8Sopenharmony_ci EXPECT_EQ(true, ret != true) << "DfxSignalTest002 Failed"; 89800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest002: end."; 90800b99b8Sopenharmony_ci} 91800b99b8Sopenharmony_ci 92800b99b8Sopenharmony_cistatic void TestSignalHandler(int sig, siginfo_t * si, void * context) 93800b99b8Sopenharmony_ci{ 94800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "Enter TestSignalHandler"; 95800b99b8Sopenharmony_ci} 96800b99b8Sopenharmony_ci 97800b99b8Sopenharmony_ci/** 98800b99b8Sopenharmony_ci * @tc.name: DfxSignalTest003 99800b99b8Sopenharmony_ci * @tc.desc: test if signal info is available in normal status 100800b99b8Sopenharmony_ci * @tc.type: FUNC 101800b99b8Sopenharmony_ci */ 102800b99b8Sopenharmony_ciHWTEST_F(DfxSignalTest, DfxSignalTest003, TestSize.Level2) 103800b99b8Sopenharmony_ci{ 104800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest003: start."; 105800b99b8Sopenharmony_ci pid_t child = fork(); 106800b99b8Sopenharmony_ci if (child == 0) { 107800b99b8Sopenharmony_ci int32_t input = SIGINT; 108800b99b8Sopenharmony_ci struct sigaction action; 109800b99b8Sopenharmony_ci (void)memset_s(&action, sizeof(action), 0, sizeof(action)); 110800b99b8Sopenharmony_ci action.sa_sigaction = TestSignalHandler; 111800b99b8Sopenharmony_ci action.sa_flags = SA_SIGINFO; 112800b99b8Sopenharmony_ci int rc = sigaction(input, &action, nullptr); 113800b99b8Sopenharmony_ci ASSERT_EQ(rc, 0) << "DfxSignalTest003 Failed, sigaction signal failed"; 114800b99b8Sopenharmony_ci 115800b99b8Sopenharmony_ci std::shared_ptr<DfxSignal> signal = std::make_shared<DfxSignal>(input); 116800b99b8Sopenharmony_ci bool ret = signal->IsAvailable(); 117800b99b8Sopenharmony_ci ASSERT_EQ(true, ret) << "DfxSignalTest003 Failed"; 118800b99b8Sopenharmony_ci _exit(0); 119800b99b8Sopenharmony_ci } 120800b99b8Sopenharmony_ci int status; 121800b99b8Sopenharmony_ci int ret = wait(&status); 122800b99b8Sopenharmony_ci ASSERT_EQ(status, 0); 123800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret; 124800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest003: end."; 125800b99b8Sopenharmony_ci} 126800b99b8Sopenharmony_ci 127800b99b8Sopenharmony_ci/** 128800b99b8Sopenharmony_ci * @tc.name: DfxSignalTest004 129800b99b8Sopenharmony_ci * @tc.desc: test if addr is available 130800b99b8Sopenharmony_ci * @tc.type: FUNC 131800b99b8Sopenharmony_ci */ 132800b99b8Sopenharmony_ciHWTEST_F(DfxSignalTest, DfxSignalTest004, TestSize.Level2) 133800b99b8Sopenharmony_ci{ 134800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest004: start."; 135800b99b8Sopenharmony_ci int32_t input = -100; // -100 is an unexpected signal 136800b99b8Sopenharmony_ci std::shared_ptr<DfxSignal> signal = std::make_shared<DfxSignal>(input); 137800b99b8Sopenharmony_ci bool ret = signal->IsAddrAvailable(); 138800b99b8Sopenharmony_ci EXPECT_EQ(true, ret != true) << "DfxSignalTest004 Failed"; 139800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest004: end."; 140800b99b8Sopenharmony_ci} 141800b99b8Sopenharmony_ci 142800b99b8Sopenharmony_ci/** 143800b99b8Sopenharmony_ci * @tc.name: DfxSignalTest005 144800b99b8Sopenharmony_ci * @tc.desc: test if addr is available in normal status 145800b99b8Sopenharmony_ci * @tc.type: FUNC 146800b99b8Sopenharmony_ci */ 147800b99b8Sopenharmony_ciHWTEST_F(DfxSignalTest, DfxSignalTest005, TestSize.Level2) 148800b99b8Sopenharmony_ci{ 149800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest005: start."; 150800b99b8Sopenharmony_ci int32_t input = SIGSEGV; 151800b99b8Sopenharmony_ci std::shared_ptr<DfxSignal> signal = std::make_shared<DfxSignal>(input); 152800b99b8Sopenharmony_ci bool ret = signal->IsAddrAvailable(); 153800b99b8Sopenharmony_ci EXPECT_EQ(true, ret) << "DfxSignalTest005 Failed"; 154800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest005: end."; 155800b99b8Sopenharmony_ci} 156800b99b8Sopenharmony_ci 157800b99b8Sopenharmony_ci/** 158800b99b8Sopenharmony_ci * @tc.name: DfxSignalTest006 159800b99b8Sopenharmony_ci * @tc.desc: test if pid is available 160800b99b8Sopenharmony_ci * @tc.type: FUNC 161800b99b8Sopenharmony_ci */ 162800b99b8Sopenharmony_ciHWTEST_F(DfxSignalTest, DfxSignalTest006, TestSize.Level2) 163800b99b8Sopenharmony_ci{ 164800b99b8Sopenharmony_ci int32_t input = 100; // 100 is an unexpected signal 165800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest006: start."; 166800b99b8Sopenharmony_ci std::shared_ptr<DfxSignal> signal = std::make_shared<DfxSignal>(input); 167800b99b8Sopenharmony_ci bool ret = signal->IsPidAvailable(); 168800b99b8Sopenharmony_ci EXPECT_EQ(true, ret != true) << "DfxSignalTest006 Failed"; 169800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest006: end."; 170800b99b8Sopenharmony_ci} 171800b99b8Sopenharmony_ci 172800b99b8Sopenharmony_ci/** 173800b99b8Sopenharmony_ci * @tc.name: DfxSignalTest007 174800b99b8Sopenharmony_ci * @tc.desc: test if pid is available in normal status 175800b99b8Sopenharmony_ci * @tc.type: FUNC 176800b99b8Sopenharmony_ci */ 177800b99b8Sopenharmony_ciHWTEST_F(DfxSignalTest, DfxSignalTest007, TestSize.Level2) 178800b99b8Sopenharmony_ci{ 179800b99b8Sopenharmony_ci int32_t input = SI_USER; 180800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest007: start."; 181800b99b8Sopenharmony_ci std::shared_ptr<DfxSignal> signal = std::make_shared<DfxSignal>(input); 182800b99b8Sopenharmony_ci bool ret = signal->IsPidAvailable(); 183800b99b8Sopenharmony_ci EXPECT_EQ(true, ret) << "DfxSignalTest007 Failed"; 184800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest007: end."; 185800b99b8Sopenharmony_ci} 186800b99b8Sopenharmony_ci 187800b99b8Sopenharmony_ci/** 188800b99b8Sopenharmony_ci * @tc.name: DfxSignalTest008 189800b99b8Sopenharmony_ci * @tc.desc: test if GetSignal 190800b99b8Sopenharmony_ci * @tc.type: FUNC 191800b99b8Sopenharmony_ci */ 192800b99b8Sopenharmony_ciHWTEST_F(DfxSignalTest, DfxSignalTest008, TestSize.Level2) 193800b99b8Sopenharmony_ci{ 194800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest008: start."; 195800b99b8Sopenharmony_ci int32_t input = 1; 196800b99b8Sopenharmony_ci std::shared_ptr<DfxSignal> signal = std::make_shared<DfxSignal>(input); 197800b99b8Sopenharmony_ci int32_t output = signal->GetSignal(); 198800b99b8Sopenharmony_ci EXPECT_EQ(true, output == input) << "DfxSignalTest008 Failed"; 199800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest008: end."; 200800b99b8Sopenharmony_ci} 201800b99b8Sopenharmony_ci 202800b99b8Sopenharmony_cistd::map<int32_t, std::string> sigKeys = { 203800b99b8Sopenharmony_ci { SIGILL, std::string("SIGILL") }, 204800b99b8Sopenharmony_ci { SIGTRAP, std::string("SIGTRAP") }, 205800b99b8Sopenharmony_ci { SIGBUS, std::string("SIGBUS") }, 206800b99b8Sopenharmony_ci { SIGFPE, std::string("SIGFPE") }, 207800b99b8Sopenharmony_ci { SIGSEGV, std::string("SIGSEGV") }, 208800b99b8Sopenharmony_ci}; 209800b99b8Sopenharmony_cistd::map<int, std::string> segvCode = { 210800b99b8Sopenharmony_ci { SEGV_MAPERR, string("SEGV_MAPERR") }, 211800b99b8Sopenharmony_ci { SEGV_ACCERR, string("SEGV_ACCERR") }, 212800b99b8Sopenharmony_ci { SI_USER, string("SI_USER") }, 213800b99b8Sopenharmony_ci}; 214800b99b8Sopenharmony_cistd::map<int, std::string> trapCode = { 215800b99b8Sopenharmony_ci { TRAP_BRKPT, string("TRAP_BRKPT") }, 216800b99b8Sopenharmony_ci { TRAP_TRACE, string("TRAP_TRACE") }, 217800b99b8Sopenharmony_ci { TRAP_BRANCH, string("TRAP_BRANCH") }, 218800b99b8Sopenharmony_ci { TRAP_HWBKPT, string("TRAP_HWBKPT") }, 219800b99b8Sopenharmony_ci { SI_USER, string("SI_USER") }, 220800b99b8Sopenharmony_ci}; 221800b99b8Sopenharmony_cistd::map<int, std::string> illCode = { 222800b99b8Sopenharmony_ci { ILL_ILLOPC, string("ILL_ILLOPC") }, 223800b99b8Sopenharmony_ci { ILL_ILLOPN, string("ILL_ILLOPN") }, 224800b99b8Sopenharmony_ci { ILL_ILLADR, string("ILL_ILLADR") }, 225800b99b8Sopenharmony_ci { ILL_ILLTRP, string("ILL_ILLTRP") }, 226800b99b8Sopenharmony_ci { ILL_PRVOPC, string("ILL_PRVOPC") }, 227800b99b8Sopenharmony_ci { ILL_PRVREG, string("ILL_PRVREG") }, 228800b99b8Sopenharmony_ci { ILL_COPROC, string("ILL_COPROC") }, 229800b99b8Sopenharmony_ci { ILL_BADSTK, string("ILL_BADSTK") }, 230800b99b8Sopenharmony_ci { SI_USER, string("SI_USER") }, 231800b99b8Sopenharmony_ci}; 232800b99b8Sopenharmony_cistd::map<int, std::string> fpeCode = { 233800b99b8Sopenharmony_ci { FPE_INTDIV, string("FPE_INTDIV") }, 234800b99b8Sopenharmony_ci { FPE_INTOVF, string("FPE_INTOVF") }, 235800b99b8Sopenharmony_ci { FPE_FLTDIV, string("FPE_FLTDIV") }, 236800b99b8Sopenharmony_ci { FPE_FLTOVF, string("FPE_FLTOVF") }, 237800b99b8Sopenharmony_ci { FPE_FLTUND, string("FPE_FLTUND") }, 238800b99b8Sopenharmony_ci { FPE_FLTRES, string("FPE_FLTRES") }, 239800b99b8Sopenharmony_ci { FPE_FLTINV, string("FPE_FLTINV") }, 240800b99b8Sopenharmony_ci { FPE_FLTSUB, string("FPE_FLTSUB") }, 241800b99b8Sopenharmony_ci { SI_USER, string("SI_USER") }, 242800b99b8Sopenharmony_ci}; 243800b99b8Sopenharmony_cistd::map<int, std::string> busCode = { 244800b99b8Sopenharmony_ci { BUS_ADRALN, string("BUS_ADRALN") }, 245800b99b8Sopenharmony_ci { BUS_ADRERR, string("BUS_ADRERR") }, 246800b99b8Sopenharmony_ci { BUS_OBJERR, string("BUS_OBJERR") }, 247800b99b8Sopenharmony_ci { BUS_MCEERR_AR, string("BUS_MCEERR_AR") }, 248800b99b8Sopenharmony_ci { BUS_MCEERR_AO, string("BUS_MCEERR_AO") }, 249800b99b8Sopenharmony_ci { SI_USER, string("SI_USER") }, 250800b99b8Sopenharmony_ci}; 251800b99b8Sopenharmony_ci/** 252800b99b8Sopenharmony_ci * @tc.name: DfxSignalTest009 253800b99b8Sopenharmony_ci * @tc.desc: test DfxSignal functions 254800b99b8Sopenharmony_ci * @tc.type: FUNC 255800b99b8Sopenharmony_ci */ 256800b99b8Sopenharmony_ciHWTEST_F(DfxSignalTest, DfxSignalTest009, TestSize.Level2) 257800b99b8Sopenharmony_ci{ 258800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest009: start."; 259800b99b8Sopenharmony_ci siginfo_t si = { 260800b99b8Sopenharmony_ci .si_signo = SIGSEGV, 261800b99b8Sopenharmony_ci .si_errno = 0, 262800b99b8Sopenharmony_ci .si_code = -1, 263800b99b8Sopenharmony_ci .si_value.sival_int = static_cast<int>(gettid()) 264800b99b8Sopenharmony_ci }; 265800b99b8Sopenharmony_ci for (auto sigKey : sigKeys) { 266800b99b8Sopenharmony_ci si.si_signo = sigKey.first; 267800b99b8Sopenharmony_ci std::map<int, std::string> codeMap; 268800b99b8Sopenharmony_ci switch (si.si_signo) { 269800b99b8Sopenharmony_ci case SIGILL: 270800b99b8Sopenharmony_ci codeMap = illCode; 271800b99b8Sopenharmony_ci break; 272800b99b8Sopenharmony_ci case SIGTRAP: 273800b99b8Sopenharmony_ci codeMap = trapCode; 274800b99b8Sopenharmony_ci break; 275800b99b8Sopenharmony_ci case SIGBUS: 276800b99b8Sopenharmony_ci codeMap = busCode; 277800b99b8Sopenharmony_ci break; 278800b99b8Sopenharmony_ci case SIGFPE: 279800b99b8Sopenharmony_ci codeMap = fpeCode; 280800b99b8Sopenharmony_ci break; 281800b99b8Sopenharmony_ci case SIGSEGV: 282800b99b8Sopenharmony_ci codeMap = segvCode; 283800b99b8Sopenharmony_ci break; 284800b99b8Sopenharmony_ci default: 285800b99b8Sopenharmony_ci break; 286800b99b8Sopenharmony_ci } 287800b99b8Sopenharmony_ci for (auto& code : codeMap) { 288800b99b8Sopenharmony_ci std::string sigKeyword = "Signal:"; 289800b99b8Sopenharmony_ci sigKeyword += sigKey.second; 290800b99b8Sopenharmony_ci si.si_code = code.first; 291800b99b8Sopenharmony_ci sigKeyword = sigKeyword + "(" + code.second + ")"; 292800b99b8Sopenharmony_ci std::string sigStr = DfxSignal::PrintSignal(si) + "\n"; 293800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << sigStr; 294800b99b8Sopenharmony_ci ASSERT_TRUE(sigStr.find(sigKeyword) != std::string::npos); 295800b99b8Sopenharmony_ci } 296800b99b8Sopenharmony_ci } 297800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "DfxSignalTest009: end."; 298800b99b8Sopenharmony_ci} 299800b99b8Sopenharmony_ci} 300