1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "OfflineUnwinder_impl.h" 18 19 #include <gtest/gtest.h> 20 21 using namespace simpleperf; 22 23 bool CheckUnwindMaps(UnwindMaps& maps, const MapSet& map_set) { 24 if (maps.Total() != map_set.maps.size()) { 25 return false; 26 } 27 unwindstack::MapInfo* prev_real_map = nullptr; 28 for (size_t i = 0; i < maps.Total(); i++) { 29 unwindstack::MapInfo* info = maps.Get(i); 30 if (info == nullptr || map_set.maps.find(info->start) == map_set.maps.end()) { 31 return false; 32 } 33 if (info->prev_real_map != prev_real_map) { 34 return false; 35 } 36 if (!info->IsBlank()) { 37 prev_real_map = info; 38 } 39 } 40 return true; 41 } 42 43 TEST(OfflineUnwinder, UnwindMaps) { 44 // 1. Create fake map entries. 45 std::unique_ptr<Dso> fake_dso = Dso::CreateDso(DSO_UNKNOWN_FILE, "unknown"); 46 std::vector<MapEntry> map_entries; 47 for (size_t i = 0; i < 10; i++) { 48 map_entries.emplace_back(i, 1, i, fake_dso.get(), false); 49 } 50 51 // 2. Init with empty maps. 52 MapSet map_set; 53 UnwindMaps maps; 54 maps.UpdateMaps(map_set); 55 ASSERT_TRUE(CheckUnwindMaps(maps, map_set)); 56 57 // 3. Add maps starting from even addr. 58 map_set.version = 1; 59 for (size_t i = 0; i < map_entries.size(); i += 2) { 60 map_set.maps.insert(std::make_pair(map_entries[i].start_addr, &map_entries[i])); 61 } 62 63 maps.UpdateMaps(map_set); 64 ASSERT_TRUE(CheckUnwindMaps(maps, map_set)); 65 66 // 4. Add maps starting from odd addr. 67 map_set.version = 2; 68 for (size_t i = 1; i < 10; i += 2) { 69 map_set.maps.insert(std::make_pair(map_entries[i].start_addr, &map_entries[i])); 70 } 71 maps.UpdateMaps(map_set); 72 ASSERT_TRUE(CheckUnwindMaps(maps, map_set)); 73 74 // 5. Remove maps starting from even addr. 75 map_set.version = 3; 76 for (size_t i = 0; i < 10; i += 2) { 77 map_set.maps.erase(map_entries[i].start_addr); 78 } 79 maps.UpdateMaps(map_set); 80 ASSERT_TRUE(CheckUnwindMaps(maps, map_set)); 81 82 // 6. Remove all maps. 83 map_set.version = 4; 84 map_set.maps.clear(); 85 maps.UpdateMaps(map_set); 86 ASSERT_TRUE(CheckUnwindMaps(maps, map_set)); 87 } 88