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