• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <filesystem>
23 #include "elf_factory.h"
24 #include "elf_imitate.h"
25 #include "unwinder_config.h"
26 
27 using namespace OHOS::HiviewDFX;
28 using namespace testing::ext;
29 using namespace std;
30 
31 #define ELF32_FILE "/data/test/resource/testdata/elf32_test"
32 #define ELF64_FILE "/data/test/resource/testdata/elf_test"
33 #define DUMPCATCHER_ELF_FILE "/system/bin/dumpcatcher"
34 namespace OHOS {
35 namespace HiviewDFX {
36 class DfxSymbolsTest : public testing::Test {
37 public:
SetUpTestCase(void)38     static void SetUpTestCase(void) {}
TearDownTestCase(void)39     static void TearDownTestCase(void) {}
SetUp()40     void SetUp() {}
TearDown()41     void TearDown() {}
42 };
43 
44 
45 /**
46  * @tc.name: DfxSymbolsTest001
47  * @tc.desc: test DfxSymbols functions with 32 bit ELF
48  * @tc.type: FUNC
49  */
50 HWTEST_F(DfxSymbolsTest, DfxSymbolsTest001, TestSize.Level2)
51 {
52     GTEST_LOG_(INFO) << "DfxSymbolsTest001: start.";
53     RegularElfFactory factory(ELF32_FILE);
54     auto elf = factory.Create();
55     ASSERT_TRUE(elf->IsValid());
56     ElfImitate elfImitate;
57     elfImitate.ParseAllHeaders(ElfImitate::ElfFileType::ELF32);
58     std::string funcName;
59     uint64_t funcOffset;
60     ASSERT_TRUE(DfxSymbols::GetFuncNameAndOffsetByPc(0x00001786, elf, funcName, funcOffset));
61     GTEST_LOG_(INFO) << funcName << " " << funcOffset;
62     std::vector<DfxSymbol> symbols;
63     std::vector<DfxSymbol> symbolsImitate;
64     ASSERT_TRUE(DfxSymbols::ParseSymbols(symbols, elf, ELF32_FILE));
65     ASSERT_TRUE(elfImitate.ParseSymbols(symbolsImitate, ELF32_FILE));
66     ASSERT_EQ(symbols.size(), symbolsImitate.size());
67     for (size_t i = 0; i < symbolsImitate.size(); ++i) {
68         symbols[i].fileVaddr_ = symbolsImitate[i].fileVaddr_;
69         symbols[i].funcVaddr_ = symbolsImitate[i].funcVaddr_;
70         symbols[i].name_ = symbolsImitate[i].name_;
71         symbols[i].demangle_ = symbolsImitate[i].demangle_;
72         symbols[i].module_ = symbolsImitate[i].module_;
73     }
74 
75     DfxSymbols::AddSymbolsByPlt(symbols, elf, ELF32_FILE);
76     elfImitate.AddSymbolsByPlt(symbolsImitate, ELF32_FILE);
77     ASSERT_EQ(symbols.size(), symbolsImitate.size());
78     for (size_t i = 0; i < symbolsImitate.size(); ++i) {
79         symbols[i].fileVaddr_ = symbolsImitate[i].fileVaddr_;
80         symbols[i].funcVaddr_ = symbolsImitate[i].funcVaddr_;
81         symbols[i].name_ = symbolsImitate[i].name_;
82         symbols[i].demangle_ = symbolsImitate[i].demangle_;
83         symbols[i].module_ = symbolsImitate[i].module_;
84     }
85     ASSERT_FALSE(DfxSymbols::ParseSymbols(symbols, nullptr, ELF32_FILE));
86     elf->SetBaseOffset(0x1000);
87     ASSERT_TRUE(DfxSymbols::ParseSymbols(symbols, elf, ELF32_FILE));
88     ASSERT_FALSE(DfxSymbols::AddSymbolsByPlt(symbols, nullptr, ELF32_FILE));
89     GTEST_LOG_(INFO) << symbols[0].module_;
90     GTEST_LOG_(INFO) << "DfxSymbolsTest001: end.";
91 }
92 
93 /**
94  * @tc.name: DfxSymbolsTest002
95  * @tc.desc: test DfxSymbols functions with 64 bit ELF
96  * @tc.type: FUNC
97  */
98 HWTEST_F(DfxSymbolsTest, DfxSymbolsTest002, TestSize.Level2)
99 {
100     GTEST_LOG_(INFO) << "DfxSymbolsTest002: start.";
101     RegularElfFactory factory(ELF64_FILE);
102     auto elf = factory.Create();
103     ASSERT_TRUE(elf->IsValid());
104     ElfImitate elfImitate;
105     elfImitate.ParseAllHeaders(ElfImitate::ElfFileType::ELF64);
106     std::string funcName;
107     uint64_t funcOffset;
108     ASSERT_TRUE(DfxSymbols::GetFuncNameAndOffsetByPc(0x00002a08, elf, funcName, funcOffset));
109     GTEST_LOG_(INFO) << funcName << " " << funcOffset;
110     std::vector<DfxSymbol> symbols;
111     std::vector<DfxSymbol> symbolsImitate;
112     ASSERT_TRUE(DfxSymbols::ParseSymbols(symbols, elf, ELF64_FILE));
113     ASSERT_TRUE(elfImitate.ParseSymbols(symbolsImitate, ELF64_FILE));
114     ASSERT_EQ(symbols.size(), symbolsImitate.size());
115     for (size_t i = 0; i < symbolsImitate.size(); ++i) {
116         symbols[i].fileVaddr_ = symbolsImitate[i].fileVaddr_;
117         symbols[i].funcVaddr_ = symbolsImitate[i].funcVaddr_;
118         symbols[i].name_ = symbolsImitate[i].name_;
119         symbols[i].demangle_ = symbolsImitate[i].demangle_;
120         symbols[i].module_ = symbolsImitate[i].module_;
121     }
122 
123     DfxSymbols::AddSymbolsByPlt(symbols, elf, ELF64_FILE);
124     elfImitate.AddSymbolsByPlt(symbolsImitate, ELF64_FILE);
125     ASSERT_EQ(symbols.size(), symbolsImitate.size());
126     for (size_t i = 0; i < symbolsImitate.size(); ++i) {
127         symbols[i].fileVaddr_ = symbolsImitate[i].fileVaddr_;
128         symbols[i].funcVaddr_ = symbolsImitate[i].funcVaddr_;
129         symbols[i].name_ = symbolsImitate[i].name_;
130         symbols[i].demangle_ = symbolsImitate[i].demangle_;
131         symbols[i].module_ = symbolsImitate[i].module_;
132     }
133     ASSERT_FALSE(DfxSymbols::ParseSymbols(symbols, nullptr, ELF64_FILE));
134     elf->SetBaseOffset(0x1000);
135     ASSERT_TRUE(DfxSymbols::ParseSymbols(symbols, elf, ELF64_FILE));
136     ASSERT_FALSE(DfxSymbols::AddSymbolsByPlt(symbols, nullptr, ELF64_FILE));
137     GTEST_LOG_(INFO) << symbols[0].module_;
138     GTEST_LOG_(INFO) << "DfxSymbolsTest002: end.";
139 }
140 
141 #if defined(ENABLE_MINIDEBUGINFO)
142 /**
143  * @tc.name: DfxSymbolsTest003
144  * @tc.desc: test DfxSymbols functions with minidebuginfo elf
145  * @tc.type: FUNC
146  */
147 HWTEST_F(DfxSymbolsTest, DfxSymbolsTest003, TestSize.Level2)
148 {
149     GTEST_LOG_(INFO) << "DfxSymbolsTest003: start.";
150     UnwinderConfig::SetEnableMiniDebugInfo(true);
151     std::vector<DfxSymbol> dfxSymbols;
152     RegularElfFactory factory(DUMPCATCHER_ELF_FILE);
153     auto elf = factory.Create();
154     ASSERT_TRUE(elf->IsValid());
155     DfxSymbols::ParseSymbols(dfxSymbols, elf, DUMPCATCHER_ELF_FILE);
156     GTEST_LOG_(INFO) << "DfxSymbolsTest003: symbols size:" << dfxSymbols.size();
157     ASSERT_GE(dfxSymbols.size(), 0);
158     for (auto dfxSymbol : dfxSymbols) {
159         GTEST_LOG_(INFO) << "DfxSymbolsTest003: dfxSymbol.demangle_: "<< dfxSymbol.demangle_;
160     }
161     GTEST_LOG_(INFO) << "DfxSymbolsTest003: end.";
162 }
163 #endif
164 
165 /**
166  * @tc.name: DfxDemangleTest001
167  * @tc.desc: test DfxSymbols demangle functions
168  * @tc.type: FUNC
169  */
170 HWTEST_F(DfxSymbolsTest, DfxDemangleTest001, TestSize.Level2)
171 {
172     GTEST_LOG_(INFO) << "DfxDemangleTest001: start.";
173     EXPECT_EQ("", DfxSymbols::Demangle(""));
174     EXPECT_EQ("a", DfxSymbols::Demangle("a"));
175     EXPECT_EQ("_", DfxSymbols::Demangle("_"));
176     EXPECT_EQ("ab", DfxSymbols::Demangle("ab"));
177     EXPECT_EQ("abc", DfxSymbols::Demangle("abc"));
178     EXPECT_EQ("_R", DfxSymbols::Demangle("_R"));
179     EXPECT_EQ("_Z", DfxSymbols::Demangle("_Z"));
180     GTEST_LOG_(INFO) << "DfxDemangleTest001: end.";
181 }
182 
183 /**
184  * @tc.name: DfxDemangleTest002
185  * @tc.desc: test DfxSymbols demangle functions with cxx
186  * @tc.type: FUNC
187  */
188 HWTEST_F(DfxSymbolsTest, DfxDemangleTest002, TestSize.Level2)
189 {
190     GTEST_LOG_(INFO) << "DfxDemangleTest002: start.";
191     EXPECT_EQ("fake(bool)", DfxSymbols::Demangle("_Z4fakeb"));
192     EXPECT_EQ("demangle(int)", DfxSymbols::Demangle("_Z8demanglei"));
193     GTEST_LOG_(INFO) << "DfxDemangleTest002: end.";
194 }
195 
196 /**
197  * @tc.name: DfxDemangleTest003
198  * @tc.desc: test DfxSymbols demangle functions with rust
199  * @tc.type: FUNC
200  */
201 HWTEST_F(DfxSymbolsTest, DfxDemangleTest003, TestSize.Level2)
202 {
203     GTEST_LOG_(INFO) << "DfxDemangleTest003: start.";
204     EXPECT_EQ("std::rt::lang_start_internal",
205         DfxSymbols::Demangle("_RNvNtCs2WRBrrl1bb1_3std2rt19lang_start_internal"));
206     EXPECT_EQ("profcollectd::main", DfxSymbols::Demangle("_RNvCs4VPobU5SDH_12profcollectd4main"));
207     GTEST_LOG_(INFO) << "DfxDemangleTest003: end.";
208 }
209 
210 /**
211  * @tc.name: DfxDemangleTest004
212  * @tc.desc: test DfxSymbols demangle functions with cangjie
213  * @tc.type: FUNC
214  */
215 HWTEST_F(DfxSymbolsTest, DfxDemangleTest004, TestSize.Level2)
216 {
217     GTEST_LOG_(INFO) << "DfxDemangleTest004: start.";
218     std::filesystem::path runtimePath("/system/lib64/chipset-sdk/libcangjie-demangle.so");
219     if (std::filesystem::exists(runtimePath)) {
220         EXPECT_EQ("std.time.initLocalDefault()",
221             DfxSymbols::Demangle("_CN8std.time16initLocalDefaultHv"));
222         EXPECT_EQ("std.core.Error::init()", DfxSymbols::Demangle("_CN8std.core5Error6<init>Hv"));
223     } else {
224         EXPECT_EQ("_CN8std.time16initLocalDefaultHv",
225             DfxSymbols::Demangle("_CN8std.time16initLocalDefaultHv"));
226         EXPECT_EQ("_CN8std.core5Error6<init>Hv",
227             DfxSymbols::Demangle("_CN8std.core5Error6<init>Hv"));
228     }
229     GTEST_LOG_(INFO) << "DfxDemangleTest004: end.";
230 }
231 
232 /**
233  * @tc.name: DfxDemangleTest005
234  * @tc.desc: test DfxSymbols demangle functions with cangjie
235  * @tc.type: FUNC
236  */
237 HWTEST_F(DfxSymbolsTest, DfxDemangleTest005, TestSize.Level2)
238 {
239     GTEST_LOG_(INFO) << "DfxDemangleTest005: start.";
240     CompressHapElfFactory compress1("", nullptr);
241     std::shared_ptr<DfxElf> res = compress1.Create();
242     EXPECT_EQ(res, nullptr);
243     auto prevMap = std::shared_ptr<DfxMap>();
244     CompressHapElfFactory compress2("", prevMap);
245     res = compress2.Create();
246     EXPECT_EQ(res, nullptr);
247     CompressHapElfFactory compress3("/proc/", prevMap);
248     res = compress3.Create();
249     EXPECT_EQ(res, nullptr);
250     CompressHapElfFactory compress4("/proc/123/test.hap", prevMap);
251     res = compress4.Create();
252     EXPECT_EQ(res, nullptr);
253     GTEST_LOG_(INFO) << "DfxDemangleTest005: end.";
254 }
255 } // namespace HiviewDFX
256 } // namespace OHOS
257 
258