• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 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 <filesystem>
19 #include <fstream>
20 #include <string>
21 #include <thread>
22 #include <vector>
23 
24 #include <unistd.h>
25 
26 #include "dfx_define.h"
27 #include "dfx_dump_catcher.h"
28 #include "dfx_json_formatter.h"
29 #include "dfx_test_util.h"
30 #include "dfx_util.h"
31 #include "faultloggerd_client.h"
32 #include "kernel_stack_async_collector.h"
33 #include "procinfo.h"
34 
35 using namespace testing;
36 using namespace testing::ext;
37 
38 namespace OHOS {
39 namespace HiviewDFX {
40 class DumpCatcherInterfacesTest : public testing::Test {
41 public:
42     static void SetUpTestCase();
43     static void TearDownTestCase();
44     void SetUp();
45     void TearDown();
46 };
47 
48 static const int THREAD_ALIVE_TIME = 2;
49 
50 static const int CREATE_THREAD_TIMEOUT = 300000;
51 
52 static pid_t g_threadId = 0;
53 
54 static pid_t g_processId = 0;
55 
56 int g_testPid = 0;
57 
SetUpTestCase()58 void DumpCatcherInterfacesTest::SetUpTestCase()
59 {
60     InstallTestHap("/data/FaultloggerdJsTest.hap");
61     std::string testBundleName = TEST_BUNDLE_NAME;
62     std::string testAbiltyName = testBundleName + ".MainAbility";
63     g_testPid = LaunchTestHap(testAbiltyName, testBundleName);
64 }
65 
TearDownTestCase()66 void DumpCatcherInterfacesTest::TearDownTestCase()
67 {
68     StopTestHap(TEST_BUNDLE_NAME);
69     UninstallTestHap(TEST_BUNDLE_NAME);
70 }
71 
SetUp()72 void DumpCatcherInterfacesTest::SetUp()
73 {}
74 
TearDown()75 void DumpCatcherInterfacesTest::TearDown()
76 {}
77 
TestFunRecursive(int recursiveCount)78 AT_OPT_NONE static void TestFunRecursive(int recursiveCount)
79 {
80     GTEST_LOG_(INFO) << "Enter TestFunRecursive recursiveCount:" << recursiveCount;
81     if (recursiveCount <= 0) {
82         GTEST_LOG_(INFO) << "start enter sleep" << gettid();
83         sleep(THREAD_ALIVE_TIME);
84         GTEST_LOG_(INFO) << "sleep end.";
85     } else {
86         TestFunRecursive(recursiveCount - 1);
87     }
88 }
89 
CreateRecursiveThread(void * argv)90 static void* CreateRecursiveThread(void *argv)
91 {
92     g_threadId = gettid();
93     GTEST_LOG_(INFO) << "create Recursive MultiThread " << gettid();
94     TestFunRecursive(266); // 266: set recursive count to 266, used for dumpcatcher get stack info
95     GTEST_LOG_(INFO) << "Recursive MultiThread thread sleep end.";
96     return nullptr;
97 }
98 
RecursiveMultiThreadConstructor(void)99 static int RecursiveMultiThreadConstructor(void)
100 {
101     pthread_t thread;
102     pthread_create(&thread, nullptr, CreateRecursiveThread, nullptr);
103     pthread_detach(thread);
104     usleep(CREATE_THREAD_TIMEOUT);
105     return 0;
106 }
107 
CreateThread(void * argv)108 static void* CreateThread(void *argv)
109 {
110     g_threadId = gettid();
111     GTEST_LOG_(INFO) << "create MultiThread " << gettid();
112     sleep(THREAD_ALIVE_TIME);
113     GTEST_LOG_(INFO) << "create MultiThread thread sleep end.";
114     return nullptr;
115 }
116 
MultiThreadConstructor(void)117 static int MultiThreadConstructor(void)
118 {
119     pthread_t thread;
120     pthread_create(&thread, nullptr, CreateThread, nullptr);
121     pthread_detach(thread);
122     usleep(CREATE_THREAD_TIMEOUT);
123     return 0;
124 }
125 
ForkMultiThreadProcess(void)126 static void ForkMultiThreadProcess(void)
127 {
128     int pid = fork();
129     if (pid == 0) {
130         MultiThreadConstructor();
131         _exit(0);
132     } else if (pid < 0) {
133         GTEST_LOG_(INFO) << "ForkMultiThreadProcess fail. ";
134     } else {
135         g_processId = pid;
136         GTEST_LOG_(INFO) << "ForkMultiThreadProcess success, pid: " << pid;
137     }
138 }
139 
140 /**
141  * @tc.name: DumpCatcherInterfacesTest001
142  * @tc.desc: test DumpCatch API: PID(test hap), TID(0)
143  * @tc.type: FUNC
144  */
145 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest001, TestSize.Level0)
146 {
147     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest001: start.";
148     bool isSuccess = g_testPid != 0;
149     if (!isSuccess) {
150         ASSERT_FALSE(isSuccess);
151         GTEST_LOG_(ERROR) << "Failed to launch target hap.";
152     } else {
153         isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
154         if (!isSuccess) {
155             ASSERT_FALSE(isSuccess);
156             GTEST_LOG_(ERROR) << "Error process comm";
157         } else {
158             DfxDumpCatcher dumplog;
159             std::string msg = "";
160             bool ret = dumplog.DumpCatch(g_testPid, 0, msg);
161             GTEST_LOG_(INFO) << ret;
162 #if defined(__aarch64__)
163             string log[] = { "Tid:", "Name:", "#00", "/system/bin/appspawn", "Name:OS_DfxWatchdog",
164                              "at jsFunc", "index_.js"};
165 #else
166             string log[] = { "Tid:", "Name:", "#00", "/system/bin/appspawn", "Name:OS_DfxWatchdog"};
167 #endif
168             log[0] += std::to_string(g_testPid);
169             log[1] += TRUNCATE_TEST_BUNDLE_NAME;
170             int len = sizeof(log) / sizeof(log[0]);
171             int count = GetKeywordsNum(msg, log, len);
172             EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest001 Failed";
173             GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest001: end.";
174         }
175     }
176 }
177 
178 /**
179  * @tc.name: DumpCatcherInterfacesTest002
180  * @tc.desc: test DumpCatchMultiPid API: multiPid{0, 0}
181  * @tc.type: FUNC
182  */
183 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest002, TestSize.Level2)
184 {
185     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest002: start.";
186     int testPid1 = 0;
187     GTEST_LOG_(INFO) << "testPid1:" << testPid1;
188     int testPid2 = 0;
189     GTEST_LOG_(INFO) << "testPid2:" << testPid2;
190     std::vector<int> multiPid {testPid1, testPid2};
191     DfxDumpCatcher dumplog;
192     std::string msg = "";
193     bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
194     GTEST_LOG_(INFO) << ret;
195     EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest002 Failed";
196     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest002: end.";
197 }
198 
199 /**
200  * @tc.name: DumpCatcherInterfacesTest003
201  * @tc.desc: test DumpCatchMultiPid API: multiPid{-11, -11}
202  * @tc.type: FUNC
203  */
204 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest003, TestSize.Level2)
205 {
206     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest003: start.";
207     int testPid1 = -11;
208     GTEST_LOG_(INFO) << "testPid1:" << testPid1;
209     int testPid2 = -11;
210     GTEST_LOG_(INFO) << "testPid2:" << testPid2;
211     std::vector<int> multiPid {testPid1, testPid2};
212     DfxDumpCatcher dumplog;
213     std::string msg = "";
214     bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
215     GTEST_LOG_(INFO) << ret;
216     EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest003 Failed";
217     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest003: end.";
218 }
219 
220 /**
221  * @tc.name: DumpCatcherInterfacesTest004
222  * @tc.desc: test DumpCatchMultiPid API: multiPid{PID(powermgr), 0}
223  * @tc.type: FUNC
224  */
225 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest004, TestSize.Level2)
226 {
227     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest004: start.";
228     std::string testProcess = "powermgr";
229     int applyPid1 = GetProcessPid(testProcess);
230     GTEST_LOG_(INFO) << "applyPid1:" << applyPid1;
231     int applyPid2 = 0;
232     GTEST_LOG_(INFO) << "applyPid2:" << applyPid2;
233     std::vector<int> multiPid {applyPid1, applyPid2};
234     DfxDumpCatcher dumplog;
235     std::string msg = "";
236     bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
237     GTEST_LOG_(INFO) << ret;
238     string log[] = { "Tid:", "Name:", "Failed" };
239     log[0] = log[0] + std::to_string(applyPid1);
240     log[1] = log[1] + "powermgr";
241     int len = sizeof(log) / sizeof(log[0]);
242     int count = GetKeywordsNum(msg, log, len);
243     EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest004 Failed";
244     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest004: end.";
245 }
246 
247 /**
248  * @tc.name: DumpCatcherInterfacesTest005
249  * @tc.desc: test DumpCatchMultiPid API: multiPid{PID(powermgr),PID(foundation),PID(systemui)}
250  * @tc.type: FUNC
251  */
252 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest005, TestSize.Level2)
253 {
254     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest005: start.";
255     std::vector<string> testProcessName = { "powermgr", "foundation", "com.ohos.systemui" };
256     string matchProcessName[] = { "powermgr", "foundation", "m.ohos.systemui" };
257     std::vector<int> multiPid;
258     std::vector<string> matchLog;
259     int index = 0;
260     for (string oneProcessName : testProcessName) {
261         int testPid = GetProcessPid(oneProcessName);
262         if (testPid == 0) {
263             GTEST_LOG_(INFO) << "process:" << oneProcessName << " pid is empty, skip";
264             index++;
265             continue;
266         }
267         multiPid.emplace_back(testPid);
268         matchLog.emplace_back("Tid:" + std::to_string(testPid));
269         matchLog.emplace_back("Name:" + matchProcessName[index]);
270         index++;
271     }
272 
273     // It is recommended that the number of effective pids be greater than 1,
274     // otherwise the testing purpose will not be achieved
275     EXPECT_GT(multiPid.size(), 1) << "DumpCatcherInterfacesTest005 Failed";
276 
277     DfxDumpCatcher dumplog;
278     std::string msg = "";
279     bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
280     GTEST_LOG_(INFO) << "ret:" << ret;
281 
282     int matchLogCount = matchLog.size();
283     auto matchLogArray = std::make_unique<string[]>(matchLogCount);
284     index = 0;
285     for (string info : matchLog) {
286         matchLogArray[index] = info;
287         index++;
288     }
289     int count = GetKeywordsNum(msg, matchLogArray.get(), matchLogCount);
290     EXPECT_EQ(count, matchLogCount) << msg << "DumpCatcherInterfacesTest005 Failed";
291     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest005: end.";
292 }
293 
294 /**
295  * @tc.name: DumpCatcherInterfacesTest006
296  * @tc.desc: test DumpCatchMultiPid API: multiPid{PID(powermgr), -11}
297  * @tc.type: FUNC
298  */
299 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest006, TestSize.Level2)
300 {
301     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest006: start.";
302     std::string testProcess = "powermgr";
303     int testPid1 = GetProcessPid(testProcess);
304     GTEST_LOG_(INFO) << "applyPid1:" << testPid1;
305     int testPid2 = -11;
306     GTEST_LOG_(INFO) << "applyPid2:" << testPid2;
307     std::vector<int> multiPid {testPid1, testPid2};
308     DfxDumpCatcher dumplog;
309     std::string msg = "";
310     bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
311     GTEST_LOG_(INFO) << ret;
312     string log[] = { "Tid:", "Name:", "Failed"};
313     log[0] = log[0] + std::to_string(testPid1);
314     log[1] = log[1] + "powermgr";
315     int len = sizeof(log) / sizeof(log[0]);
316     int count = GetKeywordsNum(msg, log, len);
317     EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest006 Failed";
318     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest006: end.";
319 }
320 
321 /**
322  * @tc.name: DumpCatcherInterfacesTest007
323  * @tc.desc: test DumpCatchMultiPid API: multiPid{9999, 9999}
324  * @tc.type: FUNC
325  */
326 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest007, TestSize.Level2)
327 {
328     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest007: start.";
329     int applyPid = 99999;
330     GTEST_LOG_(INFO) << "applyPid1:" << applyPid;
331     std::vector<int> multiPid {applyPid, applyPid};
332     DfxDumpCatcher dumplog;
333     std::string msg = "";
334     bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
335     GTEST_LOG_(INFO) << ret;
336     EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest007 Failed";
337     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest007: end.";
338 }
339 
340 /**
341  * @tc.name: DumpCatcherInterfacesTest008
342  * @tc.desc: test DumpCatchMultiPid API: multiPid{PID(powermgr), 9999}
343  * @tc.type: FUNC
344  */
345 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest008, TestSize.Level2)
346 {
347     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest008: start.";
348     std::string apply = "powermgr";
349     int applyPid1 = GetProcessPid(apply);
350     GTEST_LOG_(INFO) << "applyPid1:" << applyPid1;
351     int applyPid2 = 99999;
352     GTEST_LOG_(INFO) << "applyPid2:" << applyPid2;
353     std::vector<int> multiPid {applyPid1, applyPid2};
354     DfxDumpCatcher dumplog;
355     std::string msg = "";
356     bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
357     GTEST_LOG_(INFO) << ret;
358     string log[] = { "Tid:", "Name:", "Failed"};
359     log[0] = log[0] + std::to_string(applyPid1);
360     log[1] = log[1] + apply;
361     int len = sizeof(log) / sizeof(log[0]);
362     int count = GetKeywordsNum(msg, log, len);
363     EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest008 Failed";
364     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest008: end.";
365 }
366 
367 /**
368  * @tc.name: DumpCatcherInterfacesTest014
369  * @tc.desc: test DumpCatchMultiPid API: multiPid{PID(powermgr), PID(foundation)}
370  * @tc.type: FUNC
371  * @tc.require: issueI5PJ9O
372  */
373 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest014, TestSize.Level2)
374 {
375     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest014: start.";
376     std::string testProcess1 = "powermgr";
377     int testPid1 = GetProcessPid(testProcess1);
378     GTEST_LOG_(INFO) << "testPid1:" << testPid1;
379     std::string testProcess2 = "foundation";
380     int testPid2 = GetProcessPid(testProcess2);
381     GTEST_LOG_(INFO) << "testPid2:" << testPid2;
382     std::vector<int> multiPid {testPid1, testPid2};
383     DfxDumpCatcher dumplog;
384     std::string msg = "";
385     bool ret = dumplog.DumpCatchMultiPid(multiPid, msg);
386     GTEST_LOG_(INFO) << ret;
387     string log[] = {"Tid:", "Name:", "Tid:", "Name:"};
388     log[0] = log[0] + std::to_string(testPid1);
389     log[1] = log[1] + testProcess1;
390     log[2] = log[2] + std::to_string(testPid2);
391     log[3] = log[3] + testProcess2;
392     int len = sizeof(log) / sizeof(log[0]);
393     int count = GetKeywordsNum(msg, log, len);
394     EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest014 Failed";
395     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest014: end.";
396 }
397 
398 /**
399  * @tc.name: DumpCatcherInterfacesTest015
400  * @tc.desc: test DumpCatch API: PID(test hap), TID(test hap main thread)
401  * @tc.type: FUNC
402  * @tc.require: issueI5PJ9O
403  */
404 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest015, TestSize.Level2)
405 {
406     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest015: start.";
407     bool isSuccess = g_testPid != 0;
408     if (!isSuccess) {
409         ASSERT_FALSE(isSuccess);
410         GTEST_LOG_(ERROR) << "Failed to launch target hap.";
411     } else {
412         isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
413         if (!isSuccess) {
414             ASSERT_FALSE(isSuccess);
415             GTEST_LOG_(ERROR) << "Error process comm";
416         } else {
417             DfxDumpCatcher dumplog;
418             std::string msg = "";
419             bool ret = dumplog.DumpCatch(g_testPid, g_testPid, msg);
420             GTEST_LOG_(INFO) << ret;
421             string log[] = { "Tid:", "Name:", "#00", "/system/bin/appspawn"};
422             log[0] += std::to_string(g_testPid);
423             log[1] += TRUNCATE_TEST_BUNDLE_NAME;
424             int len = sizeof(log) / sizeof(log[0]);
425             int count = GetKeywordsNum(msg, log, len);
426             GTEST_LOG_(INFO) << msg;
427             EXPECT_EQ(count, len) << msg << "DumpCatcherInterfacesTest015 Failed";
428             GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest015: end.";
429         }
430     }
431 }
432 
433 /**
434  * @tc.name: DumpCatcherInterfacesTest016
435  * @tc.desc: test DumpCatch API: PID(test hap), TID(-1)
436  * @tc.type: FUNC
437  * @tc.require: issueI5PJ9O
438  */
439 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest016, TestSize.Level2)
440 {
441     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest016: start.";
442     bool isSuccess = g_testPid != 0;
443     if (!isSuccess) {
444         ASSERT_FALSE(isSuccess);
445         GTEST_LOG_(ERROR) << "Failed to launch target hap.";
446     } else {
447         isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
448         if (!isSuccess) {
449             ASSERT_FALSE(isSuccess);
450             GTEST_LOG_(ERROR) << "Error process comm";
451         } else {
452             DfxDumpCatcher dumplog;
453             std::string msg = "";
454             bool ret = dumplog.DumpCatch(g_testPid, -1, msg);
455             GTEST_LOG_(INFO) << ret;
456             EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest016 Failed";
457             GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest016: end.";
458         }
459     }
460 }
461 
462 /**
463  * @tc.name: DumpCatcherInterfacesTest017
464  * @tc.desc: test DumpCatch API: PID(-1), TID(-1)
465  * @tc.type: FUNC
466  * @tc.require: issueI5PJ9O
467  */
468 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest017, TestSize.Level2)
469 {
470     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest017: start.";
471     DfxDumpCatcher dumplog;
472     std::string msg = "";
473     bool ret = dumplog.DumpCatch(-1, -1, msg);
474     GTEST_LOG_(INFO) << ret;
475     EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest017 Failed";
476     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest017: end.";
477 }
478 
479 /**
480  * @tc.name: DumpCatcherInterfacesTest018
481  * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(gettid())
482  * @tc.type: FUNC
483  */
484 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest018, TestSize.Level2)
485 {
486     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest018: start.";
487     DfxDumpCatcher dumplog;
488     std::string msg = "";
489     bool ret = dumplog.DumpCatchFd(getpid(), gettid(), msg, 1);
490     GTEST_LOG_(INFO) << ret;
491     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest018 Failed";
492     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest018: end.";
493 }
494 
495 /**
496  * @tc.name: DumpCatcherInterfacesTest019
497  * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(0)
498  * @tc.type: FUNC
499  */
500 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest019, TestSize.Level2)
501 {
502     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest019: start.";
503     DfxDumpCatcher dumplog;
504     std::string msg = "";
505     bool ret = dumplog.DumpCatchFd(getpid(), 0, msg, 1);
506     GTEST_LOG_(INFO) << ret;
507     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest019 Failed";
508     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest019: end.";
509 }
510 
511 /**
512  * @tc.name: DumpCatcherInterfacesTest020
513  * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(-1)
514  * @tc.type: FUNC
515  */
516 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest020, TestSize.Level2)
517 {
518     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest020: start.";
519     DfxDumpCatcher dumplog;
520     std::string msg = "";
521     bool ret = dumplog.DumpCatchFd(getpid(), -1, msg, 1);
522     GTEST_LOG_(INFO) << ret;
523     EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest020 Failed";
524     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest020: end.";
525 }
526 
527 
528 /**
529  * @tc.name: DumpCatcherInterfacesTest021
530  * @tc.desc: test DumpCatchFd API: PID(powermgr), TID(0)
531  * @tc.type: FUNC
532  */
533 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest021, TestSize.Level2)
534 {
535     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest021: start.";
536     std::string apply = "powermgr";
537     int applyPid = GetProcessPid(apply);
538     GTEST_LOG_(INFO) << "apply:" << apply << ", pid:" << applyPid;
539     DfxDumpCatcher dumplog;
540     std::string msg = "";
541     bool ret = dumplog.DumpCatchFd(applyPid, 0, msg, 1);
542     GTEST_LOG_(INFO) << ret;
543     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest021 Failed";
544     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest021: end.";
545 }
546 
547 /**
548  * @tc.name: DumpCatcherInterfacesTest022
549  * @tc.desc: test DumpCatchFd API: PID(powermgr), TID(powermgr main thread)
550  * @tc.type: FUNC
551  */
552 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest022, TestSize.Level2)
553 {
554     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest022: start.";
555     std::string apply = "powermgr";
556     int applyPid = GetProcessPid(apply);
557     GTEST_LOG_(INFO) << "apply:" << apply << ", pid:" << applyPid;
558     DfxDumpCatcher dumplog;
559     std::string msg = "";
560     bool ret = dumplog.DumpCatchFd(applyPid, applyPid, msg, 1);
561     GTEST_LOG_(INFO) << ret;
562     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest022 Failed";
563     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest022: end.";
564 }
565 
566 /**
567  * @tc.name: DumpCatcherInterfacesTest023
568  * @tc.desc: test DumpCatchFd API: PID(powermgr), TID(-1)
569  * @tc.type: FUNC
570  */
571 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest023, TestSize.Level2)
572 {
573     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest023: start.";
574     std::string apply = "powermgr";
575     int applyPid = GetProcessPid(apply);
576     GTEST_LOG_(INFO) << "apply:" << apply << ", pid:" << applyPid;
577     DfxDumpCatcher dumplog;
578     std::string msg = "";
579     bool ret = dumplog.DumpCatchFd(applyPid, -1, msg, 1);
580     GTEST_LOG_(INFO) << ret;
581     EXPECT_EQ(ret, false) << "DumpCatcherInterfacesTest023 Failed";
582     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest023: end.";
583 }
584 
585 /**
586  * @tc.name: DumpCatcherInterfacesTest024
587  * @tc.desc: test DumpCatchFd API: PID(powermgr), TID(9999)
588  * @tc.type: FUNC
589  */
590 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest024, TestSize.Level2)
591 {
592     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest024: start.";
593     std::string apply = "powermgr";
594     int applyPid = GetProcessPid(apply);
595     GTEST_LOG_(INFO) << "apply:" << apply << ", pid:" << applyPid;
596     DfxDumpCatcher dumplog;
597     std::string msg = "";
598     bool ret = dumplog.DumpCatchFd(applyPid, 9999, msg, 1);
599     GTEST_LOG_(INFO) << ret;
600     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest024 Failed";
601     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest024: end.";
602 }
603 
604 /**
605  * @tc.name: DumpCatcherInterfacesTest025
606  * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(9999)
607  * @tc.type: FUNC
608  */
609 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest025, TestSize.Level2)
610 {
611     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest025: start.";
612     DfxDumpCatcher dumplog;
613     std::string msg = "";
614     bool ret = dumplog.DumpCatchFd(getpid(), 9999, msg, 1);
615     GTEST_LOG_(INFO) << ret;
616     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest025 Failed";
617     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest025: end.";
618 }
619 
620 /**
621  * @tc.name: DumpCatcherInterfacesTest026
622  * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(child thread)
623  * @tc.type: FUNC
624  */
625 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest026, TestSize.Level2)
626 {
627     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest026: start.";
628     MultiThreadConstructor();
629     DfxDumpCatcher dumplog;
630     std::string msg = "";
631     GTEST_LOG_(INFO) << "dump local process, "  << " tid:" << g_threadId;
632     bool ret = dumplog.DumpCatchFd(getpid(), g_threadId, msg, 1);
633     GTEST_LOG_(INFO) << ret;
634     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest026 Failed";
635     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest026: end.";
636 }
637 
638 /**
639  * @tc.name: DumpCatcherInterfacesTest027
640  * @tc.desc: test DumpCatchFd API: PID(child process), TID(child thread of child process)
641  * @tc.type: FUNC
642  */
643 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest027, TestSize.Level2)
644 {
645     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest027: start.";
646     ForkMultiThreadProcess();
647     std::vector<int> tids;
648     std::vector<int> nstids;
649     bool isSuccess = GetTidsByPid(g_processId, tids, nstids);
650     if (!isSuccess) {
651         ASSERT_FALSE(isSuccess);
652     } else {
653         int childTid = tids[1]; // 1 : child thread
654         GTEST_LOG_(INFO) << "dump remote process, "  << " pid:" << g_processId << ", tid:" << childTid;
655         DfxDumpCatcher dumplog;
656         std::string msg = "";
657         bool ret = dumplog.DumpCatchFd(g_processId, childTid, msg, 1);
658         GTEST_LOG_(INFO) << ret;
659         EXPECT_TRUE(ret) << "DumpCatcherInterfacesTest027 Failed";
660         GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest027: end.";
661     }
662 }
663 
664 /**
665  * @tc.name: DumpCatcherInterfacesTest028
666  * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(child thread) and config FrameNum
667  * @tc.type: FUNC
668  */
669 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest028, TestSize.Level2)
670 {
671     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest028: start.";
672     RecursiveMultiThreadConstructor();
673     DfxDumpCatcher dumplog;
674     std::string msg = "";
675     GTEST_LOG_(INFO) << "dump local process, "  << " tid:" << g_threadId;
676     bool ret = dumplog.DumpCatchFd(getpid(), g_threadId, msg, 1, 10); // 10 means backtrace frames is 10
677     GTEST_LOG_(INFO) << "message:"  << msg;
678     GTEST_LOG_(INFO) << ret;
679     EXPECT_TRUE(msg.find("#09") != std::string::npos);
680     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest028 Failed";
681     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest028: end.";
682 }
683 
684 /**
685  * @tc.name: DumpCatcherInterfacesTest029
686  * @tc.desc: test DumpCatchFd API: PID(getpid()), TID(child thread) and DEFAULT_MAX_FRAME_NUM
687  * @tc.type: FUNC
688  */
689 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest029, TestSize.Level2)
690 {
691     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest029: start.";
692     RecursiveMultiThreadConstructor();
693     usleep(CREATE_THREAD_TIMEOUT);
694     DfxDumpCatcher dumplog;
695     std::string msg = "";
696     GTEST_LOG_(INFO) << "dump local process, "  << " tid:" << g_threadId;
697     bool ret = dumplog.DumpCatchFd(getpid(), g_threadId, msg, 1);
698     GTEST_LOG_(INFO) << "message:"  << msg;
699     GTEST_LOG_(INFO) << ret;
700 #if (defined(__aarch64__) || defined(__loongarch_lp64))
701     std::string stackKeyword = std::string("#") + std::to_string(DEFAULT_MAX_LOCAL_FRAME_NUM - 1);
702 #else
703     std::string stackKeyword = std::string("#") + std::to_string(DEFAULT_MAX_FRAME_NUM - 1);
704 #endif
705     GTEST_LOG_(INFO) << "stackKeyword:"  << stackKeyword;
706     EXPECT_TRUE(msg.find(stackKeyword.c_str()) != std::string::npos);
707     EXPECT_EQ(ret, true) << "DumpCatcherInterfacesTest029 Failed";
708     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest029: end.";
709 }
710 
711 #ifndef is_ohos_lite
712 /**
713  * @tc.name: DumpCatcherInterfacesTest030
714  * @tc.desc: test DumpCatch remote API: PID(getpid()), TID(child thread)
715  *     and maxFrameNums(DEFAULT_MAX_FRAME_NUM), isJson(true)
716  * @tc.type: FUNC
717  */
718 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest030, TestSize.Level2)
719 {
720     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest030: start.";
721     int fd[2];
722     EXPECT_TRUE(CreatePipeFd(fd));
723     pid_t pid = fork();
724     if (pid == 0) {
725         NotifyProcStart(fd);
726         std::this_thread::sleep_for(std::chrono::seconds(10));
727         _exit(0);
728     }
729     WaitProcStart(fd);
730     GTEST_LOG_(INFO) << "dump remote process, "  << " pid:" << pid << ", tid:" << 0;
731     DfxDumpCatcher dumplog;
732     DfxJsonFormatter format;
733     string msg = "";
734     bool ret = dumplog.DumpCatch(pid, 0, msg);
735     EXPECT_TRUE(ret) << "DumpCatch remote msg Failed.";
736     string jsonMsg = "";
737     bool jsonRet = dumplog.DumpCatch(pid, 0, jsonMsg, DEFAULT_MAX_FRAME_NUM, true);
738     std::cout << jsonMsg << std::endl;
739     EXPECT_TRUE(jsonRet) << "DumpCatch remote json Failed.";
740     string stackMsg = "";
741     bool formatRet = format.FormatJsonStack(jsonMsg, stackMsg);
742     EXPECT_TRUE(formatRet) << "FormatJsonStack Failed.";
743     size_t pos = msg.find("Process name:");
744     if (pos != std::string::npos) {
745         msg = msg.erase(0, pos);
746         msg = msg.erase(0, msg.find("\n") + 1);
747     } else {
748         msg = msg.erase(0, msg.find("\n") + 1);
749     }
750     EXPECT_EQ(stackMsg == msg, true) << "stackMsg: " << stackMsg << "msg: " << msg << "stackMsg != msg";
751     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest030: end.";
752 }
753 #endif
754 
755 #ifndef is_ohos_lite
756 /**
757  * @tc.name: DumpCatcherInterfacesTest032
758  * @tc.desc: test DfxJsonFormatter
759  * @tc.type: FUNC
760  */
761 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest032, TestSize.Level2)
762 {
763     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest032: start.";
764     DfxJsonFormatter format;
765     string outStackStr = "";
766     string errorJsonMsg = "{\"test\"}";
767     bool formatRet = format.FormatJsonStack(errorJsonMsg, outStackStr);
768     EXPECT_FALSE(formatRet);
769 
770     outStackStr = "";
771     string noThreadJsonMsg = "[{\"tid\" : \"1\"}]";
772     formatRet = format.FormatJsonStack(noThreadJsonMsg, outStackStr);
773     EXPECT_TRUE(formatRet);
774 
775     outStackStr = "";
776     string noTidJsonMsg = "[{\"thread_name\" : \"test\"}]";
777     formatRet = format.FormatJsonStack(noTidJsonMsg, outStackStr);
778     EXPECT_TRUE(formatRet);
779 
780     outStackStr = "";
781     string jsJsonMsg = R"~([{"frames":[{"buildId":"", "file":"/system/lib/ld-musl-arm.so.1",
782         "offset":0, "pc":"000fdf4c", "symbol":""}, {"line":"1", "file":"/system/lib/ld-musl-arm.so.1",
783         "offset":628, "pc":"000ff7f4", "symbol":"__pthread_cond_timedwait_time64"}],
784         "thread_name":"OS_SignalHandle", "tid":1608}])~";
785     formatRet = format.FormatJsonStack(jsJsonMsg, outStackStr);
786     EXPECT_TRUE(formatRet);
787     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest032: end.";
788 }
789 #endif
790 
791 /**
792 @tc.name: DumpCatcherInterfacesTest033
793 @tc.desc: testDump after crashed
794 @tc.type: FUNC
795 */
796 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest033, TestSize.Level2)
797 {
798     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest033: start.";
799     int32_t fd = RequestFileDescriptor(FaultLoggerType::CPP_CRASH);
800     ASSERT_GT(fd, 0);
801     close(fd);
802     pid_t pid = fork();
803     if (pid == 0) {
804         GTEST_LOG_(INFO) << "dump remote process, " << "pid:" << getppid() << ", tid:" << 0;
805         DfxDumpCatcher dumplog;
806         string msg = "";
807         EXPECT_FALSE(dumplog.DumpCatch(getppid(), 0, msg));
808         constexpr int validTime = 1;
809         sleep(validTime);
810         msg = "";
811         EXPECT_TRUE(dumplog.DumpCatch(getppid(), 0, msg));
812         CheckAndExit(HasFailure());
813     } else if (pid < 0) {
814         GTEST_LOG_(INFO) << "Fail in fork.";
815     } else {
816         int status;
817         wait(&status);
818         ASSERT_EQ(status, 0);
819     }
820     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest033: end.";
821 }
822 
823 /**
824  * @tc.name: DumpCatcherInterfacesTest035
825  * @tc.desc: test DumpCatchWithTimeout API: PID(test hap)
826  * @tc.type: FUNC
827  * @tc.require: IB1XY4
828  */
829 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest035, TestSize.Level2)
830 {
831     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest035: start.";
832     bool isSuccess = g_testPid != 0;
833     if (!isSuccess) {
834         ASSERT_FALSE(isSuccess);
835         GTEST_LOG_(ERROR) << "Failed to launch target hap.";
836     } else {
837         isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
838         if (!isSuccess) {
839             ASSERT_FALSE(isSuccess);
840             GTEST_LOG_(ERROR) << "Error process comm";
841         } else {
842             DfxDumpCatcher dumplog;
843             std::string msg = "";
844             auto result = dumplog.DumpCatchWithTimeout(g_testPid, msg);
845             GTEST_LOG_(INFO) << result.second;
846             EXPECT_TRUE(result.first == 0) << "DumpCatcherInterfacesTest035 Failed";
847             string log[] = { "Tid:", "Name:", "#00", "/system/bin/appspawn", "Name:OS_DfxWatchdog" };
848             log[0] += std::to_string(g_testPid);
849             log[1] += TRUNCATE_TEST_BUNDLE_NAME;
850             int len = sizeof(log) / sizeof(log[0]);
851             int count = GetKeywordsNum(msg, log, len);
852             EXPECT_EQ(count, len) << "DumpCatcherInterfacesTest035 Failed";
853             GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest035: end.";
854         }
855     }
856 }
857 
858 /**
859  * @tc.name: DumpCatcherInterfacesTest036
860  * @tc.desc: test DumpCatchWithTimeout API: PID(test hap), TIMEOUT(1000)
861  * @tc.type: FUNC
862  * @tc.require: IB1XY4
863  */
864 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest036, TestSize.Level2)
865 {
866     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest036: start.";
867     bool isSuccess = g_testPid != 0;
868     if (!isSuccess) {
869         ASSERT_FALSE(isSuccess);
870         GTEST_LOG_(ERROR) << "Failed to launch target hap.";
871     } else {
872         isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
873         if (!isSuccess) {
874             ASSERT_FALSE(isSuccess);
875             GTEST_LOG_(ERROR) << "Error process comm";
876         } else {
877             DfxDumpCatcher dumplog;
878             std::string msg = "";
879             int timeout = 1000;
880             auto result = dumplog.DumpCatchWithTimeout(g_testPid, msg, timeout);
881             GTEST_LOG_(INFO) << result.second;
882             EXPECT_TRUE(result.first == -1) << "DumpCatcherInterfacesTest036 Failed";
883             GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest036: end.";
884         }
885     }
886 }
887 
888 /**
889  * @tc.name: DumpCatcherInterfacesTest037
890  * @tc.desc: test DumpCatchWithTimeout API: PID(nonexistent)
891  * @tc.type: FUNC
892  * @tc.require: IB1XY4
893  */
894 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest037, TestSize.Level2)
895 {
896     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest037: start.";
897     bool isSuccess = g_testPid != 0;
898     if (!isSuccess) {
899         ASSERT_FALSE(isSuccess);
900         GTEST_LOG_(ERROR) << "Failed to launch target hap.";
901     } else {
902         isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
903         if (!isSuccess) {
904             ASSERT_FALSE(isSuccess);
905             GTEST_LOG_(ERROR) << "Error process comm";
906         } else {
907             DfxDumpCatcher dumplog;
908             std::string msg = "";
909             int nonexistPid = 123456;
910             auto result = dumplog.DumpCatchWithTimeout(nonexistPid, msg);
911             GTEST_LOG_(INFO) << result.second;
912             EXPECT_TRUE(result.first == -1) << "DumpCatcherInterfacesTest037 Failed";
913             GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest037: end.";
914         }
915     }
916 }
917 
918 /**
919  * @tc.name: DumpCatcherInterfacesTest038
920  * @tc.desc: test DumpCatchWithTimeout API: PID(test hap), TIMEOUT(2000)
921  * @tc.type: FUNC
922  * @tc.require: IB1XY4
923  */
924 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest038, TestSize.Level2)
925 {
926     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest038: start.";
927     bool isSuccess = g_testPid != 0;
928     if (!isSuccess) {
929         ASSERT_FALSE(isSuccess);
930         GTEST_LOG_(ERROR) << "Failed to launch target hap.";
931     } else {
932         isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
933         if (!isSuccess) {
934             ASSERT_FALSE(isSuccess);
935             GTEST_LOG_(ERROR) << "Error process comm";
936         } else {
937             DfxDumpCatcher dumplog;
938             std::string msg = "";
939             int timeout = 2000;
940             auto result = dumplog.DumpCatchWithTimeout(g_testPid, msg, timeout);
941             GTEST_LOG_(INFO) << result.second;
942             EXPECT_TRUE(result.first == 0) << "DumpCatcherInterfacesTest038 Failed";
943             string log[] = { "Tid:", "Name:", "#00", "/system/bin/appspawn", "Name:OS_DfxWatchdog" };
944             log[0] += std::to_string(g_testPid);
945             log[1] += TRUNCATE_TEST_BUNDLE_NAME;
946             int len = sizeof(log) / sizeof(log[0]);
947             int count = GetKeywordsNum(msg, log, len);
948             EXPECT_EQ(count, len) << "DumpCatcherInterfacesTest038 Failed";
949             GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest038: end.";
950         }
951     }
952 }
953 
954 /**
955  * @tc.name: DumpCatcherInterfacesTest039
956  * @tc.desc: test DumpCatchWithTimeout API: PID(test hap) and SIGSTOP the process
957  * @tc.type: FUNC
958  * @tc.require: IB1XY4
959  */
960 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest039, TestSize.Level2)
961 {
962     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest039: start.";
963     std::string res = ExecuteCommands("uname");
964     bool isSuccess = res.find("Linux") == std::string::npos;
965     if (!isSuccess) {
966         ASSERT_FALSE(isSuccess);
967     } else {
968         isSuccess = g_testPid != 0;
969         if (!isSuccess) {
970             ASSERT_FALSE(isSuccess);
971             GTEST_LOG_(ERROR) << "Failed to launch target hap.";
972         } else {
973             isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
974             if (!isSuccess) {
975                 ASSERT_FALSE(isSuccess);
976                 GTEST_LOG_(ERROR) << "Error process comm";
977             } else {
978                 std::string stopProcessCmd = "kill -s SIGSTOP $(pidof com.example.myapplication)";
979                 ExecuteCommands(stopProcessCmd);
980                 DfxDumpCatcher dumplog;
981                 std::string msg = "";
982                 auto result = dumplog.DumpCatchWithTimeout(g_testPid, msg);
983                 std::string startProcessCmd = "kill -s SIGCONT $(pidof com.example.myapplication)";
984                 ExecuteCommands(startProcessCmd);
985                 GTEST_LOG_(INFO) << result.second;
986                 ASSERT_TRUE(result.first == 1);
987                 GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest039: end.";
988             }
989         }
990     }
991 }
992 
993 /**
994  * @tc.name: DumpCatcherInterfacesTest040
995  * @tc.desc: test DumpCatchWithTimeout API: PID(test hap) and stop the faultloggerd
996  * @tc.type: FUNC
997  * @tc.require: IB1XY4
998  */
999 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest040, TestSize.Level2)
1000 {
1001     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest040: start.";
1002     std::string res = ExecuteCommands("uname");
1003     bool isSuccess = res.find("Linux") == std::string::npos;
1004     if (!isSuccess) {
1005         ASSERT_FALSE(isSuccess);
1006     } else {
1007         isSuccess = g_testPid != 0;
1008         if (!isSuccess) {
1009             ASSERT_FALSE(isSuccess);
1010             GTEST_LOG_(ERROR) << "Failed to launch target hap.";
1011         } else {
1012             isSuccess = CheckProcessComm(g_testPid, TRUNCATE_TEST_BUNDLE_NAME);
1013             if (!isSuccess) {
1014                 ASSERT_FALSE(isSuccess);
1015                 GTEST_LOG_(ERROR) << "Error process comm";
1016             } else {
1017                 DfxDumpCatcher dumplog;
1018                 std::string msg = "";
1019                 std::string stopFaultloggerdCmd = "service_control stop faultloggerd";
1020                 ExecuteCommands(stopFaultloggerdCmd);
1021                 auto result = dumplog.DumpCatchWithTimeout(g_testPid, msg);
1022                 std::string startFaultloggerdCmd = "service_control start faultloggerd";
1023                 ExecuteCommands(startFaultloggerdCmd);
1024                 GTEST_LOG_(INFO) << result.second;
1025                 EXPECT_TRUE(result.first == -1);
1026                 std::this_thread::sleep_for(std::chrono::seconds(1));
1027                 GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest040: end.";
1028             }
1029         }
1030     }
1031 }
1032 
1033 /**
1034  * @tc.name: DumpCatcherInterfacesTest041
1035  * @tc.desc: test dumpcatch self scenario
1036  * @tc.type: FUNC
1037  */
1038 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest041, TestSize.Level2)
1039 {
1040     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest041: start.";
__anonaeaafe000102null1041     auto sleep = [] {
1042         std::this_thread::sleep_for(std::chrono::seconds(10));
1043     };
1044     for (int i = 0; i < 10; i++) {
1045         std::thread t(sleep);
1046         t.detach();
1047     }
1048     DfxDumpCatcher dump;
1049     std::string stack;
1050     bool result = dump.DumpCatch(getpid(), 0, stack);
1051     ASSERT_EQ(result, true);
1052 
1053     result = dump.DumpCatch(getpid(), getpid(), stack);
1054     ASSERT_EQ(result, true);
1055 
1056     std::vector<int> pids;
1057     result = dump.DumpCatchMultiPid(pids, stack);
1058     ASSERT_EQ(result, false);
1059     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest041: end.";
1060 }
1061 
1062 /**
1063  * @tc.name: DumpCatcherInterfacesTest042
1064  * @tc.desc: test dumpcatch FormatKernelStack
1065  * @tc.type: FUNC
1066  */
1067 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest042, TestSize.Level2)
1068 {
1069     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest042: start.";
1070     std::string msg = "";
1071     std::string formattedStack = "";
1072     ASSERT_FALSE(DfxJsonFormatter::FormatKernelStack(msg, formattedStack, false));
1073     ASSERT_FALSE(DfxJsonFormatter::FormatKernelStack(msg, formattedStack, true));
1074     msg = "Thread info: name=example_name, tid=12345, key=value., key2=value2., key3=value3., pid=0";
1075 #if defined(__aarch64__)
1076     ASSERT_TRUE(DfxJsonFormatter::FormatKernelStack(msg, formattedStack, false));
1077     ASSERT_TRUE(DfxJsonFormatter::FormatKernelStack(msg, formattedStack, true));
1078 #endif
1079     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest042: end.";
1080 }
1081 
1082 #if defined(__aarch64__)
IsPidDir(const std::filesystem::directory_entry & entry)1083 static bool IsPidDir(const std::filesystem::directory_entry& entry)
1084 {
1085     if (!entry.is_directory()) {
1086         return false;
1087     }
1088     const std::string fileName = entry.path().filename();
1089     return std::all_of(fileName.begin(), fileName.end(), [](char c) { return std::isdigit(c); });
1090 }
1091 
CheckProcessStart(const std::string & procName,pid_t & pid)1092 static bool CheckProcessStart(const std::string& procName, pid_t& pid)
1093 {
1094     for (const auto& entry : std::filesystem::directory_iterator("/proc")) {
1095         if (!IsPidDir(entry)) {
1096             continue;
1097         }
1098         std::ifstream commFile(entry.path() / "comm");
1099         if (!commFile) {
1100             continue;
1101         }
1102         std::string processName;
1103         if (std::getline(commFile, processName)) {
1104             processName.erase(processName.find_last_not_of("\n") + 1);
1105             if (processName == procName) {
1106                 pid = std::stoi(entry.path().filename());
1107                 return true;
1108             }
1109         }
1110     }
1111     return false;
1112 }
1113 
GetParentPid(int pid)1114 static int GetParentPid(int pid)
1115 {
1116     std::ifstream statFile("/proc/" + std::to_string(pid) + "/status");
1117     if (!statFile) {
1118         GTEST_LOG_(ERROR) << "GetParentPid: No process status file" << pid;
1119         return -1;
1120     }
1121 
1122     if (!statFile.is_open()) {
1123         GTEST_LOG_(ERROR) << "GetParentPid: open fail";
1124         return -1;
1125     }
1126 
1127     int ppid = -1;
1128     const size_t compareSize = 5;
1129     std::string line;
1130     while (std::getline(statFile, line)) {
1131         if (line.compare(0, compareSize, "PPid:") == 0) {
1132             std::istringstream iss(line.substr(compareSize));
1133             iss >> ppid;
1134             break;
1135         }
1136     }
1137     return ppid;
1138 }
1139 #endif
1140 
1141 /**
1142  * @tc.name: DumpCatcherInterfacesTest043
1143  * @tc.desc: test dumpcatch no parse symbol
1144  * @tc.type: FUNC
1145  */
1146 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest043, TestSize.Level2)
1147 {
1148     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest043: start.";
1149 #if defined(__aarch64__)
1150     pid_t pid = fork();
1151     if (pid < 0) {
1152         GTEST_LOG_(ERROR) << "DumpCatcherInterfacesTest043: fork fail";
1153     } else if (pid == 0) {
1154         std::this_thread::sleep_for(std::chrono::seconds(5)); // 5 : sleep 5s
1155         _exit(0);
1156     }
1157     const int checkCnt = 500; // 500 : check processdump start in 500ms
1158     const int waitForkPidStartTime = 50; // 50 : 50ms
1159     const int hungUpProcessdumpTime = 2880; // 2880 : 2.88s
1160     int timeStart = static_cast<int>(GetAbsTimeMilliSeconds());
1161     pid_t pidCheck = fork();
1162     if (pidCheck < 0) {
1163         GTEST_LOG_(ERROR) << "DumpCatcherInterfacesTest043: fork fail";
1164     } else if (pidCheck == 0) {
1165         for (int i = 0; i < checkCnt; i++) {
1166             std::this_thread::sleep_for(std::chrono::milliseconds(1));
1167             pid_t processdumpPid = 0;
1168             if (!CheckProcessStart("processdump", processdumpPid) ||
1169                 pid != GetParentPid(GetParentPid(processdumpPid))) {
1170                 continue;
1171             }
1172             GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest043: processdump " << processdumpPid << " has been forked";
1173             if (processdumpPid > 0) {
1174                 kill(processdumpPid, SIGSTOP);
1175                 int now = static_cast<int>(GetAbsTimeMilliSeconds());
1176                 int timeWait = hungUpProcessdumpTime - (now - timeStart - waitForkPidStartTime);
1177                 timeWait = timeWait > 0 ? timeWait : 0;
1178                 std::this_thread::sleep_for(std::chrono::milliseconds(timeWait));
1179                 kill(processdumpPid, SIGCONT);
1180             }
1181             break;
1182         }
1183         _exit(0);
1184     }
1185     DfxDumpCatcher dump;
1186     std::string stack;
1187     std::this_thread::sleep_for(std::chrono::milliseconds(waitForkPidStartTime));
1188     dump.DumpCatch(pid, 0, stack);
1189     GTEST_LOG_(INFO) << stack;
1190     kill(pid, SIGKILL);
1191     kill(pidCheck, SIGKILL);
1192     bool result = stack.find("no enough time to parse symbol") != std::string::npos;
1193     ASSERT_EQ(result, true);
1194 #endif
1195     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest043: end.";
1196 }
1197 
1198 /**
1199  * @tc.name: DumpCatcherInterfacesTest044
1200  * @tc.desc: test DumpCatchWithTimeout dump self
1201  * @tc.type: FUNC
1202  * @tc.require: ICAOEX
1203  */
1204 HWTEST_F(DumpCatcherInterfacesTest, DumpCatcherInterfacesTest044, TestSize.Level2)
1205 {
1206     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest044: start.";
1207     DfxDumpCatcher dumplog;
1208     std::string msg = "";
1209     int currentPid = getpid();
1210     auto result = dumplog.DumpCatchWithTimeout(currentPid, msg);
1211     GTEST_LOG_(INFO) << result.second;
1212     EXPECT_TRUE(result.first == 0);
1213     GTEST_LOG_(INFO) << "DumpCatcherInterfacesTest044: end.";
1214 }
1215 } // namespace HiviewDFX
1216 } // namepsace OHOS
1217