1 /*
2 * Copyright (c) 2021-2023 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 "dfx_elf.h"
17 #include "dfx_maps.h"
18 #include <gtest/gtest.h>
19 #include <memory>
20 #include <sys/types.h>
21
22 using namespace OHOS::HiviewDFX;
23 using namespace std;
24 using namespace testing::ext;
25
26 namespace OHOS {
27 namespace HiviewDFX {
28 namespace {
29 const string INVALID_MAP_NAME = "/system/lib64/init/libinit_context111.z.so";
30 #ifdef __arm__
31 const string MAPS_FILE = "/data/test/resource/testdata/testmaps_32";
32 const string VALID_MAP_NAME = "/system/lib/init/libinit_context.z.so";
33 const string VALID_MAP_ITEM = "f6d83000-f6d84000 r--p 00001000 b3:07 1892 /system/lib/init/libinit_context.z.so";
34 const string INVALID_MAP_ITEM = "f6d83000-f6d84000 r--p 00001000 b3:07 1892 /system/lib/init/libinit_context111.z.so";
35 const string VDSO_MAP_ITEM = "f7c21000-f7c22000 r-xp 00000000 00:00 0 [vdso]";
36 const string ARK_HAP_MAP_NAME = "/system/app/SceneBoard/SceneBoard.hap";
37 const string ARK_CODE_MAP_NAME = "[anon:ArkTS Code:libdialog.z.so/Dialog.js]";
38 #else
39 const string MAPS_FILE = "/data/test/resource/testdata/testmaps_64";
40 const string VALID_MAP_NAME = "/system/lib64/init/libinit_context.z.so";
41 const string VALID_MAP_ITEM = "7f0ab40000-7f0ab41000 r--p 00000000 b3:07 1882 /system/lib64/init/libinit_context.z.so";
42 const string INVALID_MAP_ITEM = "7f0ab40000-7f0ab41000 r--p 00000000 b3:07 1882 \
43 /system/lib64/init/libinit_context111.z.so";
44 const string VDSO_MAP_ITEM = "7f8b9df000-7f8b9e0000 r-xp 00000000 00:00 0 [vdso]";
45 const string ARK_HAP_MAP_NAME = "/system/app/SceneBoard/SceneBoard.hap";
46 const string ARK_CODE_MAP_NAME = "[anon:ArkTS Code:libdialog.z.so/Dialog.js]";
47 #endif
48 }
49
50 class MapsTest : public testing::Test {
51 public:
SetUpTestCase(void)52 static void SetUpTestCase(void) {}
TearDownTestCase(void)53 static void TearDownTestCase(void) {}
SetUp()54 void SetUp() { maps_ = DfxMaps::Create(getpid(), MAPS_FILE); }
TearDown()55 void TearDown() {}
56
57 public:
58 std::shared_ptr<DfxMaps> maps_;
59 };
60
61 namespace {
62
63 /**
64 * @tc.name: FindMapByAddrTest001
65 * @tc.desc: test FindMapByAddr functions
66 * @tc.type: FUNC
67 */
HWTEST_F(MapsTest, FindMapByAddrTest001, TestSize.Level2)68 HWTEST_F(MapsTest, FindMapByAddrTest001, TestSize.Level2)
69 {
70 GTEST_LOG_(INFO) << "FindMapByAddrTest001: start.";
71 maps_->Sort(true);
72 #ifdef __arm__
73 uintptr_t validAddr = 0xf6d80000;
74 #else
75 uintptr_t validAddr = 0x7f8b8f3001;
76 #endif
77 const uintptr_t invalidAddr = 0xffffffff;
78 std::shared_ptr<DfxMap> map = nullptr;
79 EXPECT_EQ(true, maps_->FindMapByAddr(validAddr, map));
80 EXPECT_EQ(false, maps_->FindMapByAddr(invalidAddr, map));
81 GTEST_LOG_(INFO) << "FindMapByAddrTest001: end.";
82 }
83
84 /**
85 * @tc.name: FindMapByFileInfoTest001
86 * @tc.desc: test FindMapByFileInfo functions
87 * @tc.type: FUNC
88 */
HWTEST_F(MapsTest, FindMapByFileInfoTest001, TestSize.Level2)89 HWTEST_F(MapsTest, FindMapByFileInfoTest001, TestSize.Level2)
90 {
91 GTEST_LOG_(INFO) << "FindMapByFileInfoTest001: start.";
92 std::shared_ptr<DfxMap> map = nullptr;
93 EXPECT_EQ(true, maps_->FindMapByFileInfo(VALID_MAP_NAME, 0, map));
94 EXPECT_EQ(false, maps_->FindMapByFileInfo(INVALID_MAP_NAME, 0, map));
95 const uint64_t invalidOffset = 0xffffffff;
96 EXPECT_EQ(false, maps_->FindMapByFileInfo(VALID_MAP_NAME, invalidOffset, map));
97 EXPECT_EQ(false, maps_->FindMapByFileInfo(INVALID_MAP_NAME, invalidOffset, map));
98 GTEST_LOG_(INFO) << "FindMapByFileInfoTest001: end.";
99 }
100
101 /**
102 * @tc.name: FindMapsByNameTest001
103 * @tc.desc: test FindMapsByName functions
104 * @tc.type: FUNC
105 */
HWTEST_F(MapsTest, FindMapsByNameTest001, TestSize.Level2)106 HWTEST_F(MapsTest, FindMapsByNameTest001, TestSize.Level2)
107 {
108 GTEST_LOG_(INFO) << "FindMapsByNameTest001: start.";
109 std::vector<std::shared_ptr<DfxMap>> mapsV;
110 EXPECT_EQ(true, maps_->FindMapsByName(VALID_MAP_NAME, mapsV));
111 mapsV.clear();
112 EXPECT_EQ(false, maps_->FindMapsByName(INVALID_MAP_NAME, mapsV));
113 GTEST_LOG_(INFO) << "FindMapsByNameTest001: end.";
114 }
115
116 /**
117 * @tc.name: IsArkNameTest001
118 * @tc.desc: test IsArkExecutable functions
119 * @tc.type: FUNC
120 */
HWTEST_F(MapsTest, IsArkNameTest001, TestSize.Level2)121 HWTEST_F(MapsTest, IsArkNameTest001, TestSize.Level2)
122 {
123 GTEST_LOG_(INFO) << "IsArkNameTest001: start.";
124 std::shared_ptr<DfxMap> map = nullptr;
125 map = std::make_shared<DfxMap>(0, 0, 0, "1", "anon:ArkTS Code");
126 EXPECT_EQ(false, map->IsArkExecutable());
127 map = std::make_shared<DfxMap>(0, 0, 0, "1", "/dev/zero");
128 EXPECT_EQ(false, map->IsArkExecutable());
129 map = std::make_shared<DfxMap>(0, 0, 0, 4, "[anon:ArkTS Code]");
130 EXPECT_EQ(true, map->IsArkExecutable());
131 GTEST_LOG_(INFO) << "IsArkNameTest001: end.";
132 }
133
134 /**
135 * @tc.name: GetRelPcTest
136 * @tc.desc: test getRelPc no elf
137 * @tc.type: FUNC
138 */
HWTEST_F(MapsTest, GetRelPcTest, TestSize.Level2)139 HWTEST_F(MapsTest, GetRelPcTest, TestSize.Level2)
140 {
141 GTEST_LOG_(INFO) << "GetRelPcTest: start.";
142 #ifdef __arm__
143 uint64_t pc = 0xf6d83001;
144 const uint64_t invalidOffset = 0x1001;
145 #else
146 uint64_t pc = 0x7f0ab40016;
147 const uint64_t invalidOffset = 0x16;
148 #endif
149 shared_ptr<DfxMap> map = DfxMap::Create(INVALID_MAP_ITEM, sizeof(INVALID_MAP_ITEM));
150 EXPECT_EQ(true, ((map->GetElf() == nullptr) && (map->GetRelPc(pc) == invalidOffset)));
151 GTEST_LOG_(INFO) << "GetRelPcTest: end.";
152 }
153
154 /**
155 * @tc.name: ToStringTest
156 * @tc.desc: test ToString
157 * @tc.type: FUNC
158 */
HWTEST_F(MapsTest, ToStringTest, TestSize.Level2)159 HWTEST_F(MapsTest, ToStringTest, TestSize.Level2)
160 {
161 GTEST_LOG_(INFO) << "ToStringTest: start.";
162 shared_ptr<DfxMap> map = DfxMap::Create(VALID_MAP_ITEM, sizeof(VALID_MAP_ITEM));
163 GTEST_LOG_(INFO) << map->ToString();
164 EXPECT_EQ(true, sizeof(map->ToString()) != 0);
165 GTEST_LOG_(INFO) << "ToStringTest: end.";
166 }
167
168 /**
169 * @tc.name: CreateMapsTest
170 * @tc.desc: test create maps by pid
171 * @tc.type: FUNC
172 */
HWTEST_F(MapsTest, CreateMapsTest, TestSize.Level2)173 HWTEST_F(MapsTest, CreateMapsTest, TestSize.Level2)
174 {
175 GTEST_LOG_(INFO) << "CreateMapsTest: start.";
176 std::shared_ptr<DfxMaps> dfxMaps = DfxMaps::Create(getpid());
177 ASSERT_TRUE(dfxMaps != nullptr);
178 auto maps = dfxMaps->GetMaps();
179 for (auto map : maps) {
180 std::cout << map->ToString();
181 }
182 GTEST_LOG_(INFO) << "CreateMapsTest: end.";
183 }
184
185 /**
186 * @tc.name: GetStackRangeTest
187 * @tc.desc: test GetStackRange
188 * @tc.type: FUNC
189 */
HWTEST_F(MapsTest, GetStackRangeTest, TestSize.Level2)190 HWTEST_F(MapsTest, GetStackRangeTest, TestSize.Level2)
191 {
192 GTEST_LOG_(INFO) << "GetStackRangeTest: start.";
193 uintptr_t bottom, top;
194 ASSERT_TRUE(maps_->GetStackRange(bottom, top));
195 #ifdef __arm__
196 EXPECT_EQ(bottom, 0xff860000);
197 EXPECT_EQ(top, 0xff881000);
198 #else
199 EXPECT_EQ(bottom, 0x7fe37db000);
200 EXPECT_EQ(top, 0x7fe37fc000);
201 #endif
202 GTEST_LOG_(INFO) << "GetStackRangeTest: end.";
203 }
204
205 /**
206 * @tc.name: IsArkExecutedMapTest
207 * @tc.desc: test IsArkExecutedMap
208 * @tc.type: FUNC
209 */
HWTEST_F(MapsTest, IsArkExecutedMapTest, TestSize.Level2)210 HWTEST_F(MapsTest, IsArkExecutedMapTest, TestSize.Level2)
211 {
212 GTEST_LOG_(INFO) << "IsArkExecutedMapTest: start.";
213 uintptr_t addr;
214 #ifdef __arm__
215 addr = 0xffff2001;
216 #else
217 addr = 0x7fe37fd001;
218 #endif
219 ASSERT_TRUE(maps_->IsArkExecutedMap(addr));
220 #ifdef __arm__
221 addr = 0xffff1001;
222 #else
223 addr = 0x7fe37fc001;
224 #endif
225 ASSERT_FALSE(maps_->IsArkExecutedMap(addr));
226 addr = 0x0;
227 ASSERT_FALSE(maps_->IsArkExecutedMap(addr));
228 maps_->Sort(false);
229 GTEST_LOG_(INFO) << "IsArkExecutedMapTest: end.";
230 }
231
232 /**
233 * @tc.name: IsVdsoMapTest
234 * @tc.desc: test IsVdsoMap
235 * @tc.type: FUNC
236 */
HWTEST_F(MapsTest, IsVdsoMapTest, TestSize.Level2)237 HWTEST_F(MapsTest, IsVdsoMapTest, TestSize.Level2)
238 {
239 GTEST_LOG_(INFO) << "IsVdsoMapTest: start.";
240 shared_ptr<DfxMap> map = DfxMap::Create(VDSO_MAP_ITEM, sizeof(VDSO_MAP_ITEM));
241 ASSERT_TRUE(map->IsVdsoMap());
242 GTEST_LOG_(INFO) << "IsVdsoMapTest: end.";
243 }
244
245 /**
246 * @tc.name: IsLegalMapItemTest
247 * @tc.desc: test IsLegalMapItem, IsArkHapMapItem, IsArkCodeMapItem
248 * @tc.type: FUNC
249 */
HWTEST_F(MapsTest, IsLegalMapItemTest, TestSize.Level2)250 HWTEST_F(MapsTest, IsLegalMapItemTest, TestSize.Level2)
251 {
252 GTEST_LOG_(INFO) << "IsLegalMapItemTest: start.";
253 ASSERT_TRUE(DfxMaps::IsArkHapMapItem(ARK_HAP_MAP_NAME));
254 ASSERT_TRUE(DfxMaps::IsArkCodeMapItem(ARK_CODE_MAP_NAME));
255 ASSERT_TRUE(DfxMaps::IsLegalMapItem(ARK_CODE_MAP_NAME));
256 GTEST_LOG_(INFO) << "IsLegalMapItemTest: end.";
257 }
258 }
259 } // namespace HiviewDFX
260 } // namespace OHOS