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