1800b99b8Sopenharmony_ci/*
2800b99b8Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License.
5800b99b8Sopenharmony_ci * You may obtain a copy of the License at
6800b99b8Sopenharmony_ci *
7800b99b8Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8800b99b8Sopenharmony_ci *
9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and
13800b99b8Sopenharmony_ci * limitations under the License.
14800b99b8Sopenharmony_ci */
15800b99b8Sopenharmony_ci
16800b99b8Sopenharmony_ci#include <gtest/gtest.h>
17800b99b8Sopenharmony_ci#include <sigchain.h>
18800b99b8Sopenharmony_ci
19800b99b8Sopenharmony_ci#include "dfx_define.h"
20800b99b8Sopenharmony_ci
21800b99b8Sopenharmony_ciusing namespace testing;
22800b99b8Sopenharmony_ciusing namespace testing::ext;
23800b99b8Sopenharmony_ciusing namespace std;
24800b99b8Sopenharmony_ci
25800b99b8Sopenharmony_cinamespace OHOS {
26800b99b8Sopenharmony_cinamespace HiviewDFX {
27800b99b8Sopenharmony_ciclass SignalChainTest : public testing::Test {
28800b99b8Sopenharmony_cipublic:
29800b99b8Sopenharmony_ci    static void SetUpTestCase() {}
30800b99b8Sopenharmony_ci    static void TearDownTestCase() {}
31800b99b8Sopenharmony_ci    void SetUp() {}
32800b99b8Sopenharmony_ci    void TearDown() {}
33800b99b8Sopenharmony_ci};
34800b99b8Sopenharmony_ci
35800b99b8Sopenharmony_ci#define SIGCHIAN_TEST_SIGNAL_NUM_1 1
36800b99b8Sopenharmony_ci#define SIGCHIAN_TEST_SIGNAL_NUM_2 2
37800b99b8Sopenharmony_ci
38800b99b8Sopenharmony_cistatic const int TEST_PTR_VALUE = 10;
39800b99b8Sopenharmony_cistatic const int SLEEP_10_MS = 10000;
40800b99b8Sopenharmony_cistatic const int SLEEP_1000_MS = 1000000;
41800b99b8Sopenharmony_cistatic const int SLEEP_2000_MS = 2000000;
42800b99b8Sopenharmony_ci
43800b99b8Sopenharmony_cistatic int g_count = 0;
44800b99b8Sopenharmony_cistatic bool g_testLastFlag = false;
45800b99b8Sopenharmony_cistatic bool g_signalDumpFlag = false;
46800b99b8Sopenharmony_cistatic bool g_signalSegvFlag = false;
47800b99b8Sopenharmony_cistatic bool g_sigactionDumpFlag = false;
48800b99b8Sopenharmony_cistatic bool g_sigactionSegvFlag = false;
49800b99b8Sopenharmony_cistatic bool g_sigactionIllFlag = false;
50800b99b8Sopenharmony_cistatic bool g_sigchainDumpFlag = false;
51800b99b8Sopenharmony_cistatic bool g_sigchainDump1Flag = false;
52800b99b8Sopenharmony_cistatic bool g_sigchainDump2Flag = false;
53800b99b8Sopenharmony_cistatic bool g_sigchainSegvFlag = false;
54800b99b8Sopenharmony_cistatic bool g_sigchainSegv1Flag = false;
55800b99b8Sopenharmony_cistatic bool g_sigchainSegv2Flag = false;
56800b99b8Sopenharmony_ci
57800b99b8Sopenharmony_cistatic void ResetCount()
58800b99b8Sopenharmony_ci{
59800b99b8Sopenharmony_ci    g_count = 0;
60800b99b8Sopenharmony_ci    g_testLastFlag = true;
61800b99b8Sopenharmony_ci}
62800b99b8Sopenharmony_ci
63800b99b8Sopenharmony_cistatic void SignalInit()
64800b99b8Sopenharmony_ci{
65800b99b8Sopenharmony_ci    g_testLastFlag = false;
66800b99b8Sopenharmony_ci    g_signalDumpFlag = false;
67800b99b8Sopenharmony_ci    g_signalSegvFlag = false;
68800b99b8Sopenharmony_ci    g_sigactionDumpFlag = false;
69800b99b8Sopenharmony_ci    g_sigactionSegvFlag = false;
70800b99b8Sopenharmony_ci    g_sigactionIllFlag = false;
71800b99b8Sopenharmony_ci    g_sigchainDumpFlag = false;
72800b99b8Sopenharmony_ci    g_sigchainDump1Flag = false;
73800b99b8Sopenharmony_ci    g_sigchainDump2Flag = false;
74800b99b8Sopenharmony_ci    g_sigchainSegvFlag = false;
75800b99b8Sopenharmony_ci    g_sigchainSegv1Flag = false;
76800b99b8Sopenharmony_ci    g_sigchainSegv2Flag = false;
77800b99b8Sopenharmony_ci}
78800b99b8Sopenharmony_ci
79800b99b8Sopenharmony_ciAT_UNUSED static void SignalDumpHandler(int signo)
80800b99b8Sopenharmony_ci{
81800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalDumpHandler";
82800b99b8Sopenharmony_ci    g_signalDumpFlag = true;
83800b99b8Sopenharmony_ci    EXPECT_EQ(signo, SIGDUMP) << "SignalDumpHandler Failed";
84800b99b8Sopenharmony_ci}
85800b99b8Sopenharmony_ci
86800b99b8Sopenharmony_ciAT_UNUSED static void SignalSegvHandler(int signo)
87800b99b8Sopenharmony_ci{
88800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalSegvHandler";
89800b99b8Sopenharmony_ci    g_signalSegvFlag = true;
90800b99b8Sopenharmony_ci    EXPECT_EQ(signo, SIGSEGV) << "SignalSegvHandler Failed";
91800b99b8Sopenharmony_ci}
92800b99b8Sopenharmony_ci
93800b99b8Sopenharmony_ciAT_UNUSED static void SignalDumpSigaction(int signo)
94800b99b8Sopenharmony_ci{
95800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalDumpSigaction";
96800b99b8Sopenharmony_ci    g_sigactionDumpFlag = true;
97800b99b8Sopenharmony_ci    EXPECT_EQ(signo, SIGDUMP) << "SignalDumpSigaction Failed";
98800b99b8Sopenharmony_ci}
99800b99b8Sopenharmony_ci
100800b99b8Sopenharmony_ciAT_UNUSED static void SignalSegvSigaction(int signo)
101800b99b8Sopenharmony_ci{
102800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalSegvSigaction";
103800b99b8Sopenharmony_ci    g_sigactionSegvFlag = true;
104800b99b8Sopenharmony_ci    EXPECT_EQ(signo, SIGSEGV) << "SignalSegvSigaction Failed";
105800b99b8Sopenharmony_ci}
106800b99b8Sopenharmony_ci
107800b99b8Sopenharmony_ciAT_UNUSED static void SignalIllSigaction(int signo)
108800b99b8Sopenharmony_ci{
109800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalIllSigaction";
110800b99b8Sopenharmony_ci    g_sigactionIllFlag = true;
111800b99b8Sopenharmony_ci    EXPECT_EQ(signo, SIGILL) << "SignalIllSigaction Failed";
112800b99b8Sopenharmony_ci}
113800b99b8Sopenharmony_ci
114800b99b8Sopenharmony_ciAT_UNUSED static bool SigchainSpecialHandlerDumpTrue(int signo, siginfo_t *si, void *ucontext)
115800b99b8Sopenharmony_ci{
116800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SigchainSpecialHandlerDumpTrue";
117800b99b8Sopenharmony_ci    g_sigchainDumpFlag = true;
118800b99b8Sopenharmony_ci    EXPECT_EQ(signo, SIGDUMP) << "SigchainSpecialHandlerDumpTrue Failed";
119800b99b8Sopenharmony_ci    if (g_testLastFlag) {
120800b99b8Sopenharmony_ci        g_count++;
121800b99b8Sopenharmony_ci        EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SigchainSpecialHandlerDumpTrue: g_count.";
122800b99b8Sopenharmony_ci    }
123800b99b8Sopenharmony_ci    return true;
124800b99b8Sopenharmony_ci}
125800b99b8Sopenharmony_ci
126800b99b8Sopenharmony_ciAT_UNUSED static bool SigchainSpecialHandlerDump1(int signo, siginfo_t *si, void *ucontext)
127800b99b8Sopenharmony_ci{
128800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SigchainSpecialHandlerDump1";
129800b99b8Sopenharmony_ci    g_sigchainDump1Flag = true;
130800b99b8Sopenharmony_ci    EXPECT_EQ(signo, SIGDUMP) << "SigchainSpecialHandlerDump1 Failed";
131800b99b8Sopenharmony_ci    if (g_testLastFlag) {
132800b99b8Sopenharmony_ci        g_count++;
133800b99b8Sopenharmony_ci        EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_1) << "SigchainSpecialHandlerDump1: g_count.";
134800b99b8Sopenharmony_ci    }
135800b99b8Sopenharmony_ci    return false;
136800b99b8Sopenharmony_ci}
137800b99b8Sopenharmony_ci
138800b99b8Sopenharmony_ciAT_UNUSED static bool SigchainSpecialHandlerDump2(int signo, siginfo_t *si, void *ucontext)
139800b99b8Sopenharmony_ci{
140800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SigchainSpecialHandlerDump2";
141800b99b8Sopenharmony_ci    g_sigchainDump2Flag = true;
142800b99b8Sopenharmony_ci    EXPECT_EQ(signo, SIGDUMP) << "SigchainSpecialHandlerDump2 Failed";
143800b99b8Sopenharmony_ci    if (g_testLastFlag) {
144800b99b8Sopenharmony_ci        g_count++;
145800b99b8Sopenharmony_ci        EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SigchainSpecialHandlerDump2: g_count.";
146800b99b8Sopenharmony_ci    }
147800b99b8Sopenharmony_ci    return false;
148800b99b8Sopenharmony_ci}
149800b99b8Sopenharmony_ci
150800b99b8Sopenharmony_ciAT_UNUSED static bool SigchainSpecialHandlerSegvTrue(int signo, siginfo_t *si, void *ucontext)
151800b99b8Sopenharmony_ci{
152800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SigchainSpecialHandlerSegvTrue";
153800b99b8Sopenharmony_ci    g_sigchainSegvFlag = true;
154800b99b8Sopenharmony_ci    EXPECT_EQ(signo, SIGSEGV) << "SigchainSpecialHandlerSegvTrue Failed";
155800b99b8Sopenharmony_ci    if (g_testLastFlag) {
156800b99b8Sopenharmony_ci        g_count++;
157800b99b8Sopenharmony_ci        EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SigchainSpecialHandlerSegvTrue: g_count.";
158800b99b8Sopenharmony_ci    }
159800b99b8Sopenharmony_ci    return true;
160800b99b8Sopenharmony_ci}
161800b99b8Sopenharmony_ci
162800b99b8Sopenharmony_ciAT_UNUSED static bool SigchainSpecialHandlerSegv1(int signo, siginfo_t *si, void *ucontext)
163800b99b8Sopenharmony_ci{
164800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SigchainSpecialHandlerSegv1";
165800b99b8Sopenharmony_ci    g_sigchainSegv1Flag = true;
166800b99b8Sopenharmony_ci    EXPECT_EQ(signo, SIGSEGV) << "SigchainSpecialHandlerSegv1 Failed";
167800b99b8Sopenharmony_ci    if (g_testLastFlag) {
168800b99b8Sopenharmony_ci        g_count++;
169800b99b8Sopenharmony_ci        EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_1) << "SigchainSpecialHandlerSegv1: g_count.";
170800b99b8Sopenharmony_ci    }
171800b99b8Sopenharmony_ci    return false;
172800b99b8Sopenharmony_ci}
173800b99b8Sopenharmony_ci
174800b99b8Sopenharmony_ciAT_UNUSED static bool SigchainSpecialHandlerSegv2(int signo, siginfo_t *si, void *ucontext)
175800b99b8Sopenharmony_ci{
176800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SigchainSpecialHandlerSegv2";
177800b99b8Sopenharmony_ci    g_sigchainSegv2Flag = true;
178800b99b8Sopenharmony_ci    EXPECT_EQ(signo, SIGSEGV) << "SigchainSpecialHandlerSegv2 Failed";
179800b99b8Sopenharmony_ci    if (g_testLastFlag) {
180800b99b8Sopenharmony_ci        g_count++;
181800b99b8Sopenharmony_ci        EXPECT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SigchainSpecialHandlerSegv2: g_count.";
182800b99b8Sopenharmony_ci    }
183800b99b8Sopenharmony_ci    return false;
184800b99b8Sopenharmony_ci}
185800b99b8Sopenharmony_ci
186800b99b8Sopenharmony_ciclass MixStackDumper {
187800b99b8Sopenharmony_cipublic:
188800b99b8Sopenharmony_ci    MixStackDumper() = default;
189800b99b8Sopenharmony_ci    ~MixStackDumper() = default;
190800b99b8Sopenharmony_ci    AT_UNUSED static bool DumpSignalHandler(int signo, siginfo_t *si, void *ucontext)
191800b99b8Sopenharmony_ci    {
192800b99b8Sopenharmony_ci        std::shared_ptr<int> ptr = std::make_shared<int>(TEST_PTR_VALUE);
193800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "DumpSignalHandler: " << ptr.use_count();
194800b99b8Sopenharmony_ci        g_sigchainDump2Flag = true;
195800b99b8Sopenharmony_ci        EXPECT_EQ(signo, SIGDUMP) << "DumpSignalHandler Failed";
196800b99b8Sopenharmony_ci        return true;
197800b99b8Sopenharmony_ci    }
198800b99b8Sopenharmony_ci
199800b99b8Sopenharmony_ci    AT_UNUSED static bool SegvSignalHandler(int signo, siginfo_t *si, void *ucontext)
200800b99b8Sopenharmony_ci    {
201800b99b8Sopenharmony_ci        std::shared_ptr<int> ptr = std::make_shared<int>(TEST_PTR_VALUE);
202800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "SegvSignalHandler: " << ptr.use_count();
203800b99b8Sopenharmony_ci        g_sigchainSegv2Flag = true;
204800b99b8Sopenharmony_ci        EXPECT_EQ(signo, SIGSEGV) << "SegvSignalHandler Failed";
205800b99b8Sopenharmony_ci        return false;
206800b99b8Sopenharmony_ci    }
207800b99b8Sopenharmony_ci};
208800b99b8Sopenharmony_ci
209800b99b8Sopenharmony_cistatic int KillAndWaitPid(int pid)
210800b99b8Sopenharmony_ci{
211800b99b8Sopenharmony_ci    usleep(SLEEP_10_MS);
212800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "kill SIGDUMP pid: " << pid;
213800b99b8Sopenharmony_ci    kill(pid, SIGDUMP);
214800b99b8Sopenharmony_ci    usleep(SLEEP_10_MS);
215800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "kill SIGSEGV pid: " << pid;
216800b99b8Sopenharmony_ci    kill(pid, SIGSEGV);
217800b99b8Sopenharmony_ci    usleep(SLEEP_2000_MS);
218800b99b8Sopenharmony_ci    int status;
219800b99b8Sopenharmony_ci    int ret = waitpid(pid, &status, 0);
220800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "waitpid: " << pid << ", ret: "<< ret << std::endl;
221800b99b8Sopenharmony_ci    return ret;
222800b99b8Sopenharmony_ci}
223800b99b8Sopenharmony_ci
224800b99b8Sopenharmony_ci/**
225800b99b8Sopenharmony_ci * @tc.name: SignalChainTest001
226800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler signal
227800b99b8Sopenharmony_ci * @tc.type: FUNC
228800b99b8Sopenharmony_ci */
229800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest001, TestSize.Level2)
230800b99b8Sopenharmony_ci{
231800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest001: start.";
232800b99b8Sopenharmony_ci    SignalInit();
233800b99b8Sopenharmony_ci    pid_t pid = fork();
234800b99b8Sopenharmony_ci    if (pid < 0) {
235800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
236800b99b8Sopenharmony_ci    } else if (pid == 0) {
237800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "SignalChainTest001: pid:" << getpid();
238800b99b8Sopenharmony_ci        signal(SIGSEGV, SignalSegvHandler);
239800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
240800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
241800b99b8Sopenharmony_ci        ASSERT_EQ(g_signalSegvFlag, true) << "SignalChainTest001: g_signalSegvFlag.";
242800b99b8Sopenharmony_ci        _exit(0);
243800b99b8Sopenharmony_ci    } else {
244800b99b8Sopenharmony_ci        KillAndWaitPid(pid);
245800b99b8Sopenharmony_ci    }
246800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest001: end.";
247800b99b8Sopenharmony_ci}
248800b99b8Sopenharmony_ci
249800b99b8Sopenharmony_ci/**
250800b99b8Sopenharmony_ci * @tc.name: SignalChainTest002
251800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler sigaction
252800b99b8Sopenharmony_ci * @tc.type: FUNC
253800b99b8Sopenharmony_ci */
254800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest002, TestSize.Level2)
255800b99b8Sopenharmony_ci{
256800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest002: start.";
257800b99b8Sopenharmony_ci    SignalInit();
258800b99b8Sopenharmony_ci    pid_t pid = fork();
259800b99b8Sopenharmony_ci    if (pid < 0) {
260800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
261800b99b8Sopenharmony_ci    } else if (pid == 0) {
262800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "SignalChainTest002: pid:" << getpid();
263800b99b8Sopenharmony_ci        struct sigaction sigsegv = {
264800b99b8Sopenharmony_ci            .sa_handler = SignalSegvSigaction,
265800b99b8Sopenharmony_ci        };
266800b99b8Sopenharmony_ci        sigaction(SIGSEGV, &sigsegv, NULL);
267800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
268800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
269800b99b8Sopenharmony_ci        ASSERT_EQ(g_sigactionSegvFlag, true) << "SignalChainTest002: g_sigactionSegvFlag.";
270800b99b8Sopenharmony_ci        _exit(0);
271800b99b8Sopenharmony_ci    } else {
272800b99b8Sopenharmony_ci        KillAndWaitPid(pid);
273800b99b8Sopenharmony_ci    }
274800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest002: end.";
275800b99b8Sopenharmony_ci}
276800b99b8Sopenharmony_ci
277800b99b8Sopenharmony_ci/**
278800b99b8Sopenharmony_ci * @tc.name: SignalChainTest003
279800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler add sigchain no else signal or sigaction
280800b99b8Sopenharmony_ci * @tc.type: FUNC
281800b99b8Sopenharmony_ci */
282800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest003, TestSize.Level2)
283800b99b8Sopenharmony_ci{
284800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest003: start.";
285800b99b8Sopenharmony_ci    SignalInit();
286800b99b8Sopenharmony_ci    pid_t pid = fork();
287800b99b8Sopenharmony_ci    if (pid < 0) {
288800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
289800b99b8Sopenharmony_ci    } else if (pid == 0) {
290800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "SignalChainTest003: pid:" << getpid();
291800b99b8Sopenharmony_ci        struct signal_chain_action sigchain1 = {
292800b99b8Sopenharmony_ci            .sca_sigaction = SigchainSpecialHandlerDumpTrue,
293800b99b8Sopenharmony_ci            .sca_mask = {},
294800b99b8Sopenharmony_ci            .sca_flags = 0,
295800b99b8Sopenharmony_ci        };
296800b99b8Sopenharmony_ci        add_special_signal_handler(SIGDUMP, &sigchain1);
297800b99b8Sopenharmony_ci        struct signal_chain_action sigsegv1 = {
298800b99b8Sopenharmony_ci            .sca_sigaction = SigchainSpecialHandlerSegvTrue,
299800b99b8Sopenharmony_ci            .sca_mask = {},
300800b99b8Sopenharmony_ci            .sca_flags = 0,
301800b99b8Sopenharmony_ci        };
302800b99b8Sopenharmony_ci        add_special_signal_handler(SIGSEGV, &sigsegv1);
303800b99b8Sopenharmony_ci
304800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
305800b99b8Sopenharmony_ci        ASSERT_EQ(g_sigchainDumpFlag, true) << "SignalChainTest003: g_sigchainDumpFlag.";
306800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
307800b99b8Sopenharmony_ci        ASSERT_EQ(g_sigchainSegvFlag, true) << "SignalChainTest003: g_sigchainSegvFlag.";
308800b99b8Sopenharmony_ci        _exit(0);
309800b99b8Sopenharmony_ci    } else {
310800b99b8Sopenharmony_ci        KillAndWaitPid(pid);
311800b99b8Sopenharmony_ci    }
312800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest003: end.";
313800b99b8Sopenharmony_ci}
314800b99b8Sopenharmony_ci
315800b99b8Sopenharmony_ci/**
316800b99b8Sopenharmony_ci * @tc.name: SignalChainTest004
317800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler add sigchain and have signal handler
318800b99b8Sopenharmony_ci * @tc.type: FUNC
319800b99b8Sopenharmony_ci */
320800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest004, TestSize.Level2)
321800b99b8Sopenharmony_ci{
322800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest004: start.";
323800b99b8Sopenharmony_ci    SignalInit();
324800b99b8Sopenharmony_ci    pid_t pid = fork();
325800b99b8Sopenharmony_ci    if (pid < 0) {
326800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
327800b99b8Sopenharmony_ci    } else if (pid == 0) {
328800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "SignalChainTest004: pid:" << getpid();
329800b99b8Sopenharmony_ci        signal(SIGSEGV, SignalSegvHandler);
330800b99b8Sopenharmony_ci
331800b99b8Sopenharmony_ci        struct signal_chain_action sigchain1 = {
332800b99b8Sopenharmony_ci            .sca_sigaction = SigchainSpecialHandlerDump1,
333800b99b8Sopenharmony_ci            .sca_mask = {},
334800b99b8Sopenharmony_ci            .sca_flags = 0,
335800b99b8Sopenharmony_ci        };
336800b99b8Sopenharmony_ci        add_special_signal_handler(SIGDUMP, &sigchain1);
337800b99b8Sopenharmony_ci        struct signal_chain_action sigsegv1 = {
338800b99b8Sopenharmony_ci            .sca_sigaction = SigchainSpecialHandlerSegv1,
339800b99b8Sopenharmony_ci            .sca_mask = {},
340800b99b8Sopenharmony_ci            .sca_flags = 0,
341800b99b8Sopenharmony_ci        };
342800b99b8Sopenharmony_ci        add_special_signal_handler(SIGSEGV, &sigsegv1);
343800b99b8Sopenharmony_ci
344800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
345800b99b8Sopenharmony_ci        ASSERT_EQ(g_sigchainDump1Flag, true) << "SignalChainTest004: g_sigchainDump1Flag.";
346800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
347800b99b8Sopenharmony_ci        ASSERT_EQ(g_signalSegvFlag, true) << "SignalChainTest004: g_signalSegvFlag.";
348800b99b8Sopenharmony_ci        ASSERT_EQ(g_sigchainSegv1Flag, true) << "SignalChainTest004: g_sigchainSegv1Flag.";
349800b99b8Sopenharmony_ci        _exit(0);
350800b99b8Sopenharmony_ci    } else {
351800b99b8Sopenharmony_ci        KillAndWaitPid(pid);
352800b99b8Sopenharmony_ci    }
353800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest004: end.";
354800b99b8Sopenharmony_ci}
355800b99b8Sopenharmony_ci
356800b99b8Sopenharmony_ci/**
357800b99b8Sopenharmony_ci * @tc.name: SignalChainTest005
358800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler remove sigchain
359800b99b8Sopenharmony_ci * @tc.type: FUNC
360800b99b8Sopenharmony_ci */
361800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest005, TestSize.Level2)
362800b99b8Sopenharmony_ci{
363800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest005: start.";
364800b99b8Sopenharmony_ci    SignalInit();
365800b99b8Sopenharmony_ci    pid_t pid = fork();
366800b99b8Sopenharmony_ci    if (pid < 0) {
367800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
368800b99b8Sopenharmony_ci    } else if (pid == 0) {
369800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "SignalChainTest005: pid:" << getpid();
370800b99b8Sopenharmony_ci        struct signal_chain_action sigchain1 = {
371800b99b8Sopenharmony_ci            .sca_sigaction = SigchainSpecialHandlerDump1,
372800b99b8Sopenharmony_ci            .sca_mask = {},
373800b99b8Sopenharmony_ci            .sca_flags = 0,
374800b99b8Sopenharmony_ci        };
375800b99b8Sopenharmony_ci        add_special_signal_handler(SIGDUMP, &sigchain1);
376800b99b8Sopenharmony_ci        struct signal_chain_action sigsegv1 = {
377800b99b8Sopenharmony_ci            .sca_sigaction = SigchainSpecialHandlerSegv1,
378800b99b8Sopenharmony_ci            .sca_mask = {},
379800b99b8Sopenharmony_ci            .sca_flags = 0,
380800b99b8Sopenharmony_ci        };
381800b99b8Sopenharmony_ci        add_special_signal_handler(SIGSEGV, &sigsegv1);
382800b99b8Sopenharmony_ci
383800b99b8Sopenharmony_ci        remove_special_signal_handler(SIGDUMP, SigchainSpecialHandlerDump1);
384800b99b8Sopenharmony_ci        remove_special_signal_handler(SIGSEGV, SigchainSpecialHandlerSegv1);
385800b99b8Sopenharmony_ci
386800b99b8Sopenharmony_ci        struct signal_chain_action sigchain2 = {
387800b99b8Sopenharmony_ci            .sca_sigaction = SigchainSpecialHandlerDumpTrue,
388800b99b8Sopenharmony_ci            .sca_mask = {},
389800b99b8Sopenharmony_ci            .sca_flags = 0,
390800b99b8Sopenharmony_ci        };
391800b99b8Sopenharmony_ci        add_special_signal_handler(SIGDUMP, &sigchain2);
392800b99b8Sopenharmony_ci        struct signal_chain_action sigsegv2 = {
393800b99b8Sopenharmony_ci            .sca_sigaction = SigchainSpecialHandlerSegvTrue,
394800b99b8Sopenharmony_ci            .sca_mask = {},
395800b99b8Sopenharmony_ci            .sca_flags = 0,
396800b99b8Sopenharmony_ci        };
397800b99b8Sopenharmony_ci        add_special_signal_handler(SIGSEGV, &sigsegv2);
398800b99b8Sopenharmony_ci
399800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
400800b99b8Sopenharmony_ci        ASSERT_NE(g_sigchainDump1Flag, true) << "SignalChainTest005: g_sigchainDump1Flag.";
401800b99b8Sopenharmony_ci        ASSERT_EQ(g_sigchainDumpFlag, true) << "SignalChainTest005: g_sigchainDumpFlag.";
402800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
403800b99b8Sopenharmony_ci        ASSERT_NE(g_sigchainSegv1Flag, true) << "SignalChainTest005: g_sigchainSegv1Flag.";
404800b99b8Sopenharmony_ci        ASSERT_EQ(g_sigchainSegvFlag, true) << "SignalChainTest005: g_sigchainSegvFlag.";
405800b99b8Sopenharmony_ci        _exit(0);
406800b99b8Sopenharmony_ci    } else {
407800b99b8Sopenharmony_ci        KillAndWaitPid(pid);
408800b99b8Sopenharmony_ci    }
409800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest005: end.";
410800b99b8Sopenharmony_ci}
411800b99b8Sopenharmony_ci
412800b99b8Sopenharmony_ci/**
413800b99b8Sopenharmony_ci * @tc.name: SignalChainTest006
414800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler remove all sigchain
415800b99b8Sopenharmony_ci * @tc.type: FUNC
416800b99b8Sopenharmony_ci */
417800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest006, TestSize.Level2)
418800b99b8Sopenharmony_ci{
419800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest006: start.";
420800b99b8Sopenharmony_ci    SignalInit();
421800b99b8Sopenharmony_ci    pid_t pid = fork();
422800b99b8Sopenharmony_ci    if (pid < 0) {
423800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
424800b99b8Sopenharmony_ci    } else if (pid == 0) {
425800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "SignalChainTest006: pid:" << getpid();
426800b99b8Sopenharmony_ci        signal(SIGDUMP, SignalDumpHandler);
427800b99b8Sopenharmony_ci        signal(SIGSEGV, SignalSegvHandler);
428800b99b8Sopenharmony_ci
429800b99b8Sopenharmony_ci        struct signal_chain_action sigchain1 = {
430800b99b8Sopenharmony_ci            .sca_sigaction = SigchainSpecialHandlerDump1,
431800b99b8Sopenharmony_ci            .sca_mask = {},
432800b99b8Sopenharmony_ci            .sca_flags = 0,
433800b99b8Sopenharmony_ci        };
434800b99b8Sopenharmony_ci        add_special_signal_handler(SIGDUMP, &sigchain1);
435800b99b8Sopenharmony_ci
436800b99b8Sopenharmony_ci        struct signal_chain_action sigsegv1 = {
437800b99b8Sopenharmony_ci            .sca_sigaction = SigchainSpecialHandlerSegv1,
438800b99b8Sopenharmony_ci            .sca_mask = {},
439800b99b8Sopenharmony_ci            .sca_flags = 0,
440800b99b8Sopenharmony_ci        };
441800b99b8Sopenharmony_ci        add_special_signal_handler(SIGSEGV, &sigsegv1);
442800b99b8Sopenharmony_ci
443800b99b8Sopenharmony_ci        remove_all_special_handler(SIGDUMP);
444800b99b8Sopenharmony_ci        remove_all_special_handler(SIGSEGV);
445800b99b8Sopenharmony_ci
446800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
447800b99b8Sopenharmony_ci        ASSERT_NE(g_sigchainDump1Flag, true) << "SignalChainTest006: g_sigchainDump1Flag.";
448800b99b8Sopenharmony_ci        ASSERT_NE(g_sigchainDump2Flag, true) << "SignalChainTest006: g_sigchainDump2Flag.";
449800b99b8Sopenharmony_ci        ASSERT_EQ(g_signalDumpFlag, true) << "SignalChainTest006: g_signalDumpFlag.";
450800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
451800b99b8Sopenharmony_ci        ASSERT_NE(g_sigchainSegv1Flag, true) << "SignalChainTest006: g_sigchainSegv1Flag.";
452800b99b8Sopenharmony_ci        ASSERT_NE(g_sigchainSegv2Flag, true) << "SignalChainTest006: g_sigchainSegv2Flag.";
453800b99b8Sopenharmony_ci        ASSERT_EQ(g_signalSegvFlag, true) << "SignalChainTest006: g_signalSegvFlag.";
454800b99b8Sopenharmony_ci        _exit(0);
455800b99b8Sopenharmony_ci    } else {
456800b99b8Sopenharmony_ci        KillAndWaitPid(pid);
457800b99b8Sopenharmony_ci    }
458800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest006: end.";
459800b99b8Sopenharmony_ci}
460800b99b8Sopenharmony_ci
461800b99b8Sopenharmony_ci/**
462800b99b8Sopenharmony_ci * @tc.name: SignalChainTest007
463800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler run C++ code in sigchain handler
464800b99b8Sopenharmony_ci * @tc.type: FUNC
465800b99b8Sopenharmony_ci */
466800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest007, TestSize.Level2)
467800b99b8Sopenharmony_ci{
468800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest007: start.";
469800b99b8Sopenharmony_ci    SignalInit();
470800b99b8Sopenharmony_ci    pid_t pid = fork();
471800b99b8Sopenharmony_ci    if (pid < 0) {
472800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
473800b99b8Sopenharmony_ci    } else if (pid == 0) {
474800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "SignalChainTest007: pid:" << getpid();
475800b99b8Sopenharmony_ci        remove_all_special_handler(SIGDUMP);
476800b99b8Sopenharmony_ci        remove_all_special_handler(SIGSEGV);
477800b99b8Sopenharmony_ci
478800b99b8Sopenharmony_ci        struct signal_chain_action sigchain1 = {
479800b99b8Sopenharmony_ci            .sca_sigaction = SigchainSpecialHandlerDump1,
480800b99b8Sopenharmony_ci            .sca_mask = {},
481800b99b8Sopenharmony_ci            .sca_flags = 0,
482800b99b8Sopenharmony_ci        };
483800b99b8Sopenharmony_ci        add_special_signal_handler(SIGDUMP, &sigchain1);
484800b99b8Sopenharmony_ci        struct signal_chain_action sigchain2 = {
485800b99b8Sopenharmony_ci            .sca_sigaction = &(MixStackDumper::DumpSignalHandler),
486800b99b8Sopenharmony_ci            .sca_mask = {},
487800b99b8Sopenharmony_ci            .sca_flags = 0,
488800b99b8Sopenharmony_ci        };
489800b99b8Sopenharmony_ci        add_special_signal_handler(SIGDUMP, &sigchain2);
490800b99b8Sopenharmony_ci
491800b99b8Sopenharmony_ci        struct signal_chain_action sigsegv1 = {
492800b99b8Sopenharmony_ci            .sca_sigaction = SigchainSpecialHandlerSegv1,
493800b99b8Sopenharmony_ci            .sca_mask = {},
494800b99b8Sopenharmony_ci            .sca_flags = 0,
495800b99b8Sopenharmony_ci        };
496800b99b8Sopenharmony_ci        add_special_signal_handler(SIGSEGV, &sigsegv1);
497800b99b8Sopenharmony_ci        struct signal_chain_action sigsegv2 = {
498800b99b8Sopenharmony_ci            .sca_sigaction = MixStackDumper::SegvSignalHandler,
499800b99b8Sopenharmony_ci            .sca_mask = {},
500800b99b8Sopenharmony_ci            .sca_flags = 0,
501800b99b8Sopenharmony_ci        };
502800b99b8Sopenharmony_ci        add_special_signal_handler(SIGSEGV, &sigsegv2);
503800b99b8Sopenharmony_ci
504800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
505800b99b8Sopenharmony_ci        ASSERT_EQ(g_sigchainDump1Flag, true) << "SignalChainTest007: g_sigchainDump1Flag.";
506800b99b8Sopenharmony_ci        ASSERT_EQ(g_sigchainDump2Flag, true) << "SignalChainTest007: g_sigchainDump2Flag.";
507800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
508800b99b8Sopenharmony_ci        ASSERT_EQ(g_sigchainSegv1Flag, true) << "SignalChainTest007: g_sigchainSegv1Flag.";
509800b99b8Sopenharmony_ci        ASSERT_EQ(g_sigchainSegv2Flag, true) << "SignalChainTest007: g_sigchainSegv2Flag.";
510800b99b8Sopenharmony_ci        _exit(0);
511800b99b8Sopenharmony_ci    } else {
512800b99b8Sopenharmony_ci        KillAndWaitPid(pid);
513800b99b8Sopenharmony_ci    }
514800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest007: end.";
515800b99b8Sopenharmony_ci}
516800b99b8Sopenharmony_ci
517800b99b8Sopenharmony_ci/**
518800b99b8Sopenharmony_ci * @tc.name: SignalChainTest008
519800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler add_special_handler_at_last
520800b99b8Sopenharmony_ci * @tc.type: FUNC
521800b99b8Sopenharmony_ci */
522800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest008, TestSize.Level2)
523800b99b8Sopenharmony_ci{
524800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest008: start.";
525800b99b8Sopenharmony_ci    SignalInit();
526800b99b8Sopenharmony_ci    pid_t pid = fork();
527800b99b8Sopenharmony_ci    if (pid < 0) {
528800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
529800b99b8Sopenharmony_ci    } else if (pid == 0) {
530800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "SignalChainTest008: pid:" << getpid();
531800b99b8Sopenharmony_ci        remove_all_special_handler(SIGDUMP);
532800b99b8Sopenharmony_ci        remove_all_special_handler(SIGSEGV);
533800b99b8Sopenharmony_ci
534800b99b8Sopenharmony_ci        struct signal_chain_action sigchain2 = {
535800b99b8Sopenharmony_ci            .sca_sigaction = SigchainSpecialHandlerDumpTrue,
536800b99b8Sopenharmony_ci            .sca_mask = {},
537800b99b8Sopenharmony_ci            .sca_flags = 0,
538800b99b8Sopenharmony_ci        };
539800b99b8Sopenharmony_ci        add_special_handler_at_last(SIGDUMP, &sigchain2);
540800b99b8Sopenharmony_ci
541800b99b8Sopenharmony_ci        struct signal_chain_action sigchain1 = {
542800b99b8Sopenharmony_ci            .sca_sigaction = SigchainSpecialHandlerDump1,
543800b99b8Sopenharmony_ci            .sca_mask = {},
544800b99b8Sopenharmony_ci            .sca_flags = 0,
545800b99b8Sopenharmony_ci        };
546800b99b8Sopenharmony_ci        add_special_signal_handler(SIGDUMP, &sigchain1);
547800b99b8Sopenharmony_ci
548800b99b8Sopenharmony_ci        struct signal_chain_action sigsegv2 = {
549800b99b8Sopenharmony_ci            .sca_sigaction = SigchainSpecialHandlerSegvTrue,
550800b99b8Sopenharmony_ci            .sca_mask = {},
551800b99b8Sopenharmony_ci            .sca_flags = 0,
552800b99b8Sopenharmony_ci        };
553800b99b8Sopenharmony_ci        add_special_handler_at_last(SIGSEGV, &sigsegv2);
554800b99b8Sopenharmony_ci        struct signal_chain_action sigsegv1 = {
555800b99b8Sopenharmony_ci            .sca_sigaction = SigchainSpecialHandlerSegv1,
556800b99b8Sopenharmony_ci            .sca_mask = {},
557800b99b8Sopenharmony_ci            .sca_flags = 0,
558800b99b8Sopenharmony_ci        };
559800b99b8Sopenharmony_ci        add_special_signal_handler(SIGSEGV, &sigsegv1);
560800b99b8Sopenharmony_ci
561800b99b8Sopenharmony_ci        ResetCount();
562800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
563800b99b8Sopenharmony_ci        ASSERT_EQ(g_sigchainDump1Flag, true) << "SignalChainTest008: g_sigchainDump1Flag.";
564800b99b8Sopenharmony_ci        ASSERT_EQ(g_sigchainDumpFlag, true) << "SignalChainTest008: g_sigchainDumpFlag.";
565800b99b8Sopenharmony_ci        ASSERT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SignalChainTest008: dump g_count.";
566800b99b8Sopenharmony_ci        ResetCount();
567800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
568800b99b8Sopenharmony_ci        ASSERT_EQ(g_sigchainSegv1Flag, true) << "SignalChainTest008: g_sigchainSegv1Flag.";
569800b99b8Sopenharmony_ci        ASSERT_EQ(g_sigchainSegvFlag, true) << "SignalChainTest008: g_sigchainSegvFlag.";
570800b99b8Sopenharmony_ci        ASSERT_EQ(g_count, SIGCHIAN_TEST_SIGNAL_NUM_2) << "SignalChainTest008: segv g_count.";
571800b99b8Sopenharmony_ci        _exit(0);
572800b99b8Sopenharmony_ci    } else {
573800b99b8Sopenharmony_ci        KillAndWaitPid(pid);
574800b99b8Sopenharmony_ci    }
575800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest008: end.";
576800b99b8Sopenharmony_ci}
577800b99b8Sopenharmony_ci
578800b99b8Sopenharmony_ci/**
579800b99b8Sopenharmony_ci * @tc.name: SignalChainTest009
580800b99b8Sopenharmony_ci * @tc.desc: test SignalHandler special signal(SIGILL)
581800b99b8Sopenharmony_ci * @tc.type: FUNC
582800b99b8Sopenharmony_ci */
583800b99b8Sopenharmony_ciHWTEST_F(SignalChainTest, SignalChainTest009, TestSize.Level2)
584800b99b8Sopenharmony_ci{
585800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest009: start.";
586800b99b8Sopenharmony_ci    SignalInit();
587800b99b8Sopenharmony_ci    pid_t pid = fork();
588800b99b8Sopenharmony_ci    if (pid < 0) {
589800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
590800b99b8Sopenharmony_ci    } else if (pid == 0) {
591800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "SignalChainTest009: pid:" << getpid();
592800b99b8Sopenharmony_ci        struct sigaction sigill = {
593800b99b8Sopenharmony_ci            .sa_handler = SignalIllSigaction,
594800b99b8Sopenharmony_ci        };
595800b99b8Sopenharmony_ci        sigaction(SIGILL, &sigill, NULL);
596800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
597800b99b8Sopenharmony_ci        ASSERT_EQ(g_sigactionIllFlag, true) << "SignalChainTest009: g_sigactionIllFlag.";
598800b99b8Sopenharmony_ci        _exit(0);
599800b99b8Sopenharmony_ci    } else {
600800b99b8Sopenharmony_ci        usleep(SLEEP_10_MS);
601800b99b8Sopenharmony_ci        kill(pid, SIGILL);
602800b99b8Sopenharmony_ci        usleep(SLEEP_1000_MS);
603800b99b8Sopenharmony_ci        int status;
604800b99b8Sopenharmony_ci        waitpid(pid, &status, 0);
605800b99b8Sopenharmony_ci    }
606800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalChainTest009: end.";
607800b99b8Sopenharmony_ci}
608800b99b8Sopenharmony_ci} // namespace HiviewDFX
609800b99b8Sopenharmony_ci} // namepsace OHOS
610