1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd. 3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License. 5800b99b8Sopenharmony_ci * You may obtain a copy of the License at 6800b99b8Sopenharmony_ci * 7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8800b99b8Sopenharmony_ci * 9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and 13800b99b8Sopenharmony_ci * limitations under the License. 14800b99b8Sopenharmony_ci */ 15800b99b8Sopenharmony_ci 16800b99b8Sopenharmony_ci#include <gtest/gtest.h> 17800b99b8Sopenharmony_ci 18800b99b8Sopenharmony_ci#include <cstdio> 19800b99b8Sopenharmony_ci#include <directory_ex.h> 20800b99b8Sopenharmony_ci#include <fcntl.h> 21800b99b8Sopenharmony_ci#include <malloc.h> 22800b99b8Sopenharmony_ci#include <string_ex.h> 23800b99b8Sopenharmony_ci#include <thread> 24800b99b8Sopenharmony_ci#include <unistd.h> 25800b99b8Sopenharmony_ci 26800b99b8Sopenharmony_ci#include "backtrace_local.h" 27800b99b8Sopenharmony_ci#include "dfx_test_util.h" 28800b99b8Sopenharmony_ci#include "file_util.h" 29800b99b8Sopenharmony_ci 30800b99b8Sopenharmony_ciusing namespace testing; 31800b99b8Sopenharmony_ciusing namespace testing::ext; 32800b99b8Sopenharmony_ci 33800b99b8Sopenharmony_cinamespace OHOS { 34800b99b8Sopenharmony_cinamespace HiviewDFX { 35800b99b8Sopenharmony_ci#undef LOG_DOMAIN 36800b99b8Sopenharmony_ci#undef LOG_TAG 37800b99b8Sopenharmony_ci#define LOG_TAG "DfxBacktraceUtilsTest" 38800b99b8Sopenharmony_ci#define LOG_DOMAIN 0xD002D11 39800b99b8Sopenharmony_ci 40800b99b8Sopenharmony_ci#define TEST_TEMP_FILE "/data/test/testfile" 41800b99b8Sopenharmony_ci/* 42800b99b8Sopenharmony_ciexpected output log should be like this(aarch64): 43800b99b8Sopenharmony_ci Backtrace: #01 pc 000000000000d2f8 /data/test/backtrace_utils_test 44800b99b8Sopenharmony_ci Backtrace: #02 pc 000000000000d164 /data/test/backtrace_utils_test 45800b99b8Sopenharmony_ci Backtrace: #03 pc 000000000000c86c /data/test/backtrace_utils_test 46800b99b8Sopenharmony_ci Backtrace: #04 pc 0000000000013f88 /data/test/backtrace_utils_test 47800b99b8Sopenharmony_ci Backtrace: #05 pc 00000000000148a4 /data/test/backtrace_utils_test 48800b99b8Sopenharmony_ci Backtrace: #06 pc 0000000000015140 /data/test/backtrace_utils_test 49800b99b8Sopenharmony_ci Backtrace: #07 pc 00000000000242d8 /data/test/backtrace_utils_test 50800b99b8Sopenharmony_ci Backtrace: #08 pc 0000000000023bd8 /data/test/backtrace_utils_test 51800b99b8Sopenharmony_ci Backtrace: #09 pc 000000000000df68 /data/test/backtrace_utils_test 52800b99b8Sopenharmony_ci Backtrace: #10 pc 00000000000dcf74 /system/lib/ld-musl-aarch64.so.1 53800b99b8Sopenharmony_ci Backtrace: #11 pc 000000000000c614 /data/test/backtrace_utils_test 54800b99b8Sopenharmony_ci*/ 55800b99b8Sopenharmony_ci 56800b99b8Sopenharmony_ciclass BacktraceUtilsTest : public testing::Test { 57800b99b8Sopenharmony_cipublic: 58800b99b8Sopenharmony_ci static void SetUpTestCase(); 59800b99b8Sopenharmony_ci static void TearDownTestCase(); 60800b99b8Sopenharmony_ci void SetUp(); 61800b99b8Sopenharmony_ci void TearDown(); 62800b99b8Sopenharmony_ci 63800b99b8Sopenharmony_ci uint32_t fdCount; 64800b99b8Sopenharmony_ci uint32_t mapsCount; 65800b99b8Sopenharmony_ci uint64_t memCount; 66800b99b8Sopenharmony_ci 67800b99b8Sopenharmony_ci static uint32_t fdCountTotal; 68800b99b8Sopenharmony_ci static uint32_t mapsCountTotal; 69800b99b8Sopenharmony_ci static uint64_t memCountTotal; 70800b99b8Sopenharmony_ci}; 71800b99b8Sopenharmony_ci 72800b99b8Sopenharmony_ciuint32_t BacktraceUtilsTest::fdCountTotal = 0; 73800b99b8Sopenharmony_ciuint32_t BacktraceUtilsTest::mapsCountTotal = 0; 74800b99b8Sopenharmony_ciuint64_t BacktraceUtilsTest::memCountTotal = 0; 75800b99b8Sopenharmony_ci 76800b99b8Sopenharmony_civoid BacktraceUtilsTest::SetUpTestCase() 77800b99b8Sopenharmony_ci{ 78800b99b8Sopenharmony_ci // get memory/fd/maps 79800b99b8Sopenharmony_ci BacktraceUtilsTest::fdCountTotal = GetSelfFdCount(); 80800b99b8Sopenharmony_ci BacktraceUtilsTest::mapsCountTotal = GetSelfMapsCount(); 81800b99b8Sopenharmony_ci BacktraceUtilsTest::memCountTotal = GetSelfMemoryCount(); 82800b99b8Sopenharmony_ci} 83800b99b8Sopenharmony_ci 84800b99b8Sopenharmony_civoid BacktraceUtilsTest::TearDownTestCase() 85800b99b8Sopenharmony_ci{ 86800b99b8Sopenharmony_ci // check memory/fd/maps 87800b99b8Sopenharmony_ci CheckResourceUsage(fdCountTotal, mapsCountTotal, memCountTotal); 88800b99b8Sopenharmony_ci} 89800b99b8Sopenharmony_ci 90800b99b8Sopenharmony_civoid BacktraceUtilsTest::SetUp() 91800b99b8Sopenharmony_ci{ 92800b99b8Sopenharmony_ci // get memory/fd/maps 93800b99b8Sopenharmony_ci fdCount = GetSelfFdCount(); 94800b99b8Sopenharmony_ci mapsCount = GetSelfMapsCount(); 95800b99b8Sopenharmony_ci memCount = GetSelfMemoryCount(); 96800b99b8Sopenharmony_ci} 97800b99b8Sopenharmony_ci 98800b99b8Sopenharmony_civoid BacktraceUtilsTest::TearDown() 99800b99b8Sopenharmony_ci{ 100800b99b8Sopenharmony_ci#ifdef USE_JEMALLOC_DFX_INTF 101800b99b8Sopenharmony_ci mallopt(M_FLUSH_THREAD_CACHE, 0); 102800b99b8Sopenharmony_ci#endif 103800b99b8Sopenharmony_ci // check memory/fd/maps 104800b99b8Sopenharmony_ci CheckResourceUsage(fdCount, mapsCount, memCount); 105800b99b8Sopenharmony_ci} 106800b99b8Sopenharmony_ci 107800b99b8Sopenharmony_cistatic bool CheckBacktraceContent(const std::string& content, bool fast = false) 108800b99b8Sopenharmony_ci{ 109800b99b8Sopenharmony_ci std::string existKeyWords[] = { "#09", "backtrace_utils_test", "system" }; 110800b99b8Sopenharmony_ci std::string notExistkeyWords[] = { 111800b99b8Sopenharmony_ci#if defined(__aarch64__) 112800b99b8Sopenharmony_ci "0000000000000000" 113800b99b8Sopenharmony_ci#elif defined(__arm__) 114800b99b8Sopenharmony_ci "00000000" 115800b99b8Sopenharmony_ci#endif 116800b99b8Sopenharmony_ci }; 117800b99b8Sopenharmony_ci 118800b99b8Sopenharmony_ci if (!fast) { 119800b99b8Sopenharmony_ci for (std::string keyWord : existKeyWords) { 120800b99b8Sopenharmony_ci if (!CheckContent(content, keyWord, true)) { 121800b99b8Sopenharmony_ci return false; 122800b99b8Sopenharmony_ci } 123800b99b8Sopenharmony_ci } 124800b99b8Sopenharmony_ci } 125800b99b8Sopenharmony_ci for (std::string keyWord : notExistkeyWords) { 126800b99b8Sopenharmony_ci if (!CheckContent(content, keyWord, false)) { 127800b99b8Sopenharmony_ci return false; 128800b99b8Sopenharmony_ci } 129800b99b8Sopenharmony_ci } 130800b99b8Sopenharmony_ci return true; 131800b99b8Sopenharmony_ci} 132800b99b8Sopenharmony_ci 133800b99b8Sopenharmony_cistatic bool TestGetBacktraceInterface() 134800b99b8Sopenharmony_ci{ 135800b99b8Sopenharmony_ci std::string content; 136800b99b8Sopenharmony_ci if (!GetBacktrace(content)) { 137800b99b8Sopenharmony_ci return false; 138800b99b8Sopenharmony_ci } 139800b99b8Sopenharmony_ci 140800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << content; 141800b99b8Sopenharmony_ci if (content.empty()) { 142800b99b8Sopenharmony_ci return false; 143800b99b8Sopenharmony_ci } 144800b99b8Sopenharmony_ci 145800b99b8Sopenharmony_ci if (!CheckBacktraceContent(content)) { 146800b99b8Sopenharmony_ci return false; 147800b99b8Sopenharmony_ci } 148800b99b8Sopenharmony_ci return true; 149800b99b8Sopenharmony_ci} 150800b99b8Sopenharmony_ci 151800b99b8Sopenharmony_cistatic bool TestGetBacktraceFastInterface() 152800b99b8Sopenharmony_ci{ 153800b99b8Sopenharmony_ci#ifdef __aarch64__ 154800b99b8Sopenharmony_ci std::string content; 155800b99b8Sopenharmony_ci if (!GetBacktrace(content, true)) { 156800b99b8Sopenharmony_ci return false; 157800b99b8Sopenharmony_ci } 158800b99b8Sopenharmony_ci 159800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << content; 160800b99b8Sopenharmony_ci if (content.empty()) { 161800b99b8Sopenharmony_ci return false; 162800b99b8Sopenharmony_ci } 163800b99b8Sopenharmony_ci 164800b99b8Sopenharmony_ci if (!CheckBacktraceContent(content, true)) { 165800b99b8Sopenharmony_ci return false; 166800b99b8Sopenharmony_ci } 167800b99b8Sopenharmony_ci#endif 168800b99b8Sopenharmony_ci return true; 169800b99b8Sopenharmony_ci} 170800b99b8Sopenharmony_ci 171800b99b8Sopenharmony_ci/** 172800b99b8Sopenharmony_ci * @tc.name: BacktraceUtilsTest001 173800b99b8Sopenharmony_ci * @tc.desc: test log backtrace to hilog, stdout and file 174800b99b8Sopenharmony_ci * @tc.type: FUNC 175800b99b8Sopenharmony_ci */ 176800b99b8Sopenharmony_ciHWTEST_F(BacktraceUtilsTest, BacktraceUtilsTest001, TestSize.Level2) 177800b99b8Sopenharmony_ci{ 178800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "BacktraceUtilsTest001: start."; 179800b99b8Sopenharmony_ci ASSERT_EQ(true, PrintBacktrace(STDIN_FILENO)); 180800b99b8Sopenharmony_ci ASSERT_EQ(true, PrintBacktrace(STDOUT_FILENO)); 181800b99b8Sopenharmony_ci ASSERT_EQ(true, PrintBacktrace(STDERR_FILENO)); 182800b99b8Sopenharmony_ci ASSERT_EQ(true, PrintBacktrace()); 183800b99b8Sopenharmony_ci int fd = open(TEST_TEMP_FILE, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); 184800b99b8Sopenharmony_ci ASSERT_TRUE(fd >= 0); 185800b99b8Sopenharmony_ci ASSERT_EQ(true, PrintBacktrace(fd)); 186800b99b8Sopenharmony_ci close(fd); 187800b99b8Sopenharmony_ci std::string content; 188800b99b8Sopenharmony_ci if (!OHOS::HiviewDFX::LoadStringFromFile(TEST_TEMP_FILE, content)) { 189800b99b8Sopenharmony_ci FAIL(); 190800b99b8Sopenharmony_ci } 191800b99b8Sopenharmony_ci ASSERT_EQ(CheckBacktraceContent(content), true); 192800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "BacktraceUtilsTest001: end."; 193800b99b8Sopenharmony_ci} 194800b99b8Sopenharmony_ci 195800b99b8Sopenharmony_ci/** 196800b99b8Sopenharmony_ci * @tc.name: BacktraceUtilsTest002 197800b99b8Sopenharmony_ci * @tc.desc: test get backtrace 198800b99b8Sopenharmony_ci * @tc.type: FUNC 199800b99b8Sopenharmony_ci */ 200800b99b8Sopenharmony_ciHWTEST_F(BacktraceUtilsTest, BacktraceUtilsTest002, TestSize.Level2) 201800b99b8Sopenharmony_ci{ 202800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "BacktraceUtilsTest002: start."; 203800b99b8Sopenharmony_ci ASSERT_EQ(TestGetBacktraceInterface(), true); 204800b99b8Sopenharmony_ci ASSERT_EQ(TestGetBacktraceFastInterface(), true); 205800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "BacktraceUtilsTest002: end."; 206800b99b8Sopenharmony_ci} 207800b99b8Sopenharmony_ci 208800b99b8Sopenharmony_ci/** 209800b99b8Sopenharmony_ci * @tc.name: BacktraceUtilsTest003 210800b99b8Sopenharmony_ci * @tc.desc: test get backtrace 100 times 211800b99b8Sopenharmony_ci * @tc.type: FUNC 212800b99b8Sopenharmony_ci */ 213800b99b8Sopenharmony_ciHWTEST_F(BacktraceUtilsTest, BacktraceUtilsTest003, TestSize.Level2) 214800b99b8Sopenharmony_ci{ 215800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "BacktraceUtilsTest003: start."; 216800b99b8Sopenharmony_ci int32_t loopCount = 100; 217800b99b8Sopenharmony_ci for (int32_t i = 0; i < loopCount; i++) { 218800b99b8Sopenharmony_ci ASSERT_EQ(TestGetBacktraceInterface(), true); 219800b99b8Sopenharmony_ci } 220800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "BacktraceUtilsTest003: end."; 221800b99b8Sopenharmony_ci} 222800b99b8Sopenharmony_ci 223800b99b8Sopenharmony_civoid DoCheckBacktraceInMultiThread() 224800b99b8Sopenharmony_ci{ 225800b99b8Sopenharmony_ci std::string content; 226800b99b8Sopenharmony_ci ASSERT_TRUE(GetBacktrace(content)); 227800b99b8Sopenharmony_ci ASSERT_FALSE(content.empty()); 228800b99b8Sopenharmony_ci} 229800b99b8Sopenharmony_ci 230800b99b8Sopenharmony_ci/** 231800b99b8Sopenharmony_ci * @tc.name: BacktraceUtilsTest004 232800b99b8Sopenharmony_ci * @tc.desc: test get backtrace in multi-thread situation 233800b99b8Sopenharmony_ci * @tc.type: FUNC 234800b99b8Sopenharmony_ci */ 235800b99b8Sopenharmony_ciHWTEST_F(BacktraceUtilsTest, BacktraceUtilsTest004, TestSize.Level2) 236800b99b8Sopenharmony_ci{ 237800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "BacktraceUtilsTest004: start."; 238800b99b8Sopenharmony_ci constexpr int32_t threadCount = 50; 239800b99b8Sopenharmony_ci std::vector<std::thread> threads(threadCount); 240800b99b8Sopenharmony_ci for (auto it = std::begin(threads); it != std::end(threads); ++it) { 241800b99b8Sopenharmony_ci *it = std::thread(DoCheckBacktraceInMultiThread); 242800b99b8Sopenharmony_ci } 243800b99b8Sopenharmony_ci 244800b99b8Sopenharmony_ci for (auto&& thread : threads) { 245800b99b8Sopenharmony_ci thread.join(); 246800b99b8Sopenharmony_ci } 247800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "BacktraceUtilsTest004: end."; 248800b99b8Sopenharmony_ci} 249800b99b8Sopenharmony_ci 250800b99b8Sopenharmony_ci/** 251800b99b8Sopenharmony_ci * @tc.name: BacktraceUtilsTest005 252800b99b8Sopenharmony_ci * @tc.desc: test PrintTrace to hilog, stdout and file 253800b99b8Sopenharmony_ci * @tc.type: FUNC 254800b99b8Sopenharmony_ci */ 255800b99b8Sopenharmony_ciHWTEST_F(BacktraceUtilsTest, BacktraceUtilsTest005, TestSize.Level2) 256800b99b8Sopenharmony_ci{ 257800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "BacktraceUtilsTest005: start."; 258800b99b8Sopenharmony_ci ASSERT_EQ(true, PrintTrace(STDIN_FILENO)); 259800b99b8Sopenharmony_ci ASSERT_EQ(true, PrintTrace(STDOUT_FILENO)); 260800b99b8Sopenharmony_ci ASSERT_EQ(true, PrintTrace(STDERR_FILENO)); 261800b99b8Sopenharmony_ci ASSERT_EQ(true, PrintTrace()); 262800b99b8Sopenharmony_ci int fd = open(TEST_TEMP_FILE, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); 263800b99b8Sopenharmony_ci ASSERT_TRUE(fd >= 0); 264800b99b8Sopenharmony_ci ASSERT_EQ(true, PrintTrace(fd)); 265800b99b8Sopenharmony_ci close(fd); 266800b99b8Sopenharmony_ci std::string content; 267800b99b8Sopenharmony_ci if (!OHOS::HiviewDFX::LoadStringFromFile(TEST_TEMP_FILE, content)) { 268800b99b8Sopenharmony_ci FAIL(); 269800b99b8Sopenharmony_ci } 270800b99b8Sopenharmony_ci 271800b99b8Sopenharmony_ci ASSERT_EQ(CheckBacktraceContent(content), true); 272800b99b8Sopenharmony_ci GTEST_LOG_(INFO) << "BacktraceUtilsTest005: end."; 273800b99b8Sopenharmony_ci} 274800b99b8Sopenharmony_ci} // namespace HiviewDFX 275800b99b8Sopenharmony_ci} // namepsace OHOS 276