| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Crashpad Authors. All rights reserved. | |
| 2 // | |
| 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 #include "util/mac/process_types.h" | |
| 16 | |
| 17 #include <AvailabilityMacros.h> | |
| 18 #include <mach/mach.h> | |
| 19 #include <string.h> | |
| 20 | |
| 21 #include <vector> | |
| 22 | |
| 23 #include "base/strings/stringprintf.h" | |
| 24 #include "gtest/gtest.h" | |
| 25 #include "util/mac/mac_util.h" | |
| 26 #include "util/test/mac/dyld.h" | |
| 27 | |
| 28 namespace crashpad { | |
| 29 namespace test { | |
| 30 namespace { | |
| 31 | |
| 32 #define TEST_STRING(process_reader, self_view, proctype_view, field) \ | |
| 33 do { \ | |
| 34 if (self_view->field) { \ | |
| 35 std::string proctype_string; \ | |
| 36 ASSERT_TRUE(process_reader.Memory()->ReadCString(proctype_view.field, \ | |
| 37 &proctype_string)); \ | |
| 38 EXPECT_EQ(self_view->field, proctype_string); \ | |
| 39 } \ | |
| 40 } while (false) | |
| 41 | |
| 42 TEST(ProcessTypes, DyldImagesSelf) { | |
| 43 // Get the in-process view of dyld_all_image_infos, and check it for sanity. | |
| 44 const struct dyld_all_image_infos* self_image_infos = | |
| 45 _dyld_get_all_image_infos(); | |
| 46 int mac_os_x_minor_version = MacOSXMinorVersion(); | |
| 47 if (mac_os_x_minor_version >= 9) { | |
| 48 EXPECT_GE(self_image_infos->version, 13u); | |
| 49 } else if (mac_os_x_minor_version >= 7) { | |
| 50 EXPECT_GE(self_image_infos->version, 8u); | |
| 51 } else if (mac_os_x_minor_version >= 6) { | |
| 52 EXPECT_GE(self_image_infos->version, 2u); | |
| 53 } else { | |
| 54 EXPECT_GE(self_image_infos->version, 1u); | |
| 55 } | |
| 56 | |
| 57 EXPECT_GT(self_image_infos->infoArrayCount, 1u); | |
| 58 if (self_image_infos->version >= 2) { | |
| 59 EXPECT_TRUE(self_image_infos->libSystemInitialized); | |
| 60 } | |
| 61 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 | |
| 62 if (self_image_infos->version >= 9) { | |
| 63 EXPECT_EQ(self_image_infos, self_image_infos->dyldAllImageInfosAddress); | |
| 64 } | |
| 65 #endif | |
| 66 | |
| 67 // Get the out-of-process view of dyld_all_image_infos, and work with it | |
| 68 // through the process_types interface. | |
| 69 task_dyld_info_data_t dyld_info; | |
| 70 mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; | |
| 71 kern_return_t kr = task_info(mach_task_self(), | |
| 72 TASK_DYLD_INFO, | |
| 73 reinterpret_cast<task_info_t>(&dyld_info), | |
| 74 &count); | |
| 75 ASSERT_EQ(KERN_SUCCESS, kr); | |
| 76 | |
| 77 EXPECT_EQ(reinterpret_cast<mach_vm_address_t>(self_image_infos), | |
| 78 dyld_info.all_image_info_addr); | |
| 79 EXPECT_GT(dyld_info.all_image_info_size, 1u); | |
| 80 | |
| 81 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 | |
| 82 #if !defined(ARCH_CPU_64_BITS) | |
| 83 EXPECT_EQ(TASK_DYLD_ALL_IMAGE_INFO_32, dyld_info.all_image_info_format); | |
| 84 #else | |
| 85 EXPECT_EQ(TASK_DYLD_ALL_IMAGE_INFO_64, dyld_info.all_image_info_format); | |
| 86 #endif | |
| 87 #endif | |
| 88 | |
| 89 ProcessReader process_reader; | |
| 90 ASSERT_TRUE(process_reader.Initialize(mach_task_self())); | |
| 91 | |
| 92 process_types::dyld_all_image_infos proctype_image_infos; | |
| 93 ASSERT_TRUE(proctype_image_infos.Read(&process_reader, | |
| 94 dyld_info.all_image_info_addr)); | |
| 95 | |
| 96 ASSERT_EQ(self_image_infos->version, proctype_image_infos.version); | |
| 97 | |
| 98 if (proctype_image_infos.version >= 1) { | |
| 99 EXPECT_EQ(self_image_infos->infoArrayCount, | |
| 100 proctype_image_infos.infoArrayCount); | |
| 101 EXPECT_EQ(reinterpret_cast<uint64_t>(self_image_infos->infoArray), | |
| 102 proctype_image_infos.infoArray); | |
| 103 EXPECT_EQ(reinterpret_cast<uint64_t>(self_image_infos->notification), | |
| 104 proctype_image_infos.notification); | |
| 105 EXPECT_EQ(self_image_infos->processDetachedFromSharedRegion, | |
| 106 proctype_image_infos.processDetachedFromSharedRegion); | |
| 107 } | |
| 108 if (proctype_image_infos.version >= 2) { | |
| 109 EXPECT_EQ(self_image_infos->libSystemInitialized, | |
| 110 proctype_image_infos.libSystemInitialized); | |
| 111 EXPECT_EQ( | |
| 112 reinterpret_cast<uint64_t>(self_image_infos->dyldImageLoadAddress), | |
| 113 proctype_image_infos.dyldImageLoadAddress); | |
| 114 } | |
| 115 if (proctype_image_infos.version >= 3) { | |
| 116 EXPECT_EQ(reinterpret_cast<uint64_t>(self_image_infos->jitInfo), | |
| 117 proctype_image_infos.jitInfo); | |
| 118 } | |
| 119 if (proctype_image_infos.version >= 5) { | |
| 120 EXPECT_EQ(reinterpret_cast<uint64_t>(self_image_infos->dyldVersion), | |
| 121 proctype_image_infos.dyldVersion); | |
| 122 EXPECT_EQ(reinterpret_cast<uint64_t>(self_image_infos->errorMessage), | |
| 123 proctype_image_infos.errorMessage); | |
| 124 EXPECT_EQ(static_cast<uint64_t>(self_image_infos->terminationFlags), | |
| 125 proctype_image_infos.terminationFlags); | |
| 126 | |
| 127 TEST_STRING( | |
| 128 process_reader, self_image_infos, proctype_image_infos, dyldVersion); | |
| 129 TEST_STRING( | |
| 130 process_reader, self_image_infos, proctype_image_infos, errorMessage); | |
| 131 } | |
| 132 if (proctype_image_infos.version >= 6) { | |
| 133 EXPECT_EQ( | |
| 134 reinterpret_cast<uint64_t>(self_image_infos->coreSymbolicationShmPage), | |
| 135 proctype_image_infos.coreSymbolicationShmPage); | |
| 136 } | |
| 137 if (proctype_image_infos.version >= 7) { | |
| 138 EXPECT_EQ(static_cast<uint64_t>(self_image_infos->systemOrderFlag), | |
| 139 proctype_image_infos.systemOrderFlag); | |
| 140 } | |
| 141 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 | |
| 142 if (proctype_image_infos.version >= 8) { | |
| 143 EXPECT_EQ(static_cast<uint64_t>(self_image_infos->uuidArrayCount), | |
| 144 proctype_image_infos.uuidArrayCount); | |
| 145 } | |
| 146 if (proctype_image_infos.version >= 9) { | |
| 147 EXPECT_EQ( | |
| 148 reinterpret_cast<uint64_t>(self_image_infos->dyldAllImageInfosAddress), | |
| 149 proctype_image_infos.dyldAllImageInfosAddress); | |
| 150 } | |
| 151 if (proctype_image_infos.version >= 10) { | |
| 152 EXPECT_EQ(static_cast<uint64_t>(self_image_infos->initialImageCount), | |
| 153 proctype_image_infos.initialImageCount); | |
| 154 } | |
| 155 if (proctype_image_infos.version >= 11) { | |
| 156 EXPECT_EQ(static_cast<uint64_t>(self_image_infos->errorKind), | |
| 157 proctype_image_infos.errorKind); | |
| 158 EXPECT_EQ( | |
| 159 reinterpret_cast<uint64_t>(self_image_infos->errorClientOfDylibPath), | |
| 160 proctype_image_infos.errorClientOfDylibPath); | |
| 161 EXPECT_EQ( | |
| 162 reinterpret_cast<uint64_t>(self_image_infos->errorTargetDylibPath), | |
| 163 proctype_image_infos.errorTargetDylibPath); | |
| 164 EXPECT_EQ(reinterpret_cast<uint64_t>(self_image_infos->errorSymbol), | |
| 165 proctype_image_infos.errorSymbol); | |
| 166 | |
| 167 TEST_STRING(process_reader, | |
| 168 self_image_infos, | |
| 169 proctype_image_infos, | |
| 170 errorClientOfDylibPath); | |
| 171 TEST_STRING(process_reader, | |
| 172 self_image_infos, | |
| 173 proctype_image_infos, | |
| 174 errorTargetDylibPath); | |
| 175 TEST_STRING( | |
| 176 process_reader, self_image_infos, proctype_image_infos, errorSymbol); | |
| 177 } | |
| 178 if (proctype_image_infos.version >= 12) { | |
| 179 EXPECT_EQ(static_cast<uint64_t>(self_image_infos->sharedCacheSlide), | |
| 180 proctype_image_infos.sharedCacheSlide); | |
| 181 } | |
| 182 #endif | |
| 183 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9 | |
| 184 if (proctype_image_infos.version >= 13) { | |
| 185 EXPECT_EQ(0, | |
| 186 memcmp(self_image_infos->sharedCacheUUID, | |
| 187 proctype_image_infos.sharedCacheUUID, | |
| 188 sizeof(self_image_infos->sharedCacheUUID))); | |
| 189 } | |
| 190 if (proctype_image_infos.version >= 14) { | |
| 191 for (size_t index = 0; index < arraysize(self_image_infos->reserved); | |
| 192 ++index) { | |
| 193 EXPECT_EQ(static_cast<uint64_t>(self_image_infos->reserved[index]), | |
| 194 proctype_image_infos.reserved[index]) | |
| 195 << "index " << index; | |
| 196 } | |
| 197 } | |
| 198 #endif | |
| 199 | |
| 200 if (proctype_image_infos.version >= 1) { | |
| 201 std::vector<process_types::dyld_image_info> proctype_image_info_vector( | |
| 202 proctype_image_infos.infoArrayCount); | |
| 203 ASSERT_TRUE(process_types::dyld_image_info::ReadArrayInto( | |
| 204 &process_reader, | |
| 205 proctype_image_infos.infoArray, | |
| 206 proctype_image_info_vector.size(), | |
| 207 &proctype_image_info_vector[0])); | |
| 208 | |
| 209 for (size_t index = 0; index < proctype_image_infos.infoArrayCount; | |
| 210 ++index) { | |
| 211 const dyld_image_info* self_image_info = | |
| 212 &self_image_infos->infoArray[index]; | |
| 213 const process_types::dyld_image_info& proctype_image_info = | |
| 214 proctype_image_info_vector[index]; | |
| 215 | |
| 216 EXPECT_EQ(reinterpret_cast<uint64_t>(self_image_info->imageLoadAddress), | |
| 217 proctype_image_info.imageLoadAddress) | |
| 218 << "index " << index; | |
| 219 EXPECT_EQ(reinterpret_cast<uint64_t>(self_image_info->imageFilePath), | |
| 220 proctype_image_info.imageFilePath) | |
| 221 << "index " << index; | |
| 222 EXPECT_EQ(static_cast<uint64_t>(self_image_info->imageFileModDate), | |
| 223 proctype_image_info.imageFileModDate) | |
| 224 << "index " << index; | |
| 225 | |
| 226 TEST_STRING( | |
| 227 process_reader, self_image_info, proctype_image_info, imageFilePath); | |
| 228 } | |
| 229 } | |
| 230 | |
| 231 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 | |
| 232 if (proctype_image_infos.version >= 8) { | |
| 233 std::vector<process_types::dyld_uuid_info> proctype_uuid_info_vector( | |
| 234 proctype_image_infos.uuidArrayCount); | |
| 235 ASSERT_TRUE(process_types::dyld_uuid_info::ReadArrayInto( | |
| 236 &process_reader, | |
| 237 proctype_image_infos.uuidArray, | |
| 238 proctype_uuid_info_vector.size(), | |
| 239 &proctype_uuid_info_vector[0])); | |
| 240 | |
| 241 for (size_t index = 0; index < proctype_image_infos.uuidArrayCount; | |
| 242 ++index) { | |
| 243 const dyld_uuid_info* self_uuid_info = | |
| 244 &self_image_infos->uuidArray[index]; | |
| 245 const process_types::dyld_uuid_info& proctype_uuid_info = | |
| 246 proctype_uuid_info_vector[index]; | |
| 247 | |
| 248 EXPECT_EQ(reinterpret_cast<uint64_t>(self_uuid_info->imageLoadAddress), | |
| 249 proctype_uuid_info.imageLoadAddress) | |
| 250 << "index " << index; | |
| 251 EXPECT_EQ(0, | |
| 252 memcmp(self_uuid_info->imageUUID, | |
| 253 proctype_uuid_info.imageUUID, | |
| 254 sizeof(self_uuid_info->imageUUID))) | |
| 255 << "index " << index; | |
| 256 } | |
| 257 } | |
| 258 #endif | |
| 259 } | |
| 260 | |
| 261 } // namespace | |
| 262 } // namespace test | |
| 263 } // namespace crashpad | |
| OLD | NEW |