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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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