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