1 /* 2 * Copyright (c) 2022 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 #include <ctime> 18 #include <securec.h> 19 #include <string> 20 #include <vector> 21 #include <iostream> 22 #include "dfx_elf.h" 23 #include "elf_imitate.h" 24 #include "unwinder_config.h" 25 26 using namespace OHOS::HiviewDFX; 27 using namespace testing::ext; 28 using namespace std; 29 30 #define ELF32_FILE "/data/test/resource/testdata/elf32_test" 31 #define ELF64_FILE "/data/test/resource/testdata/elf_test" 32 #define DUMPCATCHER_ELF_FILE "/system/bin/dumpcatcher" 33 namespace OHOS { 34 namespace HiviewDFX { 35 class DfxSymbolsTest : public testing::Test { 36 public: SetUpTestCase(void)37 static void SetUpTestCase(void) {} TearDownTestCase(void)38 static void TearDownTestCase(void) {} SetUp()39 void SetUp() {} TearDown()40 void TearDown() {} 41 }; 42 43 44 /** 45 * @tc.name: DfxSymbolsTest001 46 * @tc.desc: test DfxSymbols functions with 32 bit ELF 47 * @tc.type: FUNC 48 */ 49 HWTEST_F(DfxSymbolsTest, DfxSymbolsTest001, TestSize.Level2) 50 { 51 GTEST_LOG_(INFO) << "DfxSymbolsTest001: start."; 52 std::shared_ptr<DfxElf> elf = make_shared<DfxElf>(ELF32_FILE); 53 ASSERT_TRUE(elf->IsValid()); 54 ElfImitate elfImitate; 55 elfImitate.ParseAllHeaders(ElfImitate::ElfFileType::ELF32); 56 std::vector<DfxSymbol> symbols; 57 std::vector<DfxSymbol> symbolsImitate; 58 DfxSymbols::ParseSymbols(symbols, elf, ELF32_FILE); 59 elfImitate.ParseSymbols(symbolsImitate, ELF32_FILE); 60 ASSERT_EQ(symbols.size(), symbolsImitate.size()); 61 for (size_t i = 0; i < symbolsImitate.size(); ++i) { 62 symbols[i].fileVaddr_ = symbolsImitate[i].fileVaddr_; 63 symbols[i].funcVaddr_ = symbolsImitate[i].funcVaddr_; 64 symbols[i].name_ = symbolsImitate[i].name_; 65 symbols[i].demangle_ = symbolsImitate[i].demangle_; 66 symbols[i].module_ = symbolsImitate[i].module_; 67 } 68 69 DfxSymbols::AddSymbolsByPlt(symbols, elf, ELF32_FILE); 70 elfImitate.AddSymbolsByPlt(symbolsImitate, ELF32_FILE); 71 ASSERT_EQ(symbols.size(), symbolsImitate.size()); 72 for (size_t i = 0; i < symbolsImitate.size(); ++i) { 73 symbols[i].fileVaddr_ = symbolsImitate[i].fileVaddr_; 74 symbols[i].funcVaddr_ = symbolsImitate[i].funcVaddr_; 75 symbols[i].name_ = symbolsImitate[i].name_; 76 symbols[i].demangle_ = symbolsImitate[i].demangle_; 77 symbols[i].module_ = symbolsImitate[i].module_; 78 } 79 std::string funcName; 80 uint64_t funcOffset; 81 ASSERT_TRUE(DfxSymbols::GetFuncNameAndOffsetByPc(0x00001786, elf, funcName, funcOffset)); 82 GTEST_LOG_(INFO) << "DfxSymbolsTest001: end."; 83 } 84 85 /** 86 * @tc.name: DfxSymbolsTest002 87 * @tc.desc: test DfxSymbols functions with 64 bit ELF 88 * @tc.type: FUNC 89 */ 90 HWTEST_F(DfxSymbolsTest, DfxSymbolsTest002, TestSize.Level2) 91 { 92 GTEST_LOG_(INFO) << "DfxSymbolsTest002: start."; 93 std::shared_ptr<DfxElf> elf = make_shared<DfxElf>(ELF64_FILE); 94 ASSERT_TRUE(elf->IsValid()); 95 ElfImitate elfImitate; 96 elfImitate.ParseAllHeaders(ElfImitate::ElfFileType::ELF64); 97 std::vector<DfxSymbol> symbols; 98 std::vector<DfxSymbol> symbolsImitate; 99 DfxSymbols::ParseSymbols(symbols, elf, ELF64_FILE); 100 elfImitate.ParseSymbols(symbolsImitate, ELF64_FILE); 101 ASSERT_EQ(symbols.size(), symbolsImitate.size()); 102 for (size_t i = 0; i < symbolsImitate.size(); ++i) { 103 symbols[i].fileVaddr_ = symbolsImitate[i].fileVaddr_; 104 symbols[i].funcVaddr_ = symbolsImitate[i].funcVaddr_; 105 symbols[i].name_ = symbolsImitate[i].name_; 106 symbols[i].demangle_ = symbolsImitate[i].demangle_; 107 symbols[i].module_ = symbolsImitate[i].module_; 108 } 109 110 DfxSymbols::AddSymbolsByPlt(symbols, elf, ELF64_FILE); 111 elfImitate.AddSymbolsByPlt(symbolsImitate, ELF64_FILE); 112 ASSERT_EQ(symbols.size(), symbolsImitate.size()); 113 for (size_t i = 0; i < symbolsImitate.size(); ++i) { 114 symbols[i].fileVaddr_ = symbolsImitate[i].fileVaddr_; 115 symbols[i].funcVaddr_ = symbolsImitate[i].funcVaddr_; 116 symbols[i].name_ = symbolsImitate[i].name_; 117 symbols[i].demangle_ = symbolsImitate[i].demangle_; 118 symbols[i].module_ = symbolsImitate[i].module_; 119 } 120 std::string funcName; 121 uint64_t funcOffset; 122 ASSERT_TRUE(DfxSymbols::GetFuncNameAndOffsetByPc(0x00002a08, elf, funcName, funcOffset)); 123 124 GTEST_LOG_(INFO) << "DfxSymbolsTest002: end."; 125 } 126 127 #if defined(ENABLE_MINIDEBUGINFO) 128 /** 129 * @tc.name: DfxSymbolsTest003 130 * @tc.desc: test DfxSymbols functions with minidebuginfo elf 131 * @tc.type: FUNC 132 */ 133 HWTEST_F(DfxSymbolsTest, DfxSymbolsTest003, TestSize.Level2) 134 { 135 GTEST_LOG_(INFO) << "DfxSymbolsTest003: start."; 136 UnwinderConfig::SetEnableMiniDebugInfo(true); 137 std::vector<DfxSymbol> dfxSymbols; 138 std::shared_ptr<DfxElf> elf = make_shared<DfxElf>(DUMPCATCHER_ELF_FILE); 139 ASSERT_TRUE(elf->IsValid()); 140 ASSERT_TRUE(elf->IsEmbeddedElfValid()); 141 DfxSymbols::ParseSymbols(dfxSymbols, elf, DUMPCATCHER_ELF_FILE); 142 GTEST_LOG_(INFO) << "DfxSymbolsTest003: symbols size:" << dfxSymbols.size(); 143 ASSERT_GE(dfxSymbols.size(), 0); 144 for (auto dfxSymbol : dfxSymbols) { 145 GTEST_LOG_(INFO) << "DfxSymbolsTest003: dfxSymbol.demangle_: "<< dfxSymbol.demangle_; 146 } 147 GTEST_LOG_(INFO) << "DfxSymbolsTest003: end."; 148 } 149 #endif 150 151 /** 152 * @tc.name: DfxDemangleTest001 153 * @tc.desc: test DfxSymbols demangle functions 154 * @tc.type: FUNC 155 */ 156 HWTEST_F(DfxSymbolsTest, DfxDemangleTest001, TestSize.Level2) 157 { 158 GTEST_LOG_(INFO) << "DfxDemangleTest001: start."; 159 EXPECT_EQ("", DfxSymbols::Demangle("")); 160 EXPECT_EQ("a", DfxSymbols::Demangle("a")); 161 EXPECT_EQ("_", DfxSymbols::Demangle("_")); 162 EXPECT_EQ("ab", DfxSymbols::Demangle("ab")); 163 EXPECT_EQ("abc", DfxSymbols::Demangle("abc")); 164 EXPECT_EQ("_R", DfxSymbols::Demangle("_R")); 165 EXPECT_EQ("_Z", DfxSymbols::Demangle("_Z")); 166 GTEST_LOG_(INFO) << "DfxDemangleTest001: end."; 167 } 168 169 /** 170 * @tc.name: DfxDemangleTest002 171 * @tc.desc: test DfxSymbols demangle functions with cxx 172 * @tc.type: FUNC 173 */ 174 HWTEST_F(DfxSymbolsTest, DfxDemangleTest002, TestSize.Level2) 175 { 176 GTEST_LOG_(INFO) << "DfxDemangleTest002: start."; 177 EXPECT_EQ("fake(bool)", DfxSymbols::Demangle("_Z4fakeb")); 178 EXPECT_EQ("demangle(int)", DfxSymbols::Demangle("_Z8demanglei")); 179 GTEST_LOG_(INFO) << "DfxDemangleTest002: end."; 180 } 181 182 /** 183 * @tc.name: DfxDemangleTest003 184 * @tc.desc: test DfxSymbols demangle functions with rust 185 * @tc.type: FUNC 186 */ 187 HWTEST_F(DfxSymbolsTest, DfxDemangleTest003, TestSize.Level2) 188 { 189 GTEST_LOG_(INFO) << "DfxDemangleTest003: start."; 190 EXPECT_EQ("std::rt::lang_start_internal", 191 DfxSymbols::Demangle("_RNvNtCs2WRBrrl1bb1_3std2rt19lang_start_internal")); 192 EXPECT_EQ("profcollectd::main", DfxSymbols::Demangle("_RNvCs4VPobU5SDH_12profcollectd4main")); 193 GTEST_LOG_(INFO) << "DfxDemangleTest003: end."; 194 } 195 } // namespace HiviewDFX 196 } // namespace OHOS 197 198