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