1800b99b8Sopenharmony_ci/*
2800b99b8Sopenharmony_ci * Copyright (c) 2022-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 <csignal>
18800b99b8Sopenharmony_ci#include <map>
19800b99b8Sopenharmony_ci#include <securec.h>
20800b99b8Sopenharmony_ci#include <string>
21800b99b8Sopenharmony_ci#include <thread>
22800b99b8Sopenharmony_ci#include <unistd.h>
23800b99b8Sopenharmony_ci#include <vector>
24800b99b8Sopenharmony_ci#include <sys/prctl.h>
25800b99b8Sopenharmony_ci
26800b99b8Sopenharmony_ci#include "dfx_define.h"
27800b99b8Sopenharmony_ci#include "dfx_signal_handler.h"
28800b99b8Sopenharmony_ci#include "dfx_signalhandler_exception.h"
29800b99b8Sopenharmony_ci#include "dfx_test_util.h"
30800b99b8Sopenharmony_ci
31800b99b8Sopenharmony_ciusing namespace testing;
32800b99b8Sopenharmony_ciusing namespace testing::ext;
33800b99b8Sopenharmony_ciusing namespace std;
34800b99b8Sopenharmony_ci
35800b99b8Sopenharmony_cinamespace OHOS {
36800b99b8Sopenharmony_cinamespace HiviewDFX {
37800b99b8Sopenharmony_ciclass SignalHandlerTest : public testing::Test {
38800b99b8Sopenharmony_cipublic:
39800b99b8Sopenharmony_ci    static void SetUpTestCase();
40800b99b8Sopenharmony_ci    static void TearDownTestCase();
41800b99b8Sopenharmony_ci    void SetUp();
42800b99b8Sopenharmony_ci    void TearDown();
43800b99b8Sopenharmony_ci};
44800b99b8Sopenharmony_ci
45800b99b8Sopenharmony_civoid SignalHandlerTest::SetUpTestCase()
46800b99b8Sopenharmony_ci{}
47800b99b8Sopenharmony_ci
48800b99b8Sopenharmony_civoid SignalHandlerTest::TearDownTestCase()
49800b99b8Sopenharmony_ci{}
50800b99b8Sopenharmony_ci
51800b99b8Sopenharmony_civoid SignalHandlerTest::SetUp()
52800b99b8Sopenharmony_ci{}
53800b99b8Sopenharmony_ci
54800b99b8Sopenharmony_civoid SignalHandlerTest::TearDown()
55800b99b8Sopenharmony_ci{}
56800b99b8Sopenharmony_ci
57800b99b8Sopenharmony_ciextern "C" void SetThreadInfoCallback(ThreadInfoCallBack func) __attribute__((weak));
58800b99b8Sopenharmony_ciextern "C" void DFX_InstallSignalHandler(void) __attribute__((weak));
59800b99b8Sopenharmony_ciextern "C" void SetAsyncStackCallbackFunc(void* func) __attribute__((weak));
60800b99b8Sopenharmony_ciextern "C" int DFX_SetAppRunningUniqueId(const char* appRunningId, size_t len) __attribute__((weak));
61800b99b8Sopenharmony_cistatic bool CheckThreadCrashKeyWords(const string& filePath, pid_t pid, int sig)
62800b99b8Sopenharmony_ci{
63800b99b8Sopenharmony_ci    if (filePath.empty() || pid <= 0) {
64800b99b8Sopenharmony_ci        return false;
65800b99b8Sopenharmony_ci    }
66800b99b8Sopenharmony_ci    map<int, string> sigKey = {
67800b99b8Sopenharmony_ci        { SIGILL, string("SIGILL") },
68800b99b8Sopenharmony_ci        { SIGBUS, string("SIGBUS") },
69800b99b8Sopenharmony_ci        { SIGSEGV, string("SIGSEGV") },
70800b99b8Sopenharmony_ci    };
71800b99b8Sopenharmony_ci    string sigKeyword = "";
72800b99b8Sopenharmony_ci    map<int, string>::iterator iter = sigKey.find(sig);
73800b99b8Sopenharmony_ci    if (iter != sigKey.end()) {
74800b99b8Sopenharmony_ci        sigKeyword = iter->second;
75800b99b8Sopenharmony_ci    }
76800b99b8Sopenharmony_ci    string keywords[] = {
77800b99b8Sopenharmony_ci        "Pid:" + to_string(pid), "Uid:", "name:./test_signalhandler", sigKeyword,
78800b99b8Sopenharmony_ci        "Tid:", "#00", "Registers:", "FaultStack:", "Maps:", "test_signalhandler"
79800b99b8Sopenharmony_ci    };
80800b99b8Sopenharmony_ci    int length = sizeof(keywords) / sizeof(keywords[0]);
81800b99b8Sopenharmony_ci    int minRegIdx = -1;
82800b99b8Sopenharmony_ci    return CheckKeyWords(filePath, keywords, length, minRegIdx) == length;
83800b99b8Sopenharmony_ci}
84800b99b8Sopenharmony_cistatic bool CheckCrashKeyWords(const string& filePath, pid_t pid, int sig)
85800b99b8Sopenharmony_ci{
86800b99b8Sopenharmony_ci    if (filePath.empty() || pid <= 0) {
87800b99b8Sopenharmony_ci        return false;
88800b99b8Sopenharmony_ci    }
89800b99b8Sopenharmony_ci    map<int, string> sigKey = {
90800b99b8Sopenharmony_ci        { SIGILL, string("SIGILL") },
91800b99b8Sopenharmony_ci        { SIGBUS, string("SIGBUS") },
92800b99b8Sopenharmony_ci        { SIGSEGV, string("SIGSEGV") },
93800b99b8Sopenharmony_ci        { SIGABRT, string("SIGABRT") },
94800b99b8Sopenharmony_ci        { SIGFPE, string("SIGFPE") },
95800b99b8Sopenharmony_ci        { SIGSTKFLT, string("SIGSTKFLT") },
96800b99b8Sopenharmony_ci        { SIGSYS, string("SIGSYS") },
97800b99b8Sopenharmony_ci        { SIGTRAP, string("SIGTRAP") },
98800b99b8Sopenharmony_ci    };
99800b99b8Sopenharmony_ci    string sigKeyword = "";
100800b99b8Sopenharmony_ci    map<int, string>::iterator iter = sigKey.find(sig);
101800b99b8Sopenharmony_ci    if (iter != sigKey.end()) {
102800b99b8Sopenharmony_ci        sigKeyword = iter->second;
103800b99b8Sopenharmony_ci    }
104800b99b8Sopenharmony_ci    string keywords[] = {
105800b99b8Sopenharmony_ci        "Pid:" + to_string(pid), "Uid:", "name:./test_signalhandler", sigKeyword,
106800b99b8Sopenharmony_ci        "Tid:", "#00", "Registers:", "FaultStack:", "Maps:", "test_signalhandler"
107800b99b8Sopenharmony_ci    };
108800b99b8Sopenharmony_ci    int length = sizeof(keywords) / sizeof(keywords[0]);
109800b99b8Sopenharmony_ci    int minRegIdx = -1;
110800b99b8Sopenharmony_ci    return CheckKeyWords(filePath, keywords, length, minRegIdx) == length;
111800b99b8Sopenharmony_ci}
112800b99b8Sopenharmony_ci
113800b99b8Sopenharmony_civoid ThreadInfo(char* buf, size_t len, void* context __attribute__((unused)))
114800b99b8Sopenharmony_ci{
115800b99b8Sopenharmony_ci    char mes[] = "this is cash information of test thread";
116800b99b8Sopenharmony_ci    if (memcpy_s(buf, len, mes, sizeof(mes)) != 0) {
117800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "Failed to set thread info";
118800b99b8Sopenharmony_ci    }
119800b99b8Sopenharmony_ci}
120800b99b8Sopenharmony_ci
121800b99b8Sopenharmony_ciint TestThread(int threadId, int sig)
122800b99b8Sopenharmony_ci{
123800b99b8Sopenharmony_ci    std::string subThreadName = "SubTestThread" + to_string(threadId);
124800b99b8Sopenharmony_ci    prctl(PR_SET_NAME, subThreadName.c_str());
125800b99b8Sopenharmony_ci    if (SetThreadInfoCallback != nullptr) {
126800b99b8Sopenharmony_ci        SetThreadInfoCallback(ThreadInfo);
127800b99b8Sopenharmony_ci    }
128800b99b8Sopenharmony_ci    int cashThreadId = 2;
129800b99b8Sopenharmony_ci    if (threadId == cashThreadId) {
130800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << subThreadName << " is ready to raise signo(" << sig <<")";
131800b99b8Sopenharmony_ci        raise(sig);
132800b99b8Sopenharmony_ci    }
133800b99b8Sopenharmony_ci    return 0;
134800b99b8Sopenharmony_ci}
135800b99b8Sopenharmony_ci
136800b99b8Sopenharmony_ci/**
137800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest001
138800b99b8Sopenharmony_ci * @tc.desc: test thread cash SignalHandler signo(SIGILL)
139800b99b8Sopenharmony_ci * @tc.type: FUNC
140800b99b8Sopenharmony_ci */
141800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest001, TestSize.Level2)
142800b99b8Sopenharmony_ci{
143800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest001: start.";
144800b99b8Sopenharmony_ci    pid_t pid = fork();
145800b99b8Sopenharmony_ci    if (pid < 0) {
146800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
147800b99b8Sopenharmony_ci    } else if (pid == 0) {
148800b99b8Sopenharmony_ci        if (SetThreadInfoCallback != nullptr) {
149800b99b8Sopenharmony_ci            SetThreadInfoCallback(ThreadInfo);
150800b99b8Sopenharmony_ci        }
151800b99b8Sopenharmony_ci        sleep(1);
152800b99b8Sopenharmony_ci    } else {
153800b99b8Sopenharmony_ci        usleep(10000); // 10000 : sleep 10ms
154800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "process(" << getpid() << ") is ready to kill process(" << pid << ")";
155800b99b8Sopenharmony_ci        kill(pid, SIGILL);
156800b99b8Sopenharmony_ci        sleep(2); // 2 : wait for cppcrash generating
157800b99b8Sopenharmony_ci        bool ret = CheckThreadCrashKeyWords(GetCppCrashFileName(pid), pid, SIGILL);
158800b99b8Sopenharmony_ci        ASSERT_TRUE(ret);
159800b99b8Sopenharmony_ci    }
160800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest001: end.";
161800b99b8Sopenharmony_ci}
162800b99b8Sopenharmony_ci
163800b99b8Sopenharmony_ci/**
164800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest002
165800b99b8Sopenharmony_ci * @tc.desc: test thread cash SignalHandler signo(SIGBUS)
166800b99b8Sopenharmony_ci * @tc.type: FUNC
167800b99b8Sopenharmony_ci */
168800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest002, TestSize.Level2)
169800b99b8Sopenharmony_ci{
170800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest002: start.";
171800b99b8Sopenharmony_ci    pid_t pid = fork();
172800b99b8Sopenharmony_ci    if (pid < 0) {
173800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
174800b99b8Sopenharmony_ci    } else if (pid == 0) {
175800b99b8Sopenharmony_ci        if (SetThreadInfoCallback != nullptr) {
176800b99b8Sopenharmony_ci            SetThreadInfoCallback(ThreadInfo);
177800b99b8Sopenharmony_ci        }
178800b99b8Sopenharmony_ci        sleep(1);
179800b99b8Sopenharmony_ci    } else {
180800b99b8Sopenharmony_ci        usleep(10000); // 10000 : sleep 10ms
181800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "process(" << getpid() << ") is ready to kill process(" << pid << ")";
182800b99b8Sopenharmony_ci        kill(pid, SIGBUS);
183800b99b8Sopenharmony_ci        sleep(2); // 2 : wait for cppcrash generating
184800b99b8Sopenharmony_ci        bool ret = CheckThreadCrashKeyWords(GetCppCrashFileName(pid), pid, SIGBUS);
185800b99b8Sopenharmony_ci        ASSERT_TRUE(ret);
186800b99b8Sopenharmony_ci    }
187800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest002: end.";
188800b99b8Sopenharmony_ci}
189800b99b8Sopenharmony_ci
190800b99b8Sopenharmony_ci/**
191800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest003
192800b99b8Sopenharmony_ci * @tc.desc: test thread cash SignalHandler signo(SIGSEGV)
193800b99b8Sopenharmony_ci * @tc.type: FUNC
194800b99b8Sopenharmony_ci */
195800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest003, TestSize.Level2)
196800b99b8Sopenharmony_ci{
197800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest003: start.";
198800b99b8Sopenharmony_ci    pid_t pid = fork();
199800b99b8Sopenharmony_ci    if (pid < 0) {
200800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
201800b99b8Sopenharmony_ci    } else if (pid == 0) {
202800b99b8Sopenharmony_ci        if (SetThreadInfoCallback != nullptr) {
203800b99b8Sopenharmony_ci            SetThreadInfoCallback(ThreadInfo);
204800b99b8Sopenharmony_ci        }
205800b99b8Sopenharmony_ci        sleep(1);
206800b99b8Sopenharmony_ci    } else {
207800b99b8Sopenharmony_ci        usleep(10000); // 10000 : sleep 10ms
208800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << "process(" << getpid() << ") is ready to kill process(" << pid << ")";
209800b99b8Sopenharmony_ci        kill(pid, SIGSEGV);
210800b99b8Sopenharmony_ci        sleep(2); // 2 : wait for cppcrash generating
211800b99b8Sopenharmony_ci        bool ret = CheckThreadCrashKeyWords(GetCppCrashFileName(pid), pid, SIGSEGV);
212800b99b8Sopenharmony_ci        ASSERT_TRUE(ret);
213800b99b8Sopenharmony_ci    }
214800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest003: end.";
215800b99b8Sopenharmony_ci}
216800b99b8Sopenharmony_ci
217800b99b8Sopenharmony_ci/**
218800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest004
219800b99b8Sopenharmony_ci * @tc.desc: test thread crash SignalHandler in multi-thread situation signo(SIGILL)
220800b99b8Sopenharmony_ci * @tc.type: FUNC
221800b99b8Sopenharmony_ci */
222800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest004, TestSize.Level2)
223800b99b8Sopenharmony_ci{
224800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest004: start.";
225800b99b8Sopenharmony_ci    pid_t pid = fork();
226800b99b8Sopenharmony_ci    if (pid < 0) {
227800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
228800b99b8Sopenharmony_ci    } else if (pid == 0) {
229800b99b8Sopenharmony_ci        std::thread (TestThread, 1, SIGILL).join(); // 1 : first thread
230800b99b8Sopenharmony_ci        std::thread (TestThread, 2, SIGILL).join(); // 2 : second thread
231800b99b8Sopenharmony_ci        _exit(0);
232800b99b8Sopenharmony_ci    } else {
233800b99b8Sopenharmony_ci        sleep(2); // 2 : wait for cppcrash generating
234800b99b8Sopenharmony_ci        bool ret = CheckThreadCrashKeyWords(GetCppCrashFileName(pid), pid, SIGILL);
235800b99b8Sopenharmony_ci        ASSERT_TRUE(ret);
236800b99b8Sopenharmony_ci    }
237800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest004: end.";
238800b99b8Sopenharmony_ci}
239800b99b8Sopenharmony_ci
240800b99b8Sopenharmony_ci/**
241800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest005
242800b99b8Sopenharmony_ci * @tc.desc: test thread crash SignalHandler in multi-thread situation signo(SIGBUS)
243800b99b8Sopenharmony_ci * @tc.type: FUNC
244800b99b8Sopenharmony_ci */
245800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest005, TestSize.Level2)
246800b99b8Sopenharmony_ci{
247800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest005: start.";
248800b99b8Sopenharmony_ci    pid_t pid = fork();
249800b99b8Sopenharmony_ci    if (pid < 0) {
250800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
251800b99b8Sopenharmony_ci    } else if (pid == 0) {
252800b99b8Sopenharmony_ci        std::thread (TestThread, 1, SIGBUS).join(); // 1 : first thread
253800b99b8Sopenharmony_ci        std::thread (TestThread, 2, SIGBUS).join(); // 2 : second thread
254800b99b8Sopenharmony_ci        _exit(0);
255800b99b8Sopenharmony_ci    } else {
256800b99b8Sopenharmony_ci        sleep(2); // 2 : wait for cppcrash generating
257800b99b8Sopenharmony_ci        bool ret = CheckThreadCrashKeyWords(GetCppCrashFileName(pid), pid, SIGBUS);
258800b99b8Sopenharmony_ci        ASSERT_TRUE(ret);
259800b99b8Sopenharmony_ci    }
260800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest005: end.";
261800b99b8Sopenharmony_ci}
262800b99b8Sopenharmony_ci
263800b99b8Sopenharmony_ci/**
264800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest006
265800b99b8Sopenharmony_ci * @tc.desc: test thread crash SignalHandler in multi-thread situation signo(SIGSEGV)
266800b99b8Sopenharmony_ci * @tc.type: FUNC
267800b99b8Sopenharmony_ci */
268800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest006, TestSize.Level2)
269800b99b8Sopenharmony_ci{
270800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest006: start.";
271800b99b8Sopenharmony_ci    pid_t pid = fork();
272800b99b8Sopenharmony_ci    if (pid < 0) {
273800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
274800b99b8Sopenharmony_ci    } else if (pid == 0) {
275800b99b8Sopenharmony_ci        std::thread (TestThread, 1, SIGSEGV).join(); // 1 : first thread
276800b99b8Sopenharmony_ci        std::thread (TestThread, 2, SIGSEGV).join(); // 2 : second thread
277800b99b8Sopenharmony_ci        _exit(0);
278800b99b8Sopenharmony_ci    } else {
279800b99b8Sopenharmony_ci        sleep(2); // 2 : wait for cppcrash generating
280800b99b8Sopenharmony_ci        bool ret = CheckThreadCrashKeyWords(GetCppCrashFileName(pid), pid, SIGSEGV);
281800b99b8Sopenharmony_ci        ASSERT_TRUE(ret);
282800b99b8Sopenharmony_ci    }
283800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest006: end.";
284800b99b8Sopenharmony_ci}
285800b99b8Sopenharmony_ci
286800b99b8Sopenharmony_ci/**
287800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest007
288800b99b8Sopenharmony_ci * @tc.desc: test DFX_InstallSignalHandler interface
289800b99b8Sopenharmony_ci * @tc.type: FUNC
290800b99b8Sopenharmony_ci */
291800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest007, TestSize.Level2)
292800b99b8Sopenharmony_ci{
293800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest007: start.";
294800b99b8Sopenharmony_ci    int interestedSignalList[] = {
295800b99b8Sopenharmony_ci        SIGABRT, SIGBUS, SIGFPE,
296800b99b8Sopenharmony_ci        SIGSEGV, SIGSTKFLT, SIGSYS, SIGTRAP
297800b99b8Sopenharmony_ci    };
298800b99b8Sopenharmony_ci    for (int sig : interestedSignalList) {
299800b99b8Sopenharmony_ci        pid_t pid = fork();
300800b99b8Sopenharmony_ci        if (pid < 0) {
301800b99b8Sopenharmony_ci            GTEST_LOG_(ERROR) << "Failed to fork new test process.";
302800b99b8Sopenharmony_ci        } else if (pid == 0) {
303800b99b8Sopenharmony_ci            if (DFX_InstallSignalHandler != nullptr) {
304800b99b8Sopenharmony_ci                DFX_InstallSignalHandler();
305800b99b8Sopenharmony_ci            }
306800b99b8Sopenharmony_ci            sleep(1);
307800b99b8Sopenharmony_ci        } else {
308800b99b8Sopenharmony_ci            usleep(10000); // 10000 : sleep 10ms
309800b99b8Sopenharmony_ci            GTEST_LOG_(INFO) << "process(" << getpid() << ") is ready to kill << process(" << pid << ")";
310800b99b8Sopenharmony_ci            GTEST_LOG_(INFO) << "signal:" << sig;
311800b99b8Sopenharmony_ci            kill(pid, sig);
312800b99b8Sopenharmony_ci            sleep(2); // 2 : wait for cppcrash generating
313800b99b8Sopenharmony_ci            bool ret = CheckCrashKeyWords(GetCppCrashFileName(pid), pid, sig);
314800b99b8Sopenharmony_ci            ASSERT_TRUE(ret);
315800b99b8Sopenharmony_ci        }
316800b99b8Sopenharmony_ci    }
317800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest007: end.";
318800b99b8Sopenharmony_ci}
319800b99b8Sopenharmony_ci
320800b99b8Sopenharmony_ciint TestThread2(int threadId, int sig, int total, bool exitEarly)
321800b99b8Sopenharmony_ci{
322800b99b8Sopenharmony_ci    std::string subThreadName = "SubTestThread" + to_string(threadId);
323800b99b8Sopenharmony_ci    prctl(PR_SET_NAME, subThreadName.c_str());
324800b99b8Sopenharmony_ci    if (SetThreadInfoCallback != nullptr) {
325800b99b8Sopenharmony_ci        SetThreadInfoCallback(ThreadInfo);
326800b99b8Sopenharmony_ci    }
327800b99b8Sopenharmony_ci    if (threadId == total - 1) {
328800b99b8Sopenharmony_ci        GTEST_LOG_(INFO) << subThreadName << " is ready to raise signo(" << sig <<")";
329800b99b8Sopenharmony_ci        raise(sig);
330800b99b8Sopenharmony_ci    }
331800b99b8Sopenharmony_ci
332800b99b8Sopenharmony_ci    if (!exitEarly) {
333800b99b8Sopenharmony_ci        sleep(total - threadId);
334800b99b8Sopenharmony_ci    }
335800b99b8Sopenharmony_ci    if (SetThreadInfoCallback != nullptr) {
336800b99b8Sopenharmony_ci        SetThreadInfoCallback(ThreadInfo);
337800b99b8Sopenharmony_ci    }
338800b99b8Sopenharmony_ci    return 0;
339800b99b8Sopenharmony_ci}
340800b99b8Sopenharmony_ci
341800b99b8Sopenharmony_ci/**
342800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest008
343800b99b8Sopenharmony_ci * @tc.desc: test add 36 thread info callback and crash thread has no callback
344800b99b8Sopenharmony_ci * @tc.type: FUNC
345800b99b8Sopenharmony_ci */
346800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest008, TestSize.Level2)
347800b99b8Sopenharmony_ci{
348800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest008: start.";
349800b99b8Sopenharmony_ci    pid_t pid = fork();
350800b99b8Sopenharmony_ci    if (pid < 0) {
351800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
352800b99b8Sopenharmony_ci    } else if (pid == 0) {
353800b99b8Sopenharmony_ci        std::vector<std::thread> threads;
354800b99b8Sopenharmony_ci        const int testThreadCount = 36;
355800b99b8Sopenharmony_ci        for (int i = 0; i < testThreadCount; i++) {
356800b99b8Sopenharmony_ci            threads.push_back(std::thread(TestThread2, i, SIGSEGV, testThreadCount, false));
357800b99b8Sopenharmony_ci        }
358800b99b8Sopenharmony_ci
359800b99b8Sopenharmony_ci        for (auto& thread : threads) {
360800b99b8Sopenharmony_ci            thread.join();
361800b99b8Sopenharmony_ci        }
362800b99b8Sopenharmony_ci        _exit(0);
363800b99b8Sopenharmony_ci    } else {
364800b99b8Sopenharmony_ci        sleep(2); // 2 : wait for cppcrash generating
365800b99b8Sopenharmony_ci        auto file = GetCppCrashFileName(pid);
366800b99b8Sopenharmony_ci        ASSERT_FALSE(file.empty());
367800b99b8Sopenharmony_ci    }
368800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest008: end.";
369800b99b8Sopenharmony_ci}
370800b99b8Sopenharmony_ci
371800b99b8Sopenharmony_ci/**
372800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest009
373800b99b8Sopenharmony_ci * @tc.desc: test add 36 thread info callback and crash thread has the callback
374800b99b8Sopenharmony_ci * @tc.type: FUNC
375800b99b8Sopenharmony_ci */
376800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest009, TestSize.Level2)
377800b99b8Sopenharmony_ci{
378800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest009: start.";
379800b99b8Sopenharmony_ci    pid_t pid = fork();
380800b99b8Sopenharmony_ci    if (pid < 0) {
381800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
382800b99b8Sopenharmony_ci    } else if (pid == 0) {
383800b99b8Sopenharmony_ci        std::vector<std::thread> threads;
384800b99b8Sopenharmony_ci        const int testThreadCount = 36;
385800b99b8Sopenharmony_ci        for (int i = 0; i < testThreadCount; i++) {
386800b99b8Sopenharmony_ci            bool exitEarly = false;
387800b99b8Sopenharmony_ci            if (i % 2 == 0) {
388800b99b8Sopenharmony_ci                exitEarly =  true;
389800b99b8Sopenharmony_ci            }
390800b99b8Sopenharmony_ci            threads.push_back(std::thread (TestThread2, i, SIGSEGV, testThreadCount, exitEarly));
391800b99b8Sopenharmony_ci        }
392800b99b8Sopenharmony_ci
393800b99b8Sopenharmony_ci        for (auto& thread : threads) {
394800b99b8Sopenharmony_ci            thread.join();
395800b99b8Sopenharmony_ci        }
396800b99b8Sopenharmony_ci        _exit(0);
397800b99b8Sopenharmony_ci    } else {
398800b99b8Sopenharmony_ci        sleep(2); // 2 : wait for cppcrash generating
399800b99b8Sopenharmony_ci        auto file = GetCppCrashFileName(pid);
400800b99b8Sopenharmony_ci        ASSERT_FALSE(file.empty());
401800b99b8Sopenharmony_ci    }
402800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest009: end.";
403800b99b8Sopenharmony_ci}
404800b99b8Sopenharmony_ci
405800b99b8Sopenharmony_ci/**
406800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest010
407800b99b8Sopenharmony_ci * @tc.desc: test crash when free a invalid address
408800b99b8Sopenharmony_ci * @tc.type: FUNC
409800b99b8Sopenharmony_ci */
410800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest010, TestSize.Level2)
411800b99b8Sopenharmony_ci{
412800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest010: start.";
413800b99b8Sopenharmony_ci    pid_t pid = fork();
414800b99b8Sopenharmony_ci    if (pid < 0) {
415800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
416800b99b8Sopenharmony_ci    } else if (pid == 0) {
417800b99b8Sopenharmony_ci        if (SetThreadInfoCallback != nullptr) {
418800b99b8Sopenharmony_ci            SetThreadInfoCallback(ThreadInfo);
419800b99b8Sopenharmony_ci        }
420800b99b8Sopenharmony_ci        int32_t freeAddr = 0x111;
421800b99b8Sopenharmony_ci        // trigger crash
422800b99b8Sopenharmony_ci        free(reinterpret_cast<void*>(freeAddr));
423800b99b8Sopenharmony_ci        // force crash if not crash in free
424800b99b8Sopenharmony_ci        abort();
425800b99b8Sopenharmony_ci    } else {
426800b99b8Sopenharmony_ci        sleep(2); // 2 : wait for cppcrash generating
427800b99b8Sopenharmony_ci        auto file = GetCppCrashFileName(pid);
428800b99b8Sopenharmony_ci        ASSERT_FALSE(file.empty());
429800b99b8Sopenharmony_ci    }
430800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest010: end.";
431800b99b8Sopenharmony_ci}
432800b99b8Sopenharmony_ci
433800b99b8Sopenharmony_ci/**
434800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest011
435800b99b8Sopenharmony_ci * @tc.desc: test crash when realloc a invalid address
436800b99b8Sopenharmony_ci * @tc.type: FUNC
437800b99b8Sopenharmony_ci */
438800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest011, TestSize.Level2)
439800b99b8Sopenharmony_ci{
440800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest011: start.";
441800b99b8Sopenharmony_ci    pid_t pid = fork();
442800b99b8Sopenharmony_ci    if (pid < 0) {
443800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
444800b99b8Sopenharmony_ci    } else if (pid == 0) {
445800b99b8Sopenharmony_ci        int32_t initAllocSz = 10;
446800b99b8Sopenharmony_ci        int32_t reallocSz = 20;
447800b99b8Sopenharmony_ci        if (SetThreadInfoCallback != nullptr) {
448800b99b8Sopenharmony_ci            SetThreadInfoCallback(ThreadInfo);
449800b99b8Sopenharmony_ci        }
450800b99b8Sopenharmony_ci        // alloc a buffer
451800b99b8Sopenharmony_ci        int8_t* addr = reinterpret_cast<int8_t*>(malloc(initAllocSz));
452800b99b8Sopenharmony_ci        // overwrite the control block
453800b99b8Sopenharmony_ci        int8_t* newAddr = addr - initAllocSz;
454800b99b8Sopenharmony_ci        (void)memset_s(newAddr, initAllocSz, 0, initAllocSz);
455800b99b8Sopenharmony_ci        addr = reinterpret_cast<int8_t*>(realloc(reinterpret_cast<void*>(addr), reallocSz));
456800b99b8Sopenharmony_ci        free(addr);
457800b99b8Sopenharmony_ci        // force crash if not crash in realloc
458800b99b8Sopenharmony_ci        abort();
459800b99b8Sopenharmony_ci    } else {
460800b99b8Sopenharmony_ci        sleep(2); // 2 : wait for cppcrash generating
461800b99b8Sopenharmony_ci        auto file = GetCppCrashFileName(pid);
462800b99b8Sopenharmony_ci        ASSERT_FALSE(file.empty());
463800b99b8Sopenharmony_ci    }
464800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest011: end.";
465800b99b8Sopenharmony_ci}
466800b99b8Sopenharmony_ci
467800b99b8Sopenharmony_ci/**
468800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest012
469800b99b8Sopenharmony_ci * @tc.desc: test crash when realloc a invalid address without threadInfo callback
470800b99b8Sopenharmony_ci * @tc.type: FUNC
471800b99b8Sopenharmony_ci */
472800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest012, TestSize.Level2)
473800b99b8Sopenharmony_ci{
474800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest012: start.";
475800b99b8Sopenharmony_ci    pid_t pid = fork();
476800b99b8Sopenharmony_ci    if (pid < 0) {
477800b99b8Sopenharmony_ci        GTEST_LOG_(ERROR) << "Failed to fork new test process.";
478800b99b8Sopenharmony_ci    } else if (pid == 0) {
479800b99b8Sopenharmony_ci        int32_t initAllocSz = 10;
480800b99b8Sopenharmony_ci        int32_t reallocSz = 20;
481800b99b8Sopenharmony_ci        // alloc a buffer
482800b99b8Sopenharmony_ci        int8_t* addr = reinterpret_cast<int8_t*>(malloc(initAllocSz));
483800b99b8Sopenharmony_ci        // overwrite the control block
484800b99b8Sopenharmony_ci        int8_t* newAddr = addr - initAllocSz;
485800b99b8Sopenharmony_ci        (void)memset_s(newAddr, initAllocSz, 0, initAllocSz);
486800b99b8Sopenharmony_ci        addr = reinterpret_cast<int8_t*>(realloc(reinterpret_cast<void*>(addr), reallocSz));
487800b99b8Sopenharmony_ci        free(addr);
488800b99b8Sopenharmony_ci        // force crash if not crash in realloc
489800b99b8Sopenharmony_ci        abort();
490800b99b8Sopenharmony_ci    } else {
491800b99b8Sopenharmony_ci        sleep(2); // 2 : wait for cppcrash generating
492800b99b8Sopenharmony_ci        auto file = GetCppCrashFileName(pid);
493800b99b8Sopenharmony_ci        ASSERT_FALSE(file.empty());
494800b99b8Sopenharmony_ci    }
495800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest012: end.";
496800b99b8Sopenharmony_ci}
497800b99b8Sopenharmony_ci
498800b99b8Sopenharmony_ci/**
499800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest013
500800b99b8Sopenharmony_ci * @tc.desc: test add 100 thread info callback and do nothing
501800b99b8Sopenharmony_ci * @tc.type: FUNC
502800b99b8Sopenharmony_ci */
503800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest013, TestSize.Level2)
504800b99b8Sopenharmony_ci{
505800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest013: start.";
506800b99b8Sopenharmony_ci    std::vector<std::thread> threads;
507800b99b8Sopenharmony_ci    const int testThreadCount = 100;
508800b99b8Sopenharmony_ci    for (int i = 0; i < testThreadCount - 1; i++) {
509800b99b8Sopenharmony_ci        threads.push_back(std::thread (TestThread2, i, SIGSEGV, testThreadCount, true));
510800b99b8Sopenharmony_ci    }
511800b99b8Sopenharmony_ci
512800b99b8Sopenharmony_ci    for (auto& thread : threads) {
513800b99b8Sopenharmony_ci        if (thread.joinable()) {
514800b99b8Sopenharmony_ci            thread.join();
515800b99b8Sopenharmony_ci        }
516800b99b8Sopenharmony_ci    }
517800b99b8Sopenharmony_ci    auto file = GetCppCrashFileName(getpid());
518800b99b8Sopenharmony_ci    ASSERT_TRUE(file.empty());
519800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest013: end.";
520800b99b8Sopenharmony_ci}
521800b99b8Sopenharmony_ci
522800b99b8Sopenharmony_civoid TestCallbackFunc()
523800b99b8Sopenharmony_ci{}
524800b99b8Sopenharmony_ci
525800b99b8Sopenharmony_ci/**
526800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest015
527800b99b8Sopenharmony_ci * @tc.desc: test DFX_SetAppRunningUniqueId
528800b99b8Sopenharmony_ci * @tc.type: FUNC
529800b99b8Sopenharmony_ci */
530800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest015, TestSize.Level2)
531800b99b8Sopenharmony_ci{
532800b99b8Sopenharmony_ci    bool isSuccess = DFX_SetAppRunningUniqueId != nullptr;
533800b99b8Sopenharmony_ci    if (!isSuccess) {
534800b99b8Sopenharmony_ci        ASSERT_FALSE(isSuccess);
535800b99b8Sopenharmony_ci        return;
536800b99b8Sopenharmony_ci    }
537800b99b8Sopenharmony_ci    /**
538800b99b8Sopenharmony_ci     * @tc.steps: step1.
539800b99b8Sopenharmony_ci     *            case: appRunningId == nullptr, len= 0
540800b99b8Sopenharmony_ci     * @tc.expected: ret == -1
541800b99b8Sopenharmony_ci     * */
542800b99b8Sopenharmony_ci    int ret = DFX_SetAppRunningUniqueId(nullptr, 0);
543800b99b8Sopenharmony_ci    ASSERT_EQ(ret, -1);
544800b99b8Sopenharmony_ci
545800b99b8Sopenharmony_ci    /**
546800b99b8Sopenharmony_ci     * @tc.steps: step2.
547800b99b8Sopenharmony_ci     *            case: appRunningId == nullptr, len= MAX_APP_RUNNING_UNIQUE_ID_LEN
548800b99b8Sopenharmony_ci     * @tc.expected: ret == -1
549800b99b8Sopenharmony_ci     * */
550800b99b8Sopenharmony_ci    ret = DFX_SetAppRunningUniqueId(nullptr, MAX_APP_RUNNING_UNIQUE_ID_LEN);
551800b99b8Sopenharmony_ci    ASSERT_EQ(ret, -1);
552800b99b8Sopenharmony_ci
553800b99b8Sopenharmony_ci    /**
554800b99b8Sopenharmony_ci     * @tc.steps: step3.
555800b99b8Sopenharmony_ci     *            case: appRunningId != nullptr, len= 0
556800b99b8Sopenharmony_ci     * @tc.expected: ret == 0
557800b99b8Sopenharmony_ci     * */
558800b99b8Sopenharmony_ci    constexpr char testId1[] = "App running unique test id";
559800b99b8Sopenharmony_ci    ret = DFX_SetAppRunningUniqueId(testId1, 0);
560800b99b8Sopenharmony_ci    ASSERT_EQ(ret, 0);
561800b99b8Sopenharmony_ci
562800b99b8Sopenharmony_ci    /**
563800b99b8Sopenharmony_ci     * @tc.steps: step4.
564800b99b8Sopenharmony_ci     *            case: appRunningId != nullptr, len= strleng(appRunningId)
565800b99b8Sopenharmony_ci     * @tc.expected: ret == 0
566800b99b8Sopenharmony_ci     * */
567800b99b8Sopenharmony_ci    ret = DFX_SetAppRunningUniqueId(testId1, strlen(testId1));
568800b99b8Sopenharmony_ci    ASSERT_EQ(ret, 0);
569800b99b8Sopenharmony_ci
570800b99b8Sopenharmony_ci    /**
571800b99b8Sopenharmony_ci     * @tc.steps: step5.
572800b99b8Sopenharmony_ci     *            case: appRunningId != nullptr, len= MAX_APP_RUNNING_UNIQUE_ID_LEN + 1
573800b99b8Sopenharmony_ci     * @tc.expected: ret == -1
574800b99b8Sopenharmony_ci     * */
575800b99b8Sopenharmony_ci    constexpr size_t testLen = MAX_APP_RUNNING_UNIQUE_ID_LEN + 1;
576800b99b8Sopenharmony_ci    ret = DFX_SetAppRunningUniqueId(testId1, testLen);
577800b99b8Sopenharmony_ci    ASSERT_EQ(ret, -1);
578800b99b8Sopenharmony_ci
579800b99b8Sopenharmony_ci    /**
580800b99b8Sopenharmony_ci     * @tc.steps: step6.
581800b99b8Sopenharmony_ci     *            case: appRunningId != nullptr, len= MAX_APP_RUNNING_UNIQUE_ID_LEN
582800b99b8Sopenharmony_ci     * @tc.expected: ret == 0
583800b99b8Sopenharmony_ci     * */
584800b99b8Sopenharmony_ci    constexpr char testId2[MAX_APP_RUNNING_UNIQUE_ID_LEN] = "App running unique test id";
585800b99b8Sopenharmony_ci    ret = DFX_SetAppRunningUniqueId(testId2, MAX_APP_RUNNING_UNIQUE_ID_LEN);
586800b99b8Sopenharmony_ci    ASSERT_EQ(ret, -1);
587800b99b8Sopenharmony_ci}
588800b99b8Sopenharmony_ci
589800b99b8Sopenharmony_ci/**
590800b99b8Sopenharmony_ci * @tc.name: SignalHandlerTest016
591800b99b8Sopenharmony_ci * @tc.desc: test ReportException
592800b99b8Sopenharmony_ci * @tc.type: FUNC
593800b99b8Sopenharmony_ci */
594800b99b8Sopenharmony_ciHWTEST_F(SignalHandlerTest, SignalHandlerTest016, TestSize.Level2)
595800b99b8Sopenharmony_ci{
596800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest016: start.";
597800b99b8Sopenharmony_ci    if (SetAsyncStackCallbackFunc != nullptr) {
598800b99b8Sopenharmony_ci        SetAsyncStackCallbackFunc(reinterpret_cast<void*>(TestCallbackFunc));
599800b99b8Sopenharmony_ci    }
600800b99b8Sopenharmony_ci
601800b99b8Sopenharmony_ci    struct CrashDumpException exception;
602800b99b8Sopenharmony_ci    exception.pid = 1;
603800b99b8Sopenharmony_ci    exception.uid = 1;
604800b99b8Sopenharmony_ci    exception.error = CRASH_SIGNAL_EMASKED;
605800b99b8Sopenharmony_ci    int ret = ReportException(exception);
606800b99b8Sopenharmony_ci    ASSERT_NE(ret, -1);
607800b99b8Sopenharmony_ci    GTEST_LOG_(INFO) << "SignalHandlerTest016: end.";
608800b99b8Sopenharmony_ci}
609800b99b8Sopenharmony_ci} // namespace HiviewDFX
610800b99b8Sopenharmony_ci} // namepsace OHOS
611