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