• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <gtest/gtest.h>
17 #include <map>
18 #include <memory>
19 #include <securec.h>
20 #include <csignal>
21 #include <string>
22 
23 #include "dfx_signal.h"
24 #include "dfx_test_util.h"
25 
26 using namespace OHOS::HiviewDFX;
27 using namespace testing::ext;
28 using namespace std;
29 
30 namespace OHOS {
31 namespace HiviewDFX {
32 class DfxSignalTest : public testing::Test {
33 public:
SetUpTestCase(void)34     static void SetUpTestCase(void) {}
TearDownTestCase(void)35     static void TearDownTestCase(void) {}
SetUp()36     void SetUp() {}
TearDown()37     void TearDown() {}
38 };
39 } // namespace HiviewDFX
40 } // namespace OHOS
41 
42 namespace {
43 /**
44  * @tc.name: DfxSignalTest001
45  * @tc.desc: test DfxSignal functions
46  * @tc.type: FUNC
47  */
48 HWTEST_F(DfxSignalTest, DfxSignalTest001, TestSize.Level2)
49 {
50     GTEST_LOG_(INFO) << "DfxSignalTest001: start.";
51     siginfo_t si = {
52         .si_signo = SIGSEGV,
53         .si_errno = 0,
54         .si_code = -1,
55         .si_value.sival_int = static_cast<int>(gettid())
56     };
57     std::map<int, std::string> sigKey = {
58         { SIGILL, string("SIGILL") },
59         { SIGTRAP, string("SIGTRAP") },
60         { SIGABRT, string("SIGABRT") },
61         { SIGBUS, string("SIGBUS") },
62         { SIGFPE, string("SIGFPE") },
63         { SIGSEGV, string("SIGSEGV") },
64         { SIGSTKFLT, string("SIGSTKFLT") },
65         { SIGSYS, string("SIGSYS") },
66     };
67     for (auto sigKey : sigKey) {
68         std::string sigKeyword = "Signal:";
69         si.si_signo = sigKey.first;
70         sigKeyword += sigKey.second;
71         std::string sigStr = DfxSignal::PrintSignal(si) + "\n";
72         GTEST_LOG_(INFO) << sigStr;
73         ASSERT_TRUE(sigStr.find(sigKeyword) != std::string::npos);
74     }
75     GTEST_LOG_(INFO) << "DfxSignalTest001: end.";
76 }
77 
78 /**
79  * @tc.name: DfxSignalTest002
80  * @tc.desc: test if signal info is available
81  * @tc.type: FUNC
82  */
83 HWTEST_F(DfxSignalTest, DfxSignalTest002, TestSize.Level2)
84 {
85     GTEST_LOG_(INFO) << "DfxSignalTest002: start.";
86     int32_t input = 1;
87     std::shared_ptr<DfxSignal> signal = std::make_shared<DfxSignal>(input);
88     bool ret = signal->IsAvailable();
89     EXPECT_EQ(true, ret != true) << "DfxSignalTest002 Failed";
90     GTEST_LOG_(INFO) << "DfxSignalTest002: end.";
91 }
92 
TestSignalHandler(int sig,siginfo_t * si,void * context)93 static void TestSignalHandler(int sig, siginfo_t * si, void * context)
94 {
95     GTEST_LOG_(INFO) << "Enter TestSignalHandler";
96 }
97 
98 /**
99  * @tc.name: DfxSignalTest003
100  * @tc.desc: test if signal info is available in normal status
101  * @tc.type: FUNC
102  */
103 HWTEST_F(DfxSignalTest, DfxSignalTest003, TestSize.Level2)
104 {
105     GTEST_LOG_(INFO) << "DfxSignalTest003: start.";
106     pid_t child = fork();
107     if (child == 0) {
108         int32_t input = SIGINT;
109         struct sigaction action;
110         (void)memset_s(&action, sizeof(action), 0, sizeof(action));
111         action.sa_sigaction = TestSignalHandler;
112         action.sa_flags = SA_SIGINFO;
113         int rc = sigaction(input, &action, nullptr);
114         EXPECT_EQ(rc, 0) << "DfxSignalTest003 Failed, sigaction signal failed";
115 
116         std::shared_ptr<DfxSignal> signal = std::make_shared<DfxSignal>(input);
117         bool ret = signal->IsAvailable();
118         EXPECT_EQ(true, ret) << "DfxSignalTest003 Failed";
119         CheckAndExit(HasFailure());
120     }
121     int status;
122     wait(&status);
123     ASSERT_EQ(status, 0);
124     GTEST_LOG_(INFO) << "DfxSignalTest003: end.";
125 }
126 
127 /**
128  * @tc.name: DfxSignalTest004
129  * @tc.desc: test if addr is available
130  * @tc.type: FUNC
131  */
132 HWTEST_F(DfxSignalTest, DfxSignalTest004, TestSize.Level2)
133 {
134     GTEST_LOG_(INFO) << "DfxSignalTest004: start.";
135     int32_t input = -100; // -100 is an unexpected signal
136     std::shared_ptr<DfxSignal> signal = std::make_shared<DfxSignal>(input);
137     bool ret = signal->IsAddrAvailable();
138     EXPECT_EQ(true, ret != true) << "DfxSignalTest004 Failed";
139     GTEST_LOG_(INFO) << "DfxSignalTest004: end.";
140 }
141 
142 /**
143  * @tc.name: DfxSignalTest005
144  * @tc.desc: test if addr is available in normal status
145  * @tc.type: FUNC
146  */
147 HWTEST_F(DfxSignalTest, DfxSignalTest005, TestSize.Level2)
148 {
149     GTEST_LOG_(INFO) << "DfxSignalTest005: start.";
150     int32_t input = SIGSEGV;
151     std::shared_ptr<DfxSignal> signal = std::make_shared<DfxSignal>(input);
152     bool ret = signal->IsAddrAvailable();
153     EXPECT_EQ(true, ret) << "DfxSignalTest005 Failed";
154     GTEST_LOG_(INFO) << "DfxSignalTest005: end.";
155 }
156 
157 /**
158  * @tc.name: DfxSignalTest006
159  * @tc.desc: test if pid is available
160  * @tc.type: FUNC
161  */
162 HWTEST_F(DfxSignalTest, DfxSignalTest006, TestSize.Level2)
163 {
164     int32_t input = 100; // 100 is an unexpected signal
165     GTEST_LOG_(INFO) << "DfxSignalTest006: start.";
166     std::shared_ptr<DfxSignal> signal = std::make_shared<DfxSignal>(input);
167     bool ret = signal->IsPidAvailable();
168     EXPECT_EQ(true, ret != true) << "DfxSignalTest006 Failed";
169     GTEST_LOG_(INFO) << "DfxSignalTest006: end.";
170 }
171 
172 /**
173  * @tc.name: DfxSignalTest007
174  * @tc.desc: test if pid is available in normal status
175  * @tc.type: FUNC
176  */
177 HWTEST_F(DfxSignalTest, DfxSignalTest007, TestSize.Level2)
178 {
179     int32_t input = SI_USER;
180     GTEST_LOG_(INFO) << "DfxSignalTest007: start.";
181     std::shared_ptr<DfxSignal> signal = std::make_shared<DfxSignal>(input);
182     bool ret = signal->IsPidAvailable();
183     EXPECT_EQ(true, ret) << "DfxSignalTest007 Failed";
184     GTEST_LOG_(INFO) << "DfxSignalTest007: end.";
185 }
186 
187 /**
188  * @tc.name: DfxSignalTest008
189  * @tc.desc: test if GetSignal
190  * @tc.type: FUNC
191  */
192 HWTEST_F(DfxSignalTest, DfxSignalTest008, TestSize.Level2)
193 {
194     GTEST_LOG_(INFO) << "DfxSignalTest008: start.";
195     int32_t input = 1;
196     std::shared_ptr<DfxSignal> signal = std::make_shared<DfxSignal>(input);
197     int32_t output = signal->GetSignal();
198     EXPECT_EQ(true, output == input) << "DfxSignalTest008 Failed";
199     GTEST_LOG_(INFO) << "DfxSignalTest008: end.";
200 }
201 
202 std::map<int32_t, std::string> sigKeys = {
203     { SIGILL, std::string("SIGILL") },
204     { SIGTRAP, std::string("SIGTRAP") },
205     { SIGBUS, std::string("SIGBUS") },
206     { SIGFPE, std::string("SIGFPE") },
207     { SIGSEGV, std::string("SIGSEGV") },
208 };
209 std::map<int, std::string> segvCode = {
210     { SEGV_MAPERR, string("SEGV_MAPERR") },
211     { SEGV_ACCERR, string("SEGV_ACCERR") },
212     { SI_USER, string("SI_USER") },
213 };
214 std::map<int, std::string> trapCode = {
215     { TRAP_BRKPT, string("TRAP_BRKPT") },
216     { TRAP_TRACE, string("TRAP_TRACE") },
217     { TRAP_BRANCH, string("TRAP_BRANCH") },
218     { TRAP_HWBKPT, string("TRAP_HWBKPT") },
219     { SI_USER, string("SI_USER") },
220 };
221 std::map<int, std::string> illCode = {
222     { ILL_ILLOPC, string("ILL_ILLOPC") },
223     { ILL_ILLOPN, string("ILL_ILLOPN") },
224     { ILL_ILLADR, string("ILL_ILLADR") },
225     { ILL_ILLTRP, string("ILL_ILLTRP") },
226     { ILL_PRVOPC, string("ILL_PRVOPC") },
227     { ILL_PRVREG, string("ILL_PRVREG") },
228     { ILL_COPROC, string("ILL_COPROC") },
229     { ILL_BADSTK, string("ILL_BADSTK") },
230     { ILL_ILLPACCFI, string("ILL_ILLPACCFI") },
231     { SI_USER, string("SI_USER") },
232 };
233 std::map<int, std::string> fpeCode = {
234     { FPE_INTDIV, string("FPE_INTDIV") },
235     { FPE_INTOVF, string("FPE_INTOVF") },
236     { FPE_FLTDIV, string("FPE_FLTDIV") },
237     { FPE_FLTOVF, string("FPE_FLTOVF") },
238     { FPE_FLTUND, string("FPE_FLTUND") },
239     { FPE_FLTRES, string("FPE_FLTRES") },
240     { FPE_FLTINV, string("FPE_FLTINV") },
241     { FPE_FLTSUB, string("FPE_FLTSUB") },
242     { SI_USER, string("SI_USER") },
243 };
244 std::map<int, std::string> busCode = {
245     { BUS_ADRALN, string("BUS_ADRALN") },
246     { BUS_ADRERR, string("BUS_ADRERR") },
247     { BUS_OBJERR, string("BUS_OBJERR") },
248     { BUS_MCEERR_AR, string("BUS_MCEERR_AR") },
249     { BUS_MCEERR_AO, string("BUS_MCEERR_AO") },
250     { SI_USER, string("SI_USER") },
251 };
252 /**
253  * @tc.name: DfxSignalTest009
254  * @tc.desc: test DfxSignal functions
255  * @tc.type: FUNC
256  */
257 HWTEST_F(DfxSignalTest, DfxSignalTest009, TestSize.Level2)
258 {
259     GTEST_LOG_(INFO) << "DfxSignalTest009: start.";
260     siginfo_t si = {
261         .si_signo = SIGSEGV,
262         .si_errno = 0,
263         .si_code = -1,
264         .si_value.sival_int = static_cast<int>(gettid())
265     };
266     for (auto sigKey : sigKeys) {
267         si.si_signo = sigKey.first;
268         std::map<int, std::string> codeMap;
269         switch (si.si_signo) {
270             case SIGILL:
271                 codeMap = illCode;
272                 break;
273             case SIGTRAP:
274                 codeMap = trapCode;
275                 break;
276             case SIGBUS:
277                 codeMap = busCode;
278                 break;
279             case SIGFPE:
280                 codeMap = fpeCode;
281                 break;
282             case SIGSEGV:
283                 codeMap = segvCode;
284                 break;
285             default:
286                 break;
287         }
288         for (auto& code : codeMap) {
289             std::string sigKeyword = "Signal:";
290             sigKeyword += sigKey.second;
291             si.si_code = code.first;
292             sigKeyword = sigKeyword + "(" + code.second + ")";
293             std::string sigStr = DfxSignal::PrintSignal(si) + "\n";
294             GTEST_LOG_(INFO) << sigStr;
295             ASSERT_TRUE(sigStr.find(sigKeyword) != std::string::npos);
296         }
297     }
298     GTEST_LOG_(INFO) << "DfxSignalTest009: end.";
299 }
300 }
301