1 /*
2  * Copyright (c) 2022-2024 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 
18 #include <string>
19 #include <thread>
20 #include <vector>
21 
22 #include <unistd.h>
23 
24 #include "dfx_define.h"
25 #include "dfx_dump_catcher.h"
26 #include "dfx_json_formatter.h"
27 #include "dfx_test_util.h"
28 #include "faultloggerd_client.h"
29 #include "procinfo.h"
30 
31 using namespace testing;
32 using namespace testing::ext;
33 
34 namespace OHOS {
35 namespace HiviewDFX {
36 class DumpCatcherInterfacesTest : public testing::Test {
37 public:
38     static void SetUpTestCase();
39     static void TearDownTestCase();
40     void SetUp();
41     void TearDown();
42 };
43 
44 static const int THREAD_ALIVE_TIME = 2;
45 
46 static const int CREATE_THREAD_TIMEOUT = 300000;
47 
48 static pid_t g_threadId = 0;
49 
50 static pid_t g_processId = 0;
51 
52 int g_testPid = 0;
53 
SetUpTestCase()54 void DumpCatcherInterfacesTest::SetUpTestCase()
55 {
56     InstallTestHap("/data/FaultloggerdJsTest.hap");
57     std::string testBundleName = TEST_BUNDLE_NAME;
58     std::string testAbiltyName = testBundleName + ".MainAbility";
59     g_testPid = LaunchTestHap(testAbiltyName, testBundleName);
60 }
61 
TearDownTestCase()62 void DumpCatcherInterfacesTest::TearDownTestCase()
63 {
64     StopTestHap(TEST_BUNDLE_NAME);
65     UninstallTestHap(TEST_BUNDLE_NAME);
66 }
67 
SetUp()68 void DumpCatcherInterfacesTest::SetUp()
69 {}
70 
TearDown()71 void DumpCatcherInterfacesTest::TearDown()
72 {}
73 
TestFunRecursive(int recursiveCount)74 static void TestFunRecursive(int recursiveCount)
75 {
76     GTEST_LOG_(INFO) << "Enter TestFunRecursive recursiveCount:" << recursiveCount;
77     if (recursiveCount <= 0) {
78         GTEST_LOG_(INFO) << "start enter sleep" << gettid();
79         sleep(THREAD_ALIVE_TIME);
80         GTEST_LOG_(INFO) << "sleep end.";
81     } else {
82         TestFunRecursive(recursiveCount - 1);
83     }
84 }
85 
CreateRecursiveThread(void *argv)86 static void* CreateRecursiveThread(void *argv)
87 {
88     g_threadId = gettid();
89     GTEST_LOG_(INFO) << "create Recursive MultiThread " << gettid();
90     TestFunRecursive(266); // 266: set recursive count to 266, used for dumpcatcher get stack info
91     GTEST_LOG_(INFO) << "Recursive MultiThread thread sleep end.";
92     return nullptr;
93 }
94 
RecursiveMultiThreadConstructor(void)95 static int RecursiveMultiThreadConstructor(void)
96 {
97     pthread_t thread;
98     pthread_create(&thread, nullptr, CreateRecursiveThread, nullptr);
99     pthread_detach(thread);
100     usleep(CREATE_THREAD_TIMEOUT);
101     return 0;
102 }
103 
CreateThread(void *argv)104 static void* CreateThread(void *argv)
105 {
106     g_threadId = gettid();
107     GTEST_LOG_(INFO) << "create MultiThread " << gettid();
108     sleep(THREAD_ALIVE_TIME);
109     GTEST_LOG_(INFO) << "create MultiThread thread sleep end.";
110     return nullptr;
111 }
112 
MultiThreadConstructor(void)113 static int MultiThreadConstructor(void)
114 {
115     pthread_t thread;
116     pthread_create(&thread, nullptr, CreateThread, nullptr);
117     pthread_detach(thread);
118     usleep(CREATE_THREAD_TIMEOUT);
119     return 0;
120 }
121 
ForkMultiThreadProcess(void)122 static void ForkMultiThreadProcess(void)
123 {
124     int pid = fork();
125     if (pid == 0) {
126         MultiThreadConstructor();
127         _exit(0);
128     } else if (pid < 0) {
129         GTEST_LOG_(INFO) << "ForkMultiThreadProcess fail. ";
130     } else {
131         g_processId = pid;
132         GTEST_LOG_(INFO) << "ForkMultiThreadProcess success, pid: " << pid;
133     }
134 }
135 
136 /**
137  * @tc.name: DumpCatcherInterfacesTest001
138  * @tc.desc: test DumpCatchMultiPid API: multiPid{PID(accountmgr), PID(foundation)}
139  * @tc.type: FUNC
140  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest001, TestSize.Level2)141 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest001, TestSize.Level2)
142 {
143     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest001: start.";
144     std::string testProcess1 = "accountmgr";
145     int testPid1 = GetProcessPid(testProcess1);
146     GTEST_LOG_(INFO) << "testPid1:" << testPid1;
147     std::string testProcess2 = "foundation";
148     int testPid2 = GetProcessPid(testProcess2);
149     GTEST_LOG_(INFO) << "testPid2:" << testPid2;
150     std::vector<int> multiPid {testPid1, testPid2};
151     DfxDumpCatcher dumplog;
152     std::string msg = "";
153     bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
154     GTEST_LOG_(INFO) << ret;
155     string log[] = {"Tid:", "Name:", "Tid:", "Name:"};
156     log[0] = log[0] + std::to_string(testPid1);
157     log[1] = log[1] + testProcess1;
158     log[2] = log[2] + std::to_string(testPid2);
159     log[3] = log[3] + testProcess2;
160     int len = sizeof(log) / sizeof(log[0]);
161     int count = GetKeywordsNum(msg, log, len);
162     EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest001 Failed";
163     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest001: end.";
164 }
165 
166 /**
167  * @tc.name: DumpCatcherInterfacesTest002
168  * @tc.desc: test DumpCatchMultiPid API: multiPid{0, 0}
169  * @tc.type: FUNC
170  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest002, TestSize.Level2)171 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest002, TestSize.Level2)
172 {
173     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest002: start.";
174     int testPid1 = 0;
175     GTEST_LOG_(INFO) << "testPid1:" << testPid1;
176     int testPid2 = 0;
177     GTEST_LOG_(INFO) << "testPid2:" << testPid2;
178     std::vector<int> multiPid {testPid1, testPid2};
179     DfxDumpCatcher dumplog;
180     std::string msg = "";
181     bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
182     GTEST_LOG_(INFO) << ret;
183     EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest002 Failed";
184     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest002: end.";
185 }
186 
187 /**
188  * @tc.name: DumpCatcherInterfacesTest003
189  * @tc.desc: test DumpCatchMultiPid API: multiPid{-11, -11}
190  * @tc.type: FUNC
191  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest003, TestSize.Level2)192 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest003, TestSize.Level2)
193 {
194     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest003: start.";
195     int testPid1 = -11;
196     GTEST_LOG_(INFO) << "testPid1:" << testPid1;
197     int testPid2 = -11;
198     GTEST_LOG_(INFO) << "testPid2:" << testPid2;
199     std::vector<int> multiPid {testPid1, testPid2};
200     DfxDumpCatcher dumplog;
201     std::string msg = "";
202     bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
203     GTEST_LOG_(INFO) << ret;
204     EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest003 Failed";
205     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest003: end.";
206 }
207 
208 /**
209  * @tc.name: DumpCatcherInterfacesTest004
210  * @tc.desc: test DumpCatchMultiPid API: multiPid{PID(accountmgr), 0}
211  * @tc.type: FUNC
212  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest004, TestSize.Level2)213 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest004, TestSize.Level2)
214 {
215     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest004: start.";
216     std::string testProcess = "accountmgr";
217     int applyPid1 = GetProcessPid(testProcess);
218     GTEST_LOG_(INFO) << "applyPid1:" << applyPid1;
219     int applyPid2 = 0;
220     GTEST_LOG_(INFO) << "applyPid2:" << applyPid2;
221     std::vector<int> multiPid {applyPid1, applyPid2};
222     DfxDumpCatcher dumplog;
223     std::string msg = "";
224     bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
225     GTEST_LOG_(INFO) << ret;
226     string log[] = { "Tid:", "Name:", "Failed" };
227     log[0] = log[0] + std::to_string(applyPid1);
228     log[1] = log[1] + "accountmgr";
229     int len = sizeof(log) / sizeof(log[0]);
230     int count = GetKeywordsNum(msg, log, len);
231     EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest004 Failed";
232     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest004: end.";
233 }
234 
235 /**
236  * @tc.name: DumpCatcherInterfacesTest005
237  * @tc.desc: test DumpCatchMultiPid API: multiPid{PID(accountmgr),PID(foundation),PID(systemui)}
238  * @tc.type: FUNC
239  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest005, TestSize.Level2)240 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest005, TestSize.Level2)
241 {
242     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest005: start.";
243     std::vector<string> testProcessName = { "accountmgr", "foundation", "com.ohos.systemui" };
244     string matchProcessName[] = { "accountmgr", "foundation", "m.ohos.systemui" };
245     std::vector<int> multiPid;
246     std::vector<string> matchLog;
247     int index = 0;
248     for (string oneProcessName : testProcessName) {
249         int testPid = GetProcessPid(oneProcessName);
250         if (testPid == 0) {
251             GTEST_LOG_(INFO) << "process:" << oneProcessName << " pid is empty, skip";
252             index++;
253             continue;
254         }
255         multiPid.emplace_back(testPid);
256         matchLog.emplace_back("Tid:" + std::to_string(testPid));
257         matchLog.emplace_back("Name:" + matchProcessName[index]);
258         index++;
259     }
260 
261     // It is recommended that the number of effective pids be greater than 1,
262     // otherwise the testing purpose will not be achieved
263     EXPECT_GT(multiPid.size(), 1) << "DumpCatcherInterfacesTest005 Failed";
264 
265     DfxDumpCatcher dumplog;
266     std::string msg = "";
267     bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
268     GTEST_LOG_(INFO) << "ret:" << ret;
269 
270     int matchLogCount = matchLog.size();
271     auto matchLogArray = std::make_unique<string[]>(matchLogCount);
272     index = 0;
273     for (string info : matchLog) {
274         matchLogArray[index] = info;
275         index++;
276     }
277     int count = GetKeywordsNum(msg, matchLogArray.get(), matchLogCount);
278     EXPECT_EQ(count, matchLogCount) << msg << "DumpCatcherInterfacesTest005 Failed";
279     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest005: end.";
280 }
281 
282 /**
283  * @tc.name: DumpCatcherInterfacesTest006
284  * @tc.desc: test DumpCatchMultiPid API: multiPid{PID(accountmgr), -11}
285  * @tc.type: FUNC
286  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest006, TestSize.Level2)287 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest006, TestSize.Level2)
288 {
289     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest006: start.";
290     std::string testProcess = "accountmgr";
291     int testPid1 = GetProcessPid(testProcess);
292     GTEST_LOG_(INFO) << "applyPid1:" << testPid1;
293     int testPid2 = -11;
294     GTEST_LOG_(INFO) << "applyPid2:" << testPid2;
295     std::vector<int> multiPid {testPid1, testPid2};
296     DfxDumpCatcher dumplog;
297     std::string msg = "";
298     bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
299     GTEST_LOG_(INFO) << ret;
300     string log[] = { "Tid:", "Name:", "Failed"};
301     log[0] = log[0] + std::to_string(testPid1);
302     log[1] = log[1] + "accountmgr";
303     int len = sizeof(log) / sizeof(log[0]);
304     int count = GetKeywordsNum(msg, log, len);
305     EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest006 Failed";
306     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest006: end.";
307 }
308 
309 /**
310  * @tc.name: DumpCatcherInterfacesTest007
311  * @tc.desc: test DumpCatchMultiPid API: multiPid{9999, 9999}
312  * @tc.type: FUNC
313  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest007, TestSize.Level2)314 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest007, TestSize.Level2)
315 {
316     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest007: start.";
317     int applyPid = 9999;
318     GTEST_LOG_(INFO) << "applyPid1:" << applyPid;
319     std::vector<int> multiPid {applyPid, applyPid};
320     DfxDumpCatcher dumplog;
321     std::string msg = "";
322     bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
323     GTEST_LOG_(INFO) << ret;
324     EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest007 Failed";
325     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest007: end.";
326 }
327 
328 /**
329  * @tc.name: DumpCatcherInterfacesTest008
330  * @tc.desc: test DumpCatchMultiPid API: multiPid{PID(accountmgr), 9999}
331  * @tc.type: FUNC
332  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest008, TestSize.Level2)333 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest008, TestSize.Level2)
334 {
335     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest008: start.";
336     std::string apply = "accountmgr";
337     int applyPid1 = GetProcessPid(apply);
338     GTEST_LOG_(INFO) << "applyPid1:" << applyPid1;
339     int applyPid2 = 9999;
340     GTEST_LOG_(INFO) << "applyPid2:" << applyPid2;
341     std::vector<int> multiPid {applyPid1, applyPid2};
342     DfxDumpCatcher dumplog;
343     std::string msg = "";
344     bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
345     GTEST_LOG_(INFO) << ret;
346     string log[] = { "Tid:", "Name:", "Failed"};
347     log[0] = log[0] + std::to_string(applyPid1);
348     log[1] = log[1] + apply;
349     int len = sizeof(log) / sizeof(log[0]);
350     int count = GetKeywordsNum(msg, log, len);
351     EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest008 Failed";
352     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest008: end.";
353 }
354 
355 /**
356  * @tc.name: DumpCatcherInterfacesTest014
357  * @tc.desc: test DumpCatch API: PID(test hap), TID(0)
358  * @tc.type: FUNC
359  * @tc.require: issueI5PJ9O
360  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest014, TestSize.Level2)361 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest014, TestSize.Level2)
362 {
363     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest014: start.";
364     bool isSuccess = g_testPid != 0;
365     if (!isSuccess) {
366         ASSERT_FALSE(isSuccess);
367         GTEST_LOG_(ERROR) << "Failed to launch target hap.";
368         return;
369     }
370     isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
371     if (!isSuccess) {
372         ASSERT_FALSE(isSuccess);
373         GTEST_LOG_(ERROR) << "Error process comm";
374         return;
375     }
376     DfxDumpCatcher dumplog;
377     std::string msg = "";
378     bool ret = dumplog.DumpCatch(g_testPid, 0, msg);
379     GTEST_LOG_(INFO) << ret;
380     string log[] = { "Tid:", "Name:", "#00", "/system/bin/appspawn", "Name:OS_DfxWatchdog" };
381     log[0] += std::to_string(g_testPid);
382     log[1] += TRUNCATE_TEST_BUNDLE_NAME;
383     int len = sizeof(log) / sizeof(log[0]);
384     int count = GetKeywordsNum(msg, log, len);
385     EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest014 Failed";
386     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest014: end.";
387 }
388 
389 /**
390  * @tc.name: DumpCatcherInterfacesTest015
391  * @tc.desc: test DumpCatch API: PID(test hap), TID(test hap main thread)
392  * @tc.type: FUNC
393  * @tc.require: issueI5PJ9O
394  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest015, TestSize.Level2)395 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest015, TestSize.Level2)
396 {
397     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest015: start.";
398     bool isSuccess = g_testPid != 0;
399     if (!isSuccess) {
400         ASSERT_FALSE(isSuccess);
401         GTEST_LOG_(ERROR) << "Failed to launch target hap.";
402         return;
403     }
404     isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
405     if (!isSuccess) {
406         ASSERT_FALSE(isSuccess);
407         GTEST_LOG_(ERROR) << "Error process comm";
408         return;
409     }
410     DfxDumpCatcher dumplog;
411     std::string msg = "";
412     bool ret = dumplog.DumpCatch(g_testPid, g_testPid, msg);
413     GTEST_LOG_(INFO) << ret;
414     string log[] = { "Tid:", "Name:", "#00", "/system/bin/appspawn"};
415     log[0] += std::to_string(g_testPid);
416     log[1] += TRUNCATE_TEST_BUNDLE_NAME;
417     int len = sizeof(log) / sizeof(log[0]);
418     int count = GetKeywordsNum(msg, log, len);
419     GTEST_LOG_(INFO) << msg;
420     EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest015 Failed";
421     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest015: end.";
422 }
423 
424 /**
425  * @tc.name: DumpCatcherInterfacesTest016
426  * @tc.desc: test DumpCatch API: PID(test hap), TID(-1)
427  * @tc.type: FUNC
428  * @tc.require: issueI5PJ9O
429  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest016, TestSize.Level2)430 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest016, TestSize.Level2)
431 {
432     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest016: start.";
433     bool isSuccess = g_testPid != 0;
434     if (!isSuccess) {
435         ASSERT_FALSE(isSuccess);
436         GTEST_LOG_(ERROR) << "Failed to launch target hap.";
437         return;
438     }
439     isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
440     if (!isSuccess) {
441         ASSERT_FALSE(isSuccess);
442         GTEST_LOG_(ERROR) << "Error process comm";
443         return;
444     }
445     DfxDumpCatcher dumplog;
446     std::string msg = "";
447     bool ret = dumplog.DumpCatch(g_testPid, -1, msg);
448     GTEST_LOG_(INFO) << ret;
449     EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest016 Failed";
450     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest016: end.";
451 }
452 
453 /**
454  * @tc.name: DumpCatcherInterfacesTest017
455  * @tc.desc: test DumpCatch API: PID(-1), TID(-1)
456  * @tc.type: FUNC
457  * @tc.require: issueI5PJ9O
458  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest017, TestSize.Level2)459 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest017, TestSize.Level2)
460 {
461     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest017: start.";
462     DfxDumpCatcher dumplog;
463     std::string msg = "";
464     bool ret = dumplog.DumpCatch(-1, -1, msg);
465     GTEST_LOG_(INFO) << ret;
466     EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest017 Failed";
467     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest017: end.";
468 }
469 
470 /**
471  * @tc.name: DumpCatcherInterfacesTest018
472  * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(gettid())
473  * @tc.type: FUNC
474  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest018, TestSize.Level2)475 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest018, TestSize.Level2)
476 {
477     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest018: start.";
478     DfxDumpCatcher dumplog;
479     std::string msg = "";
480     bool ret = dumplog.DumpCatchFd(getpid(), gettid(), msg, 1);
481     GTEST_LOG_(INFO) << ret;
482     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest018 Failed";
483     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest018: end.";
484 }
485 
486 /**
487  * @tc.name: DumpCatcherInterfacesTest019
488  * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(0)
489  * @tc.type: FUNC
490  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest019, TestSize.Level2)491 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest019, TestSize.Level2)
492 {
493     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest019: start.";
494     DfxDumpCatcher dumplog;
495     std::string msg = "";
496     bool ret = dumplog.DumpCatchFd(getpid(), 0, msg, 1);
497     GTEST_LOG_(INFO) << ret;
498     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest019 Failed";
499     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest019: end.";
500 }
501 
502 /**
503  * @tc.name: DumpCatcherInterfacesTest020
504  * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(-1)
505  * @tc.type: FUNC
506  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest020, TestSize.Level2)507 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest020, TestSize.Level2)
508 {
509     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest020: start.";
510     DfxDumpCatcher dumplog;
511     std::string msg = "";
512     bool ret = dumplog.DumpCatchFd(getpid(), -1, msg, 1);
513     GTEST_LOG_(INFO) << ret;
514     EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest020 Failed";
515     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest020: end.";
516 }
517 
518 
519 /**
520  * @tc.name: DumpCatcherInterfacesTest021
521  * @tc.desc: test DumpCatchFd API: PID(accountmgr), TID(0)
522  * @tc.type: FUNC
523  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest021, TestSize.Level2)524 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest021, TestSize.Level2)
525 {
526     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest021: start.";
527     std::string apply = "accountmgr";
528     int applyPid = GetProcessPid(apply);
529     GTEST_LOG_(INFO) << "apply:" << apply << ", pid:" << applyPid;
530     DfxDumpCatcher dumplog;
531     std::string msg = "";
532     bool ret = dumplog.DumpCatchFd(applyPid, 0, msg, 1);
533     GTEST_LOG_(INFO) << ret;
534     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest021 Failed";
535     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest021: end.";
536 }
537 
538 /**
539  * @tc.name: DumpCatcherInterfacesTest022
540  * @tc.desc: test DumpCatchFd API: PID(accountmgr), TID(accountmgr main thread)
541  * @tc.type: FUNC
542  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest022, TestSize.Level2)543 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest022, TestSize.Level2)
544 {
545     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest022: start.";
546     std::string apply = "accountmgr";
547     int applyPid = GetProcessPid(apply);
548     GTEST_LOG_(INFO) << "apply:" << apply << ", pid:" << applyPid;
549     DfxDumpCatcher dumplog;
550     std::string msg = "";
551     bool ret = dumplog.DumpCatchFd(applyPid, applyPid, msg, 1);
552     GTEST_LOG_(INFO) << ret;
553     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest022 Failed";
554     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest022: end.";
555 }
556 
557 /**
558  * @tc.name: DumpCatcherInterfacesTest023
559  * @tc.desc: test DumpCatchFd API: PID(accountmgr), TID(-1)
560  * @tc.type: FUNC
561  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest023, TestSize.Level2)562 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest023, TestSize.Level2)
563 {
564     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest023: start.";
565     std::string apply = "accountmgr";
566     int applyPid = GetProcessPid(apply);
567     GTEST_LOG_(INFO) << "apply:" << apply << ", pid:" << applyPid;
568     DfxDumpCatcher dumplog;
569     std::string msg = "";
570     bool ret = dumplog.DumpCatchFd(applyPid, -1, msg, 1);
571     GTEST_LOG_(INFO) << ret;
572     EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest023 Failed";
573     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest023: end.";
574 }
575 
576 /**
577  * @tc.name: DumpCatcherInterfacesTest024
578  * @tc.desc: test DumpCatchFd API: PID(accountmgr), TID(9999)
579  * @tc.type: FUNC
580  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest024, TestSize.Level2)581 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest024, TestSize.Level2)
582 {
583     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest024: start.";
584     std::string apply = "accountmgr";
585     int applyPid = GetProcessPid(apply);
586     GTEST_LOG_(INFO) << "apply:" << apply << ", pid:" << applyPid;
587     DfxDumpCatcher dumplog;
588     std::string msg = "";
589     bool ret = dumplog.DumpCatchFd(applyPid, 9999, msg, 1);
590     GTEST_LOG_(INFO) << ret;
591     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest024 Failed";
592     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest024: end.";
593 }
594 
595 /**
596  * @tc.name: DumpCatcherInterfacesTest025
597  * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(9999)
598  * @tc.type: FUNC
599  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest025, TestSize.Level2)600 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest025, TestSize.Level2)
601 {
602     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest025: start.";
603     DfxDumpCatcher dumplog;
604     std::string msg = "";
605     bool ret = dumplog.DumpCatchFd(getpid(), 9999, msg, 1);
606     GTEST_LOG_(INFO) << ret;
607     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest025 Failed";
608     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest025: end.";
609 }
610 
611 /**
612  * @tc.name: DumpCatcherInterfacesTest026
613  * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(child thread)
614  * @tc.type: FUNC
615  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest026, TestSize.Level2)616 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest026, TestSize.Level2)
617 {
618     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest026: start.";
619     MultiThreadConstructor();
620     DfxDumpCatcher dumplog;
621     std::string msg = "";
622     GTEST_LOG_(INFO) << "dump local process, "  << " tid:" << g_threadId;
623     bool ret = dumplog.DumpCatchFd(getpid(), g_threadId, msg, 1);
624     GTEST_LOG_(INFO) << ret;
625     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest026 Failed";
626     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest026: end.";
627 }
628 
629 /**
630  * @tc.name: DumpCatcherInterfacesTest027
631  * @tc.desc: test DumpCatchFd API: PID(child process), TID(child thread of child process)
632  * @tc.type: FUNC
633  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest027, TestSize.Level2)634 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest027, TestSize.Level2)
635 {
636     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest027: start.";
637     ForkMultiThreadProcess();
638     std::vector<int> tids;
639     std::vector<int> nstids;
640     bool isSuccess = GetTidsByPid(g_processId, tids, nstids);
641     if (!isSuccess) {
642         ASSERT_FALSE(isSuccess);
643         return;
644     }
645     int childTid = tids[1]; // 1 : child thread
646     GTEST_LOG_(INFO) << "dump remote process, "  << " pid:" << g_processId << ", tid:" << childTid;
647     DfxDumpCatcher dumplog;
648     std::string msg = "";
649     bool ret = dumplog.DumpCatchFd(g_processId, childTid, msg, 1);
650     GTEST_LOG_(INFO) << ret;
651     EXPECT_TRUE(ret) << "DumpCatcherInterfacesTest027 Failed";
652     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest027: end.";
653 }
654 
655 /**
656  * @tc.name: DumpCatcherInterfacesTest028
657  * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(child thread) and config FrameNum
658  * @tc.type: FUNC
659  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest028, TestSize.Level2)660 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest028, TestSize.Level2)
661 {
662     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest028: start.";
663     RecursiveMultiThreadConstructor();
664     DfxDumpCatcher dumplog;
665     std::string msg = "";
666     GTEST_LOG_(INFO) << "dump local process, "  << " tid:" << g_threadId;
667     bool ret = dumplog.DumpCatchFd(getpid(), g_threadId, msg, 1, 10); // 10 means backtrace frames is 10
668     GTEST_LOG_(INFO) << "message:"  << msg;
669     GTEST_LOG_(INFO) << ret;
670     EXPECT_TRUE(msg.find("#09") != std::string::npos);
671     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest028 Failed";
672     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest028: end.";
673 }
674 
675 /**
676  * @tc.name: DumpCatcherInterfacesTest029
677  * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(child thread) and DEFAULT_MAX_FRAME_NUM
678  * @tc.type: FUNC
679  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest029, TestSize.Level2)680 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest029, TestSize.Level2)
681 {
682     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest029: start.";
683     RecursiveMultiThreadConstructor();
684     usleep(CREATE_THREAD_TIMEOUT);
685     DfxDumpCatcher dumplog;
686     std::string msg = "";
687     GTEST_LOG_(INFO) << "dump local process, "  << " tid:" << g_threadId;
688     bool ret = dumplog.DumpCatchFd(getpid(), g_threadId, msg, 1);
689     GTEST_LOG_(INFO) << "message:"  << msg;
690     GTEST_LOG_(INFO) << ret;
691 #if defined(__aarch64__)
692     std::string stackKeyword = std::string("#") + std::to_string(DEFAULT_MAX_LOCAL_FRAME_NUM - 1);
693 #else
694     std::string stackKeyword = std::string("#") + std::to_string(DEFAULT_MAX_FRAME_NUM - 1);
695 #endif
696     GTEST_LOG_(INFO) << "stackKeyword:"  << stackKeyword;
697     EXPECT_TRUE(msg.find(stackKeyword.c_str()) != std::string::npos);
698     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest029 Failed";
699     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest029: end.";
700 }
701 
702 #ifndef is_ohos_lite
703 /**
704  * @tc.name: DumpCatcherInterfacesTest030
705  * @tc.desc: test DumpCatch remote API: PID(getpid()), TID(child thread)
706  *     and maxFrameNums(DEFAULT_MAX_FRAME_NUM), isJson(true)
707  * @tc.type: FUNC
708  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest030, TestSize.Level2)709 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest030, TestSize.Level2)
710 {
711     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest030: start.";
712     pid_t pid = fork();
713     if (pid == 0) {
714         std::this_thread::sleep_for(std::chrono::seconds(10));
715         _exit(0);
716     }
717     GTEST_LOG_(INFO) << "dump remote process, "  << " pid:" << pid << ", tid:" << 0;
718     DfxDumpCatcher dumplog;
719     DfxJsonFormatter format;
720     string msg = "";
721     bool ret = dumplog.DumpCatch(pid, 0, msg);
722     EXPECT_TRUE(ret) << "DumpCatch remote msg Failed.";
723     string jsonMsg = "";
724     bool jsonRet = dumplog.DumpCatch(pid, 0, jsonMsg, DEFAULT_MAX_FRAME_NUM, true);
725     std::cout << jsonMsg << std::endl;
726     EXPECT_TRUE(jsonRet) << "DumpCatch remote json Failed.";
727     string stackMsg = "";
728     bool formatRet = format.FormatJsonStack(jsonMsg, stackMsg);
729     EXPECT_TRUE(formatRet) << "FormatJsonStack Failed.";
730     size_t pos = msg.find("Process name:");
731     if (pos != std::string::npos) {
732         msg = msg.erase(0, pos);
733         msg = msg.erase(0, msg.find("\n") + 1);
734     } else {
735         msg = msg.erase(0, msg.find("\n") + 1);
736     }
737     EXPECT_EQ(stackMsg == msg, true) << "stackMsg != msg";
738     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest030: end.";
739 }
740 
741 /**
742  * @tc.name: DumpCatcherInterfacesTest031
743  * @tc.desc: test DumpCatchProcess
744  * @tc.type: FUNC
745  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest031, TestSize.Level2)746 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest031, TestSize.Level2)
747 {
748     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest031: start.";
749     std::string res = ExecuteCommands("uname");
750     bool isSuccess = res.find("Linux") == std::string::npos;
751     if (!isSuccess) {
752         ASSERT_FALSE(isSuccess);
753         return;
754     }
755     isSuccess = g_testPid != 0;
756     if (!isSuccess) {
757         ASSERT_FALSE(isSuccess);
758         GTEST_LOG_(ERROR) << "Failed to launch target hap.";
759         return;
760     }
761     isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
762     if (!isSuccess) {
763         ASSERT_FALSE(isSuccess);
764         GTEST_LOG_(ERROR) << "Error process comm";
765         return;
766     }
767     std::string stopProcessCmd = "kill -s SIGSTOP $(pidof com.example.myapplication)";
768     ExecuteCommands(stopProcessCmd);
769     DfxDumpCatcher dumplog;
770     std::string msg = "";
771     ASSERT_EQ(dumplog.DumpCatchProcess(g_testPid, msg), 1); //kernel stack
772     GTEST_LOG_(INFO) << msg;
773     std::string formattedStack = "";
774     ASSERT_TRUE(DfxJsonFormatter::FormatKernelStack(msg, formattedStack, false));
775     ASSERT_GT(formattedStack.size(), 0);
776     GTEST_LOG_(INFO) << formattedStack;
777     ASSERT_NE(formattedStack.find("#"), std::string::npos);
778     ASSERT_TRUE(DfxJsonFormatter::FormatKernelStack(msg, formattedStack, true));
779     GTEST_LOG_(INFO) << formattedStack;
780     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest031: end.";
781 }
782 #endif
783 
784 #ifndef is_ohos_lite
785 /**
786  * @tc.name: DumpCatcherInterfacesTest032
787  * @tc.desc: test DfxJsonFormatter
788  * @tc.type: FUNC
789  */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest032, TestSize.Level2)790 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest032, TestSize.Level2)
791 {
792     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest032: start.";
793     DfxJsonFormatter format;
794     string outStackStr = "";
795     string errorJsonMsg = "{\"test\"}";
796     bool formatRet = format.FormatJsonStack(errorJsonMsg, outStackStr);
797     EXPECT_FALSE(formatRet);
798 
799     outStackStr = "";
800     string noThreadJsonMsg = "[{\"tid\" : \"1\"}]";
801     formatRet = format.FormatJsonStack(noThreadJsonMsg, outStackStr);
802     EXPECT_TRUE(formatRet);
803 
804     outStackStr = "";
805     string noTidJsonMsg = "[{\"thread_name\" : \"test\"}]";
806     formatRet = format.FormatJsonStack(noTidJsonMsg, outStackStr);
807     EXPECT_TRUE(formatRet);
808 
809     outStackStr = "";
810     string jsJsonMsg = R"~([{"frames":[{"buildId":"", "file":"/system/lib/ld-musl-arm.so.1",
811         "offset":0, "pc":"000fdf4c", "symbol":""}, {"line":"1", "file":"/system/lib/ld-musl-arm.so.1",
812         "offset":628, "pc":"000ff7f4", "symbol":"__pthread_cond_timedwait_time64"}],
813         "thread_name":"OS_SignalHandle", "tid":1608}])~";
814     formatRet = format.FormatJsonStack(jsJsonMsg, outStackStr);
815     EXPECT_TRUE(formatRet);
816     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest032: end.";
817 }
818 #endif
819 
820 /**
821 @tc.name: DumpCatcherInterfacesTest033
822 @tc.desc: testDump after crashed
823 @tc.type: FUNC
824 */
HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest033, TestSize.Level2)825 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest033, TestSize.Level2)
826 {
827     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest033: start.";
828     pid_t pid = fork();
829     if (pid == 0) {
830         int32_t fd = RequestFileDescriptor(FaultLoggerType::CPP_CRASH);
831         ASSERT_GT(fd, 0);
832         close(fd);
833         std::this_thread::sleep_for(std::chrono::seconds(10));
834         _exit(0);
835     } else if (pid < 0) {
836         GTEST_LOG_(INFO) << "Fail in fork.";
837     } else {
838         GTEST_LOG_(INFO) << "dump remote process, " << "pid:" << pid << ", tid:" << 0;
839         DfxDumpCatcher dumplog;
840         string msg = "";
841         EXPECT_FALSE(dumplog.DumpCatch(pid, 0, msg));
842         constexpr int validTime = 8;
843         sleep(validTime);
844         msg = "";
845         EXPECT_TRUE(dumplog.DumpCatch(pid, 0, msg));
846     }
847     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest033: end.";
848 }
849 } // namespace HiviewDFX
850 } // namepsace OHOS