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 |