• 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 <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