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.Level2)
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 signal(SIGSEGV, SignalSegvHandler);
239 usleep(SLEEP_1000_MS);
240 usleep(SLEEP_1000_MS);
241 ASSERT_EQ(g_signalSegvFlag, true) << "SignalChainTest001: g_signalSegvFlag.";
242 _exit(0);
243 } else {
244 KillAndWaitPid(pid);
245 }
246 GTEST_LOG_(INFO) << "SignalChainTest001: end.";
247 }
248
249 /**
250 * @tc.name: SignalChainTest002
251 * @tc.desc: test SignalHandler sigaction
252 * @tc.type: FUNC
253 */
254 HWTEST_F(SignalChainTest, SignalChainTest002, TestSize.Level2)
255 {
256 GTEST_LOG_(INFO) << "SignalChainTest002: start.";
257 SignalInit();
258 pid_t pid = fork();
259 if (pid < 0) {
260 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
261 } else if (pid == 0) {
262 GTEST_LOG_(INFO) << "SignalChainTest002: pid:" << getpid();
263 struct sigaction sigsegv = {
264 .sa_handler = SignalSegvSigaction,
265 };
266 sigaction(SIGSEGV, &sigsegv, NULL);
267 usleep(SLEEP_1000_MS);
268 usleep(SLEEP_1000_MS);
269 ASSERT_EQ(g_sigactionSegvFlag, true) << "SignalChainTest002: g_sigactionSegvFlag.";
270 _exit(0);
271 } else {
272 KillAndWaitPid(pid);
273 }
274 GTEST_LOG_(INFO) << "SignalChainTest002: end.";
275 }
276
277 /**
278 * @tc.name: SignalChainTest003
279 * @tc.desc: test SignalHandler add sigchain no else signal or sigaction
280 * @tc.type: FUNC
281 */
282 HWTEST_F(SignalChainTest, SignalChainTest003, TestSize.Level2)
283 {
284 GTEST_LOG_(INFO) << "SignalChainTest003: start.";
285 SignalInit();
286 pid_t pid = fork();
287 if (pid < 0) {
288 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
289 } else if (pid == 0) {
290 GTEST_LOG_(INFO) << "SignalChainTest003: pid:" << getpid();
291 struct signal_chain_action sigchain1 = {
292 .sca_sigaction = SigchainSpecialHandlerDumpTrue,
293 .sca_mask = {},
294 .sca_flags = 0,
295 };
296 add_special_signal_handler(SIGDUMP, &sigchain1);
297 struct signal_chain_action sigsegv1 = {
298 .sca_sigaction = SigchainSpecialHandlerSegvTrue,
299 .sca_mask = {},
300 .sca_flags = 0,
301 };
302 add_special_signal_handler(SIGSEGV, &sigsegv1);
303
304 usleep(SLEEP_1000_MS);
305 ASSERT_EQ(g_sigchainDumpFlag, true) << "SignalChainTest003: g_sigchainDumpFlag.";
306 usleep(SLEEP_1000_MS);
307 ASSERT_EQ(g_sigchainSegvFlag, true) << "SignalChainTest003: g_sigchainSegvFlag.";
308 _exit(0);
309 } else {
310 KillAndWaitPid(pid);
311 }
312 GTEST_LOG_(INFO) << "SignalChainTest003: end.";
313 }
314
315 /**
316 * @tc.name: SignalChainTest004
317 * @tc.desc: test SignalHandler add sigchain and have signal handler
318 * @tc.type: FUNC
319 */
320 HWTEST_F(SignalChainTest, SignalChainTest004, TestSize.Level2)
321 {
322 GTEST_LOG_(INFO) << "SignalChainTest004: start.";
323 SignalInit();
324 pid_t pid = fork();
325 if (pid < 0) {
326 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
327 } else if (pid == 0) {
328 GTEST_LOG_(INFO) << "SignalChainTest004: pid:" << getpid();
329 signal(SIGSEGV, SignalSegvHandler);
330
331 struct signal_chain_action sigchain1 = {
332 .sca_sigaction = SigchainSpecialHandlerDump1,
333 .sca_mask = {},
334 .sca_flags = 0,
335 };
336 add_special_signal_handler(SIGDUMP, &sigchain1);
337 struct signal_chain_action sigsegv1 = {
338 .sca_sigaction = SigchainSpecialHandlerSegv1,
339 .sca_mask = {},
340 .sca_flags = 0,
341 };
342 add_special_signal_handler(SIGSEGV, &sigsegv1);
343
344 usleep(SLEEP_1000_MS);
345 ASSERT_EQ(g_sigchainDump1Flag, true) << "SignalChainTest004: g_sigchainDump1Flag.";
346 usleep(SLEEP_1000_MS);
347 ASSERT_EQ(g_signalSegvFlag, true) << "SignalChainTest004: g_signalSegvFlag.";
348 ASSERT_EQ(g_sigchainSegv1Flag, true) << "SignalChainTest004: g_sigchainSegv1Flag.";
349 _exit(0);
350 } else {
351 KillAndWaitPid(pid);
352 }
353 GTEST_LOG_(INFO) << "SignalChainTest004: end.";
354 }
355
356 /**
357 * @tc.name: SignalChainTest005
358 * @tc.desc: test SignalHandler remove sigchain
359 * @tc.type: FUNC
360 */
361 HWTEST_F(SignalChainTest, SignalChainTest005, TestSize.Level2)
362 {
363 GTEST_LOG_(INFO) << "SignalChainTest005: start.";
364 SignalInit();
365 pid_t pid = fork();
366 if (pid < 0) {
367 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
368 } else if (pid == 0) {
369 GTEST_LOG_(INFO) << "SignalChainTest005: pid:" << getpid();
370 struct signal_chain_action sigchain1 = {
371 .sca_sigaction = SigchainSpecialHandlerDump1,
372 .sca_mask = {},
373 .sca_flags = 0,
374 };
375 add_special_signal_handler(SIGDUMP, &sigchain1);
376 struct signal_chain_action sigsegv1 = {
377 .sca_sigaction = SigchainSpecialHandlerSegv1,
378 .sca_mask = {},
379 .sca_flags = 0,
380 };
381 add_special_signal_handler(SIGSEGV, &sigsegv1);
382
383 remove_special_signal_handler(SIGDUMP, SigchainSpecialHandlerDump1);
384 remove_special_signal_handler(SIGSEGV, SigchainSpecialHandlerSegv1);
385
386 struct signal_chain_action sigchain2 = {
387 .sca_sigaction = SigchainSpecialHandlerDumpTrue,
388 .sca_mask = {},
389 .sca_flags = 0,
390 };
391 add_special_signal_handler(SIGDUMP, &sigchain2);
392 struct signal_chain_action sigsegv2 = {
393 .sca_sigaction = SigchainSpecialHandlerSegvTrue,
394 .sca_mask = {},
395 .sca_flags = 0,
396 };
397 add_special_signal_handler(SIGSEGV, &sigsegv2);
398
399 usleep(SLEEP_1000_MS);
400 ASSERT_NE(g_sigchainDump1Flag, true) << "SignalChainTest005: g_sigchainDump1Flag.";
401 ASSERT_EQ(g_sigchainDumpFlag, true) << "SignalChainTest005: g_sigchainDumpFlag.";
402 usleep(SLEEP_1000_MS);
403 ASSERT_NE(g_sigchainSegv1Flag, true) << "SignalChainTest005: g_sigchainSegv1Flag.";
404 ASSERT_EQ(g_sigchainSegvFlag, true) << "SignalChainTest005: g_sigchainSegvFlag.";
405 _exit(0);
406 } else {
407 KillAndWaitPid(pid);
408 }
409 GTEST_LOG_(INFO) << "SignalChainTest005: end.";
410 }
411
412 /**
413 * @tc.name: SignalChainTest006
414 * @tc.desc: test SignalHandler remove all sigchain
415 * @tc.type: FUNC
416 */
417 HWTEST_F(SignalChainTest, SignalChainTest006, TestSize.Level2)
418 {
419 GTEST_LOG_(INFO) << "SignalChainTest006: start.";
420 SignalInit();
421 pid_t pid = fork();
422 if (pid < 0) {
423 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
424 } else if (pid == 0) {
425 GTEST_LOG_(INFO) << "SignalChainTest006: pid:" << getpid();
426 signal(SIGDUMP, SignalDumpHandler);
427 signal(SIGSEGV, SignalSegvHandler);
428
429 struct signal_chain_action sigchain1 = {
430 .sca_sigaction = SigchainSpecialHandlerDump1,
431 .sca_mask = {},
432 .sca_flags = 0,
433 };
434 add_special_signal_handler(SIGDUMP, &sigchain1);
435
436 struct signal_chain_action sigsegv1 = {
437 .sca_sigaction = SigchainSpecialHandlerSegv1,
438 .sca_mask = {},
439 .sca_flags = 0,
440 };
441 add_special_signal_handler(SIGSEGV, &sigsegv1);
442
443 remove_all_special_handler(SIGDUMP);
444 remove_all_special_handler(SIGSEGV);
445
446 usleep(SLEEP_1000_MS);
447 ASSERT_NE(g_sigchainDump1Flag, true) << "SignalChainTest006: g_sigchainDump1Flag.";
448 ASSERT_NE(g_sigchainDump2Flag, true) << "SignalChainTest006: g_sigchainDump2Flag.";
449 ASSERT_EQ(g_signalDumpFlag, true) << "SignalChainTest006: g_signalDumpFlag.";
450 usleep(SLEEP_1000_MS);
451 ASSERT_NE(g_sigchainSegv1Flag, true) << "SignalChainTest006: g_sigchainSegv1Flag.";
452 ASSERT_NE(g_sigchainSegv2Flag, true) << "SignalChainTest006: g_sigchainSegv2Flag.";
453 ASSERT_EQ(g_signalSegvFlag, true) << "SignalChainTest006: g_signalSegvFlag.";
454 _exit(0);
455 } else {
456 KillAndWaitPid(pid);
457 }
458 GTEST_LOG_(INFO) << "SignalChainTest006: end.";
459 }
460
461 /**
462 * @tc.name: SignalChainTest007
463 * @tc.desc: test SignalHandler run C++ code in sigchain handler
464 * @tc.type: FUNC
465 */
466 HWTEST_F(SignalChainTest, SignalChainTest007, TestSize.Level2)
467 {
468 GTEST_LOG_(INFO) << "SignalChainTest007: start.";
469 SignalInit();
470 pid_t pid = fork();
471 if (pid < 0) {
472 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
473 } else if (pid == 0) {
474 GTEST_LOG_(INFO) << "SignalChainTest007: pid:" << getpid();
475 remove_all_special_handler(SIGDUMP);
476 remove_all_special_handler(SIGSEGV);
477
478 struct signal_chain_action sigchain1 = {
479 .sca_sigaction = SigchainSpecialHandlerDump1,
480 .sca_mask = {},
481 .sca_flags = 0,
482 };
483 add_special_signal_handler(SIGDUMP, &sigchain1);
484 struct signal_chain_action sigchain2 = {
485 .sca_sigaction = &(MixStackDumper::DumpSignalHandler),
486 .sca_mask = {},
487 .sca_flags = 0,
488 };
489 add_special_signal_handler(SIGDUMP, &sigchain2);
490
491 struct signal_chain_action sigsegv1 = {
492 .sca_sigaction = SigchainSpecialHandlerSegv1,
493 .sca_mask = {},
494 .sca_flags = 0,
495 };
496 add_special_signal_handler(SIGSEGV, &sigsegv1);
497 struct signal_chain_action sigsegv2 = {
498 .sca_sigaction = MixStackDumper::SegvSignalHandler,
499 .sca_mask = {},
500 .sca_flags = 0,
501 };
502 add_special_signal_handler(SIGSEGV, &sigsegv2);
503
504 usleep(SLEEP_1000_MS);
505 ASSERT_EQ(g_sigchainDump1Flag, true) << "SignalChainTest007: g_sigchainDump1Flag.";
506 ASSERT_EQ(g_sigchainDump2Flag, true) << "SignalChainTest007: g_sigchainDump2Flag.";
507 usleep(SLEEP_1000_MS);
508 ASSERT_EQ(g_sigchainSegv1Flag, true) << "SignalChainTest007: g_sigchainSegv1Flag.";
509 ASSERT_EQ(g_sigchainSegv2Flag, true) << "SignalChainTest007: g_sigchainSegv2Flag.";
510 _exit(0);
511 } else {
512 KillAndWaitPid(pid);
513 }
514 GTEST_LOG_(INFO) << "SignalChainTest007: end.";
515 }
516
517 /**
518 * @tc.name: SignalChainTest008
519 * @tc.desc: test SignalHandler add_special_handler_at_last
520 * @tc.type: FUNC
521 */
522 HWTEST_F(SignalChainTest, SignalChainTest008, TestSize.Level2)
523 {
524 GTEST_LOG_(INFO) << "SignalChainTest008: start.";
525 SignalInit();
526 pid_t pid = fork();
527 if (pid < 0) {
528 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
529 } else if (pid == 0) {
530 GTEST_LOG_(INFO) << "SignalChainTest008: pid:" << getpid();
531 remove_all_special_handler(SIGDUMP);
532 remove_all_special_handler(SIGSEGV);
533
534 struct signal_chain_action sigchain2 = {
535 .sca_sigaction = SigchainSpecialHandlerDumpTrue,
536 .sca_mask = {},
537 .sca_flags = 0,
538 };
539 add_special_handler_at_last(SIGDUMP, &sigchain2);
540
541 struct signal_chain_action sigchain1 = {
542 .sca_sigaction = SigchainSpecialHandlerDump1,
543 .sca_mask = {},
544 .sca_flags = 0,
545 };
546 add_special_signal_handler(SIGDUMP, &sigchain1);
547
548 struct signal_chain_action sigsegv2 = {
549 .sca_sigaction = SigchainSpecialHandlerSegvTrue,
550 .sca_mask = {},
551 .sca_flags = 0,
552 };
553 add_special_handler_at_last(SIGSEGV, &sigsegv2);
554 struct signal_chain_action sigsegv1 = {
555 .sca_sigaction = SigchainSpecialHandlerSegv1,
556 .sca_mask = {},
557 .sca_flags = 0,
558 };
559 add_special_signal_handler(SIGSEGV, &sigsegv1);
560
561 ResetCount();
562 usleep(SLEEP_1000_MS);
563 ASSERT_EQ(g_sigchainDump1Flag, true) << "SignalChainTest008: g_sigchainDump1Flag.";
564 ASSERT_EQ(g_sigchainDumpFlag, true) << "SignalChainTest008: g_sigchainDumpFlag.";
565 ASSERT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SignalChainTest008: dump g_count.";
566 ResetCount();
567 usleep(SLEEP_1000_MS);
568 ASSERT_EQ(g_sigchainSegv1Flag, true) << "SignalChainTest008: g_sigchainSegv1Flag.";
569 ASSERT_EQ(g_sigchainSegvFlag, true) << "SignalChainTest008: g_sigchainSegvFlag.";
570 ASSERT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SignalChainTest008: segv g_count.";
571 _exit(0);
572 } else {
573 KillAndWaitPid(pid);
574 }
575 GTEST_LOG_(INFO) << "SignalChainTest008: end.";
576 }
577
578 /**
579 * @tc.name: SignalChainTest009
580 * @tc.desc: test SignalHandler special signal(SIGILL)
581 * @tc.type: FUNC
582 */
583 HWTEST_F(SignalChainTest, SignalChainTest009, TestSize.Level2)
584 {
585 GTEST_LOG_(INFO) << "SignalChainTest009: start.";
586 SignalInit();
587 pid_t pid = fork();
588 if (pid < 0) {
589 GTEST_LOG_(ERROR) << "Failed to fork new test process.";
590 } else if (pid == 0) {
591 GTEST_LOG_(INFO) << "SignalChainTest009: pid:" << getpid();
592 struct sigaction sigill = {
593 .sa_handler = SignalIllSigaction,
594 };
595 sigaction(SIGILL, &sigill, NULL);
596 usleep(SLEEP_1000_MS);
597 ASSERT_EQ(g_sigactionIllFlag, true) << "SignalChainTest009: g_sigactionIllFlag.";
598 _exit(0);
599 } else {
600 usleep(SLEEP_10_MS);
601 kill(pid, SIGILL);
602 usleep(SLEEP_1000_MS);
603 int status;
604 waitpid(pid, &status, 0);
605 }
606 GTEST_LOG_(INFO) << "SignalChainTest009: end.";
607 }
608 } // namespace HiviewDFX
609 } // namepsace OHOS
610