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 <sigchain.h>
18
19 #include "dfx_define.h"
20
21 using namespace testing;
22 using namespace testing::ext;
23 using namespace std;
24
25 namespace OHOS {
26 namespace HiviewDFX {
27 class SignalChainTest : public testing::Test {
28 public:
SetUpTestCase()29 static void SetUpTestCase() {}
TearDownTestCase()30 static void TearDownTestCase() {}
SetUp()31 void SetUp() {}
TearDown()32 void TearDown() {}
33 };
34
35 #define SIGCHIAN_TEST_SIGNAL_NUM_1 1
36 #define SIGCHIAN_TEST_SIGNAL_NUM_2 2
37
38 static const int TEST_PTR_VALUE = 10;
39 static const int SLEEP_10_MS = 10000;
40 static const int SLEEP_1000_MS = 1000000;
41 static const int SLEEP_2000_MS = 2000000;
42
43 static int g_count = 0;
44 static bool g_testLastFlag = false;
45 static bool g_signalDumpFlag = false;
46 static bool g_signalSegvFlag = false;
47 static bool g_sigactionDumpFlag = false;
48 static bool g_sigactionSegvFlag = false;
49 static bool g_sigactionIllFlag = false;
50 static bool g_sigchainDumpFlag = false;
51 static bool g_sigchainDump1Flag = false;
52 static bool g_sigchainDump2Flag = false;
53 static bool g_sigchainSegvFlag = false;
54 static bool g_sigchainSegv1Flag = false;
55 static bool g_sigchainSegv2Flag = false;
56
ResetCount()57 static void ResetCount()
58 {
59 g_count = 0;
60 g_testLastFlag = true;
61 }
62
SignalInit()63 static void SignalInit()
64 {
65 g_testLastFlag = false;
66 g_signalDumpFlag = false;
67 g_signalSegvFlag = false;
68 g_sigactionDumpFlag = false;
69 g_sigactionSegvFlag = false;
70 g_sigactionIllFlag = false;
71 g_sigchainDumpFlag = false;
72 g_sigchainDump1Flag = false;
73 g_sigchainDump2Flag = false;
74 g_sigchainSegvFlag = false;
75 g_sigchainSegv1Flag = false;
76 g_sigchainSegv2Flag = false;
77 }
78
SignalDumpHandler(int signo)79 AT_UNUSED static void SignalDumpHandler(int signo)
80 {
81 GTEST_LOG_(INFO) << "SignalDumpHandler";
82 g_signalDumpFlag = true;
83 EXPECT_EQ(signo, SIGDUMP) << "SignalDumpHandler Failed";
84 }
85
SignalSegvHandler(int signo)86 AT_UNUSED static void SignalSegvHandler(int signo)
87 {
88 GTEST_LOG_(INFO) << "SignalSegvHandler";
89 g_signalSegvFlag = true;
90 EXPECT_EQ(signo, SIGSEGV) << "SignalSegvHandler Failed";
91 }
92
SignalDumpSigaction(int signo)93 AT_UNUSED static void SignalDumpSigaction(int signo)
94 {
95 GTEST_LOG_(INFO) << "SignalDumpSigaction";
96 g_sigactionDumpFlag = true;
97 EXPECT_EQ(signo, SIGDUMP) << "SignalDumpSigaction Failed";
98 }
99
SignalSegvSigaction(int signo)100 AT_UNUSED static void SignalSegvSigaction(int signo)
101 {
102 GTEST_LOG_(INFO) << "SignalSegvSigaction";
103 g_sigactionSegvFlag = true;
104 EXPECT_EQ(signo, SIGSEGV) << "SignalSegvSigaction Failed";
105 }
106
SignalIllSigaction(int signo)107 AT_UNUSED static void SignalIllSigaction(int signo)
108 {
109 GTEST_LOG_(INFO) << "SignalIllSigaction";
110 g_sigactionIllFlag = true;
111 EXPECT_EQ(signo, SIGILL) << "SignalIllSigaction Failed";
112 }
113
SigchainSpecialHandlerDumpTrue(int signo,siginfo_t * si,void * ucontext)114 AT_UNUSED static bool SigchainSpecialHandlerDumpTrue(int signo, siginfo_t *si, void *ucontext)
115 {
116 GTEST_LOG_(INFO) << "SigchainSpecialHandlerDumpTrue";
117 g_sigchainDumpFlag = true;
118 EXPECT_EQ(signo, SIGDUMP) << "SigchainSpecialHandlerDumpTrue Failed";
119 if (g_testLastFlag) {
120 g_count++;
121 EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SigchainSpecialHandlerDumpTrue: g_count.";
122 }
123 return true;
124 }
125
SigchainSpecialHandlerDump1(int signo,siginfo_t * si,void * ucontext)126 AT_UNUSED static bool SigchainSpecialHandlerDump1(int signo, siginfo_t *si, void *ucontext)
127 {
128 GTEST_LOG_(INFO) << "SigchainSpecialHandlerDump1";
129 g_sigchainDump1Flag = true;
130 EXPECT_EQ(signo, SIGDUMP) << "SigchainSpecialHandlerDump1 Failed";
131 if (g_testLastFlag) {
132 g_count++;
133 EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_1) << "SigchainSpecialHandlerDump1: g_count.";
134 }
135 return false;
136 }
137
SigchainSpecialHandlerDump2(int signo,siginfo_t * si,void * ucontext)138 AT_UNUSED static bool SigchainSpecialHandlerDump2(int signo, siginfo_t *si, void *ucontext)
139 {
140 GTEST_LOG_(INFO) << "SigchainSpecialHandlerDump2";
141 g_sigchainDump2Flag = true;
142 EXPECT_EQ(signo, SIGDUMP) << "SigchainSpecialHandlerDump2 Failed";
143 if (g_testLastFlag) {
144 g_count++;
145 EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SigchainSpecialHandlerDump2: g_count.";
146 }
147 return false;
148 }
149
SigchainSpecialHandlerSegvTrue(int signo,siginfo_t * si,void * ucontext)150 AT_UNUSED static bool SigchainSpecialHandlerSegvTrue(int signo, siginfo_t *si, void *ucontext)
151 {
152 GTEST_LOG_(INFO) << "SigchainSpecialHandlerSegvTrue";
153 g_sigchainSegvFlag = true;
154 EXPECT_EQ(signo, SIGSEGV) << "SigchainSpecialHandlerSegvTrue Failed";
155 if (g_testLastFlag) {
156 g_count++;
157 EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SigchainSpecialHandlerSegvTrue: g_count.";
158 }
159 return true;
160 }
161
SigchainSpecialHandlerSegv1(int signo,siginfo_t * si,void * ucontext)162 AT_UNUSED static bool SigchainSpecialHandlerSegv1(int signo, siginfo_t *si, void *ucontext)
163 {
164 GTEST_LOG_(INFO) << "SigchainSpecialHandlerSegv1";
165 g_sigchainSegv1Flag = true;
166 EXPECT_EQ(signo, SIGSEGV) << "SigchainSpecialHandlerSegv1 Failed";
167 if (g_testLastFlag) {
168 g_count++;
169 EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_1) << "SigchainSpecialHandlerSegv1: g_count.";
170 }
171 return false;
172 }
173
SigchainSpecialHandlerSegv2(int signo,siginfo_t * si,void * ucontext)174 AT_UNUSED static bool SigchainSpecialHandlerSegv2(int signo, siginfo_t *si, void *ucontext)
175 {
176 GTEST_LOG_(INFO) << "SigchainSpecialHandlerSegv2";
177 g_sigchainSegv2Flag = true;
178 EXPECT_EQ(signo, SIGSEGV) << "SigchainSpecialHandlerSegv2 Failed";
179 if (g_testLastFlag) {
180 g_count++;
181 EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SigchainSpecialHandlerSegv2: g_count.";
182 }
183 return false;
184 }
185
186 class MixStackDumper {
187 public:
188 MixStackDumper() = default;
189 ~MixStackDumper() = default;
DumpSignalHandler(int signo,siginfo_t * si,void * ucontext)190 AT_UNUSED static bool DumpSignalHandler(int signo, siginfo_t *si, void *ucontext)
191 {
192 std::shared_ptr<int> ptr = std::make_shared<int>(TEST_PTR_VALUE);
193 GTEST_LOG_(INFO) << "DumpSignalHandler: " << ptr.use_count();
194 g_sigchainDump2Flag = true;
195 EXPECT_EQ(signo, SIGDUMP) << "DumpSignalHandler Failed";
196 return true;
197 }
198
SegvSignalHandler(int signo,siginfo_t * si,void * ucontext)199 AT_UNUSED static bool SegvSignalHandler(int signo, siginfo_t *si, void *ucontext)
200 {
201 std::shared_ptr<int> ptr = std::make_shared<int>(TEST_PTR_VALUE);
202 GTEST_LOG_(INFO) << "SegvSignalHandler: " << ptr.use_count();
203 g_sigchainSegv2Flag = true;
204 EXPECT_EQ(signo, SIGSEGV) << "SegvSignalHandler Failed";
205 return false;
206 }
207 };
208
KillAndWaitPid(int pid)209 static int KillAndWaitPid(int pid)
210 {
211 usleep(SLEEP_10_MS);
212 GTEST_LOG_(INFO) << "kill SIGDUMP pid: " << pid;
213 kill(pid, SIGDUMP);
214 usleep(SLEEP_10_MS);
215 GTEST_LOG_(INFO) << "kill SIGSEGV pid: " << pid;
216 kill(pid, SIGSEGV);
217 usleep(SLEEP_2000_MS);
218 int status;
219 int ret = waitpid(pid, &status, 0);
220 GTEST_LOG_(INFO) << "waitpid: " << pid << ", ret: "<< ret << std::endl;
221 return ret;
222 }
223
224 /**
225 * @tc.name: SignalChainTest001
226 * @tc.desc: test SignalHandler signal
227 * @tc.type: FUNC
228 */
229 HWTEST_F(SignalChainTest, SignalChainTest001, TestSize.Level0)
230 {
231 GTEST_LOG_(INFO) << "SignalChainTest001: start.";
232 SignalInit();
233 pid_t pid = fork();
234 if (pid < 0) {
235 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
236 } else if (pid == 0) {
237 GTEST_LOG_(INFO) << "SignalChainTest001: pid:" << getpid();
238 remove_all_special_handler(SIGDUMP);
239 remove_all_special_handler(SIGSEGV);
240 signal(SIGSEGV, SignalSegvHandler);
241 usleep(SLEEP_1000_MS);
242 usleep(SLEEP_1000_MS);
243 EXPECT_EQ(g_signalSegvFlag, true) << "SignalChainTest001: g_signalSegvFlag.";
244 _exit(0);
245 } else {
246 KillAndWaitPid(pid);
247 }
248 GTEST_LOG_(INFO) << "SignalChainTest001: end.";
249 }
250
251 /**
252 * @tc.name: SignalChainTest002
253 * @tc.desc: test SignalHandler sigaction
254 * @tc.type: FUNC
255 */
256 HWTEST_F(SignalChainTest, SignalChainTest002, TestSize.Level2)
257 {
258 GTEST_LOG_(INFO) << "SignalChainTest002: start.";
259 SignalInit();
260 pid_t pid = fork();
261 if (pid < 0) {
262 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
263 } else if (pid == 0) {
264 GTEST_LOG_(INFO) << "SignalChainTest002: pid:" << getpid();
265 remove_all_special_handler(SIGDUMP);
266 remove_all_special_handler(SIGSEGV);
267 struct sigaction sigsegv = {
268 .sa_handler = SignalSegvSigaction,
269 };
270 sigaction(SIGSEGV, &sigsegv, NULL);
271 usleep(SLEEP_1000_MS);
272 usleep(SLEEP_1000_MS);
273 ASSERT_EQ(g_sigactionSegvFlag, true) << "SignalChainTest002: g_sigactionSegvFlag.";
274 _exit(0);
275 } else {
276 KillAndWaitPid(pid);
277 }
278 GTEST_LOG_(INFO) << "SignalChainTest002: end.";
279 }
280
281 /**
282 * @tc.name: SignalChainTest003
283 * @tc.desc: test SignalHandler add sigchain no else signal or sigaction
284 * @tc.type: FUNC
285 */
286 HWTEST_F(SignalChainTest, SignalChainTest003, TestSize.Level2)
287 {
288 GTEST_LOG_(INFO) << "SignalChainTest003: start.";
289 SignalInit();
290 pid_t pid = fork();
291 if (pid < 0) {
292 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
293 } else if (pid == 0) {
294 GTEST_LOG_(INFO) << "SignalChainTest003: pid:" << getpid();
295 remove_all_special_handler(SIGDUMP);
296 remove_all_special_handler(SIGSEGV);
297 struct signal_chain_action sigchain1 = {
298 .sca_sigaction = SigchainSpecialHandlerDumpTrue,
299 .sca_mask = {},
300 .sca_flags = 0,
301 };
302 add_special_signal_handler(SIGDUMP, &sigchain1);
303 struct signal_chain_action sigsegv1 = {
304 .sca_sigaction = SigchainSpecialHandlerSegvTrue,
305 .sca_mask = {},
306 .sca_flags = 0,
307 };
308 add_special_signal_handler(SIGSEGV, &sigsegv1);
309
310 usleep(SLEEP_1000_MS);
311 ASSERT_EQ(g_sigchainDumpFlag, true) << "SignalChainTest003: g_sigchainDumpFlag.";
312 usleep(SLEEP_1000_MS);
313 ASSERT_EQ(g_sigchainSegvFlag, true) << "SignalChainTest003: g_sigchainSegvFlag.";
314 _exit(0);
315 } else {
316 KillAndWaitPid(pid);
317 }
318 GTEST_LOG_(INFO) << "SignalChainTest003: end.";
319 }
320
321 /**
322 * @tc.name: SignalChainTest004
323 * @tc.desc: test SignalHandler add sigchain and have signal handler
324 * @tc.type: FUNC
325 */
326 HWTEST_F(SignalChainTest, SignalChainTest004, TestSize.Level2)
327 {
328 GTEST_LOG_(INFO) << "SignalChainTest004: start.";
329 SignalInit();
330 pid_t pid = fork();
331 if (pid < 0) {
332 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
333 } else if (pid == 0) {
334 GTEST_LOG_(INFO) << "SignalChainTest004: pid:" << getpid();
335 remove_all_special_handler(SIGDUMP);
336 remove_all_special_handler(SIGSEGV);
337 signal(SIGSEGV, SignalSegvHandler);
338
339 struct signal_chain_action sigchain1 = {
340 .sca_sigaction = SigchainSpecialHandlerDump1,
341 .sca_mask = {},
342 .sca_flags = 0,
343 };
344 add_special_signal_handler(SIGDUMP, &sigchain1);
345 struct signal_chain_action sigsegv1 = {
346 .sca_sigaction = SigchainSpecialHandlerSegv1,
347 .sca_mask = {},
348 .sca_flags = 0,
349 };
350 add_special_signal_handler(SIGSEGV, &sigsegv1);
351
352 usleep(SLEEP_1000_MS);
353 ASSERT_EQ(g_sigchainDump1Flag, true) << "SignalChainTest004: g_sigchainDump1Flag.";
354 usleep(SLEEP_1000_MS);
355 ASSERT_EQ(g_signalSegvFlag, true) << "SignalChainTest004: g_signalSegvFlag.";
356 ASSERT_EQ(g_sigchainSegv1Flag, true) << "SignalChainTest004: g_sigchainSegv1Flag.";
357 _exit(0);
358 } else {
359 KillAndWaitPid(pid);
360 }
361 GTEST_LOG_(INFO) << "SignalChainTest004: end.";
362 }
363
364 /**
365 * @tc.name: SignalChainTest005
366 * @tc.desc: test SignalHandler remove sigchain
367 * @tc.type: FUNC
368 */
369 HWTEST_F(SignalChainTest, SignalChainTest005, TestSize.Level2)
370 {
371 GTEST_LOG_(INFO) << "SignalChainTest005: start.";
372 SignalInit();
373 pid_t pid = fork();
374 if (pid < 0) {
375 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
376 } else if (pid == 0) {
377 GTEST_LOG_(INFO) << "SignalChainTest005: pid:" << getpid();
378 struct signal_chain_action sigchain1 = {
379 .sca_sigaction = SigchainSpecialHandlerDump1,
380 .sca_mask = {},
381 .sca_flags = 0,
382 };
383 add_special_signal_handler(SIGDUMP, &sigchain1);
384 struct signal_chain_action sigsegv1 = {
385 .sca_sigaction = SigchainSpecialHandlerSegv1,
386 .sca_mask = {},
387 .sca_flags = 0,
388 };
389 add_special_signal_handler(SIGSEGV, &sigsegv1);
390
391 remove_special_signal_handler(SIGDUMP, SigchainSpecialHandlerDump1);
392 remove_special_signal_handler(SIGSEGV, SigchainSpecialHandlerSegv1);
393
394 struct signal_chain_action sigchain2 = {
395 .sca_sigaction = SigchainSpecialHandlerDumpTrue,
396 .sca_mask = {},
397 .sca_flags = 0,
398 };
399 add_special_signal_handler(SIGDUMP, &sigchain2);
400 struct signal_chain_action sigsegv2 = {
401 .sca_sigaction = SigchainSpecialHandlerSegvTrue,
402 .sca_mask = {},
403 .sca_flags = 0,
404 };
405 add_special_signal_handler(SIGSEGV, &sigsegv2);
406
407 usleep(SLEEP_1000_MS);
408 ASSERT_NE(g_sigchainDump1Flag, true) << "SignalChainTest005: g_sigchainDump1Flag.";
409 ASSERT_EQ(g_sigchainDumpFlag, true) << "SignalChainTest005: g_sigchainDumpFlag.";
410 usleep(SLEEP_1000_MS);
411 ASSERT_NE(g_sigchainSegv1Flag, true) << "SignalChainTest005: g_sigchainSegv1Flag.";
412 ASSERT_EQ(g_sigchainSegvFlag, true) << "SignalChainTest005: g_sigchainSegvFlag.";
413 _exit(0);
414 } else {
415 KillAndWaitPid(pid);
416 }
417 GTEST_LOG_(INFO) << "SignalChainTest005: end.";
418 }
419
420 /**
421 * @tc.name: SignalChainTest006
422 * @tc.desc: test SignalHandler remove all sigchain
423 * @tc.type: FUNC
424 */
425 HWTEST_F(SignalChainTest, SignalChainTest006, TestSize.Level2)
426 {
427 GTEST_LOG_(INFO) << "SignalChainTest006: start.";
428 SignalInit();
429 pid_t pid = fork();
430 if (pid < 0) {
431 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
432 } else if (pid == 0) {
433 GTEST_LOG_(INFO) << "SignalChainTest006: pid:" << getpid();
434 signal(SIGDUMP, SignalDumpHandler);
435 signal(SIGSEGV, SignalSegvHandler);
436
437 struct signal_chain_action sigchain1 = {
438 .sca_sigaction = SigchainSpecialHandlerDump1,
439 .sca_mask = {},
440 .sca_flags = 0,
441 };
442 add_special_signal_handler(SIGDUMP, &sigchain1);
443
444 struct signal_chain_action sigsegv1 = {
445 .sca_sigaction = SigchainSpecialHandlerSegv1,
446 .sca_mask = {},
447 .sca_flags = 0,
448 };
449 add_special_signal_handler(SIGSEGV, &sigsegv1);
450
451 remove_all_special_handler(SIGDUMP);
452 remove_all_special_handler(SIGSEGV);
453
454 usleep(SLEEP_1000_MS);
455 ASSERT_NE(g_sigchainDump1Flag, true) << "SignalChainTest006: g_sigchainDump1Flag.";
456 ASSERT_NE(g_sigchainDump2Flag, true) << "SignalChainTest006: g_sigchainDump2Flag.";
457 ASSERT_EQ(g_signalDumpFlag, true) << "SignalChainTest006: g_signalDumpFlag.";
458 usleep(SLEEP_1000_MS);
459 ASSERT_NE(g_sigchainSegv1Flag, true) << "SignalChainTest006: g_sigchainSegv1Flag.";
460 ASSERT_NE(g_sigchainSegv2Flag, true) << "SignalChainTest006: g_sigchainSegv2Flag.";
461 ASSERT_EQ(g_signalSegvFlag, true) << "SignalChainTest006: g_signalSegvFlag.";
462 _exit(0);
463 } else {
464 KillAndWaitPid(pid);
465 }
466 GTEST_LOG_(INFO) << "SignalChainTest006: end.";
467 }
468
469 /**
470 * @tc.name: SignalChainTest007
471 * @tc.desc: test SignalHandler run C++ code in sigchain handler
472 * @tc.type: FUNC
473 */
474 HWTEST_F(SignalChainTest, SignalChainTest007, TestSize.Level2)
475 {
476 GTEST_LOG_(INFO) << "SignalChainTest007: start.";
477 SignalInit();
478 pid_t pid = fork();
479 if (pid < 0) {
480 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
481 } else if (pid == 0) {
482 GTEST_LOG_(INFO) << "SignalChainTest007: pid:" << getpid();
483 remove_all_special_handler(SIGDUMP);
484 remove_all_special_handler(SIGSEGV);
485
486 struct signal_chain_action sigchain1 = {
487 .sca_sigaction = SigchainSpecialHandlerDump1,
488 .sca_mask = {},
489 .sca_flags = 0,
490 };
491 add_special_signal_handler(SIGDUMP, &sigchain1);
492 struct signal_chain_action sigchain2 = {
493 .sca_sigaction = &(MixStackDumper::DumpSignalHandler),
494 .sca_mask = {},
495 .sca_flags = 0,
496 };
497 add_special_signal_handler(SIGDUMP, &sigchain2);
498
499 struct signal_chain_action sigsegv1 = {
500 .sca_sigaction = SigchainSpecialHandlerSegv1,
501 .sca_mask = {},
502 .sca_flags = 0,
503 };
504 add_special_signal_handler(SIGSEGV, &sigsegv1);
505 struct signal_chain_action sigsegv2 = {
506 .sca_sigaction = MixStackDumper::SegvSignalHandler,
507 .sca_mask = {},
508 .sca_flags = 0,
509 };
510 add_special_signal_handler(SIGSEGV, &sigsegv2);
511
512 usleep(SLEEP_1000_MS);
513 ASSERT_EQ(g_sigchainDump1Flag, true) << "SignalChainTest007: g_sigchainDump1Flag.";
514 ASSERT_EQ(g_sigchainDump2Flag, true) << "SignalChainTest007: g_sigchainDump2Flag.";
515 usleep(SLEEP_1000_MS);
516 ASSERT_EQ(g_sigchainSegv1Flag, true) << "SignalChainTest007: g_sigchainSegv1Flag.";
517 ASSERT_EQ(g_sigchainSegv2Flag, true) << "SignalChainTest007: g_sigchainSegv2Flag.";
518 _exit(0);
519 } else {
520 KillAndWaitPid(pid);
521 }
522 GTEST_LOG_(INFO) << "SignalChainTest007: end.";
523 }
524
525 /**
526 * @tc.name: SignalChainTest008
527 * @tc.desc: test SignalHandler add_special_handler_at_last
528 * @tc.type: FUNC
529 */
530 HWTEST_F(SignalChainTest, SignalChainTest008, TestSize.Level2)
531 {
532 GTEST_LOG_(INFO) << "SignalChainTest008: start.";
533 SignalInit();
534 pid_t pid = fork();
535 if (pid < 0) {
536 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
537 } else if (pid == 0) {
538 GTEST_LOG_(INFO) << "SignalChainTest008: pid:" << getpid();
539 remove_all_special_handler(SIGDUMP);
540 remove_all_special_handler(SIGSEGV);
541
542 struct signal_chain_action sigchain2 = {
543 .sca_sigaction = SigchainSpecialHandlerDumpTrue,
544 .sca_mask = {},
545 .sca_flags = 0,
546 };
547 add_special_handler_at_last(SIGDUMP, &sigchain2);
548
549 struct signal_chain_action sigchain1 = {
550 .sca_sigaction = SigchainSpecialHandlerDump1,
551 .sca_mask = {},
552 .sca_flags = 0,
553 };
554 add_special_signal_handler(SIGDUMP, &sigchain1);
555
556 struct signal_chain_action sigsegv2 = {
557 .sca_sigaction = SigchainSpecialHandlerSegvTrue,
558 .sca_mask = {},
559 .sca_flags = 0,
560 };
561 add_special_handler_at_last(SIGSEGV, &sigsegv2);
562 struct signal_chain_action sigsegv1 = {
563 .sca_sigaction = SigchainSpecialHandlerSegv1,
564 .sca_mask = {},
565 .sca_flags = 0,
566 };
567 add_special_signal_handler(SIGSEGV, &sigsegv1);
568
569 ResetCount();
570 usleep(SLEEP_1000_MS);
571 ASSERT_EQ(g_sigchainDump1Flag, true) << "SignalChainTest008: g_sigchainDump1Flag.";
572 ASSERT_EQ(g_sigchainDumpFlag, true) << "SignalChainTest008: g_sigchainDumpFlag.";
573 ASSERT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SignalChainTest008: dump g_count.";
574 ResetCount();
575 usleep(SLEEP_1000_MS);
576 ASSERT_EQ(g_sigchainSegv1Flag, true) << "SignalChainTest008: g_sigchainSegv1Flag.";
577 ASSERT_EQ(g_sigchainSegvFlag, true) << "SignalChainTest008: g_sigchainSegvFlag.";
578 ASSERT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SignalChainTest008: segv g_count.";
579 _exit(0);
580 } else {
581 KillAndWaitPid(pid);
582 }
583 GTEST_LOG_(INFO) << "SignalChainTest008: end.";
584 }
585
586 /**
587 * @tc.name: SignalChainTest009
588 * @tc.desc: test SignalHandler special signal(SIGILL)
589 * @tc.type: FUNC
590 */
591 HWTEST_F(SignalChainTest, SignalChainTest009, TestSize.Level2)
592 {
593 GTEST_LOG_(INFO) << "SignalChainTest009: start.";
594 SignalInit();
595 pid_t pid = fork();
596 if (pid < 0) {
597 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
598 } else if (pid == 0) {
599 GTEST_LOG_(INFO) << "SignalChainTest009: pid:" << getpid();
600 struct sigaction sigill = {
601 .sa_handler = SignalIllSigaction,
602 };
603 sigaction(SIGILL, &sigill, NULL);
604 usleep(SLEEP_1000_MS);
605 ASSERT_EQ(g_sigactionIllFlag, true) << "SignalChainTest009: g_sigactionIllFlag.";
606 _exit(0);
607 } else {
608 usleep(SLEEP_10_MS);
609 kill(pid, SIGILL);
610 usleep(SLEEP_1000_MS);
611 int status;
612 waitpid(pid, &status, 0);
613 }
614 GTEST_LOG_(INFO) << "SignalChainTest009: end.";
615 }
616 } // namespace HiviewDFX
617 } // namepsace OHOS
618