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
21using namespace testing;
22using namespace testing::ext;
23using namespace std;
24
25namespace OHOS {
26namespace HiviewDFX {
27class SignalChainTest : public testing::Test {
28public:
29    static void SetUpTestCase() {}
30    static void TearDownTestCase() {}
31    void SetUp() {}
32    void TearDown() {}
33};
34
35#define SIGCHIAN_TEST_SIGNAL_NUM_1 1
36#define SIGCHIAN_TEST_SIGNAL_NUM_2 2
37
38static const int TEST_PTR_VALUE = 10;
39static const int SLEEP_10_MS = 10000;
40static const int SLEEP_1000_MS = 1000000;
41static const int SLEEP_2000_MS = 2000000;
42
43static int g_count = 0;
44static bool g_testLastFlag = false;
45static bool g_signalDumpFlag = false;
46static bool g_signalSegvFlag = false;
47static bool g_sigactionDumpFlag = false;
48static bool g_sigactionSegvFlag = false;
49static bool g_sigactionIllFlag = false;
50static bool g_sigchainDumpFlag = false;
51static bool g_sigchainDump1Flag = false;
52static bool g_sigchainDump2Flag = false;
53static bool g_sigchainSegvFlag = false;
54static bool g_sigchainSegv1Flag = false;
55static bool g_sigchainSegv2Flag = false;
56
57static void ResetCount()
58{
59    g_count = 0;
60    g_testLastFlag = true;
61}
62
63static 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
79AT_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
86AT_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
93AT_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
100AT_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
107AT_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
114AT_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
126AT_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
138AT_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
150AT_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
162AT_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
174AT_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
186class MixStackDumper {
187public:
188    MixStackDumper() = default;
189    ~MixStackDumper() = default;
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
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
209static 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 */
229HWTEST_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 */
254HWTEST_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 */
282HWTEST_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 */
320HWTEST_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 */
361HWTEST_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 */
417HWTEST_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 */
466HWTEST_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 */
522HWTEST_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 */
583HWTEST_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