Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: snapshot/mac/mach_o_image_annotations_reader_test.cc

Issue 1277513003: Recognize crashreporter_annotations_t version 5 found on OS X 10.11 (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: ExpectedSizeForVersion(), ReadIntoVersioned() Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Crashpad Authors. All rights reserved. 1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with 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 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
(...skipping 29 matching lines...) Expand all
40 #include "util/mach/exc_server_variants.h" 40 #include "util/mach/exc_server_variants.h"
41 #include "util/mach/exception_ports.h" 41 #include "util/mach/exception_ports.h"
42 #include "util/mach/mach_extensions.h" 42 #include "util/mach/mach_extensions.h"
43 #include "util/mach/mach_message.h" 43 #include "util/mach/mach_message.h"
44 #include "util/mach/mach_message_server.h" 44 #include "util/mach/mach_message_server.h"
45 45
46 namespace crashpad { 46 namespace crashpad {
47 namespace test { 47 namespace test {
48 namespace { 48 namespace {
49 49
50 // \return The path to crashpad_snapshot_test_module_crashy_initializer.so
51 std::string ModuleWithCrashyInitializer() {
52 return Paths::Executable().value() + "_module_crashy_initializer.so";
53 }
54
50 //! \return The path to the crashpad_snapshot_test_no_op executable. 55 //! \return The path to the crashpad_snapshot_test_no_op executable.
51 base::FilePath NoOpExecutable() { 56 base::FilePath NoOpExecutable() {
52 return base::FilePath(Paths::Executable().value() + "_no_op"); 57 return base::FilePath(Paths::Executable().value() + "_no_op");
53 } 58 }
54 59
55 class TestMachOImageAnnotationsReader final 60 class TestMachOImageAnnotationsReader final
56 : public MachMultiprocess, 61 : public MachMultiprocess,
57 public UniversalMachExcServer::Interface { 62 public UniversalMachExcServer::Interface {
58 public: 63 public:
59 enum TestType { 64 enum TestType {
60 // Don’t crash, just test the CrashpadInfo interface. 65 // Don’t crash, just test the CrashpadInfo interface.
61 kDontCrash = 0, 66 kDontCrash = 0,
62 67
63 // The child process should crash by calling abort(). The parent verifies 68 // The child process should crash by calling abort(). The parent verifies
64 // that the system libraries set the expected annotations. 69 // that the system libraries set the expected annotations.
70 //
71 // This test verifies that the message field in crashreporter_annotations_t
72 // can be recovered. Either 10.10.2 Libc-1044.1.2/stdlib/FreeBSD/abort.c
73 // abort() or 10.10.2 Libc-1044.10.1/sys/_libc_fork_child.c
74 // _libc_fork_child() calls CRSetCrashLogMessage() to set the message field.
65 kCrashAbort, 75 kCrashAbort,
66 76
77 // The child process should crash at module initialization time, when dyld
78 // will have set an annotation matching the path of the module being
79 // initialized.
80 //
81 // This test exists to verify that the message2 field in
82 // crashreporter_annotations_t can be recovered. 10.10.2
83 // dyld-353.2.1/src/ImageLoaderMachO.cpp
84 // ImageLoaderMachO::doInitialization() calls CRSetCrashLogMessage2() to set
85 // the message2 field.
86 kCrashModuleInitialization,
87
67 // The child process should crash by setting DYLD_INSERT_LIBRARIES to 88 // The child process should crash by setting DYLD_INSERT_LIBRARIES to
68 // contain a nonexistent library. The parent verifies that dyld sets the 89 // contain a nonexistent library. The parent verifies that dyld sets the
69 // expected annotations. 90 // expected annotations.
70 kCrashDyld, 91 kCrashDyld,
71 }; 92 };
72 93
73 explicit TestMachOImageAnnotationsReader(TestType test_type) 94 explicit TestMachOImageAnnotationsReader(TestType test_type)
74 : MachMultiprocess(), 95 : MachMultiprocess(),
75 UniversalMachExcServer::Interface(), 96 UniversalMachExcServer::Interface(),
76 test_type_(test_type) { 97 test_type_(test_type) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 } 140 }
120 } 141 }
121 142
122 // Mac OS X 10.6 doesn’t have support for CrashReporter annotations 143 // Mac OS X 10.6 doesn’t have support for CrashReporter annotations
123 // (CrashReporterClient.h), so don’t look for any special annotations in 144 // (CrashReporterClient.h), so don’t look for any special annotations in
124 // that version. 145 // that version.
125 int mac_os_x_minor_version = MacOSXMinorVersion(); 146 int mac_os_x_minor_version = MacOSXMinorVersion();
126 if (mac_os_x_minor_version > 7) { 147 if (mac_os_x_minor_version > 7) {
127 EXPECT_GE(all_annotations_vector.size(), 1u); 148 EXPECT_GE(all_annotations_vector.size(), 1u);
128 149
129 const char* expected_annotation = nullptr; 150 std::string expected_annotation;
130 switch (test_type_) { 151 switch (test_type_) {
131 case kCrashAbort: 152 case kCrashAbort:
132 // The child process calls abort(), so the expected annotation 153 // The child process calls abort(), so the expected annotation
133 // reflects this, with a string set by 10.7.5 154 // reflects this, with a string set by 10.7.5
134 // Libc-763.13/stdlib/abort-fbsd.c abort(). This string is still 155 // Libc-763.13/stdlib/abort-fbsd.c abort(). This string is still
135 // present in 10.9.5 Libc-997.90.3/stdlib/FreeBSD/abort.c abort(), 156 // present in 10.9.5 Libc-997.90.3/stdlib/FreeBSD/abort.c abort(),
136 // but because abort() tests to see if a message is already set and 157 // but because abort() tests to see if a message is already set and
137 // something else in Libc will have set a message, this string is 158 // something else in Libc will have set a message, this string is
138 // not the expectation on 10.9 or higher. Instead, after fork(), the 159 // not the expectation on 10.9 or higher. Instead, after fork(), the
139 // child process has a message indicating that a fork() without 160 // child process has a message indicating that a fork() without
140 // exec() occurred. See 10.9.5 Libc-997.90.3/sys/_libc_fork_child.c 161 // exec() occurred. See 10.9.5 Libc-997.90.3/sys/_libc_fork_child.c
141 // _libc_fork_child(). 162 // _libc_fork_child().
142 expected_annotation = 163 expected_annotation =
143 mac_os_x_minor_version <= 8 164 mac_os_x_minor_version <= 8
144 ? "abort() called" 165 ? "abort() called"
145 : "crashed on child side of fork pre-exec"; 166 : "crashed on child side of fork pre-exec";
146 break; 167 break;
147 168
169 case kCrashModuleInitialization:
170 // This message is set by dyld-353.2.1/src/ImageLoaderMachO.cpp
171 // ImageLoaderMachO::doInitialization().
172 expected_annotation = ModuleWithCrashyInitializer();
173 break;
174
148 case kCrashDyld: 175 case kCrashDyld:
149 // This is independent of dyld’s error_string, which is tested 176 // This is independent of dyld’s error_string, which is tested
150 // below. 177 // below.
151 expected_annotation = "dyld: launch, loading dependent libraries"; 178 expected_annotation = "dyld: launch, loading dependent libraries";
152 break; 179 break;
153 180
154 default: 181 default:
155 ADD_FAILURE(); 182 ADD_FAILURE();
156 break; 183 break;
157 } 184 }
158 185
159 size_t expected_annotation_length = strlen(expected_annotation);
160 bool found = false; 186 bool found = false;
161 for (const std::string& annotation : all_annotations_vector) { 187 for (const std::string& annotation : all_annotations_vector) {
162 // Look for the expectation as a leading susbtring, because the actual 188 // Look for the expectation as a leading susbtring, because the actual
163 // string that dyld uses will have the contents of the 189 // string that dyld uses will have the contents of the
164 // DYLD_INSERT_LIBRARIES environment variable appended to it on Mac 190 // DYLD_INSERT_LIBRARIES environment variable appended to it on Mac
165 // OS X 10.10. 191 // OS X 10.10.
166 if (annotation.substr(0, expected_annotation_length) == 192 if (annotation.substr(0, expected_annotation.length()) ==
167 expected_annotation) { 193 expected_annotation) {
168 found = true; 194 found = true;
169 break; 195 break;
170 } 196 }
171 } 197 }
172 EXPECT_TRUE(found); 198 EXPECT_TRUE(found) << expected_annotation;
173 } 199 }
174 200
175 // dyld exposes its error_string at least as far back as Mac OS X 10.4. 201 // dyld exposes its error_string at least as far back as Mac OS X 10.4.
176 if (test_type_ == kCrashDyld) { 202 if (test_type_ == kCrashDyld) {
177 const char kExpectedAnnotation[] = "could not load inserted library"; 203 const char kExpectedAnnotation[] = "could not load inserted library";
178 size_t expected_annotation_length = strlen(kExpectedAnnotation); 204 size_t expected_annotation_length = strlen(kExpectedAnnotation);
179 bool found = false; 205 bool found = false;
180 for (const std::string& annotation : all_annotations_vector) { 206 for (const std::string& annotation : all_annotations_vector) {
181 // Look for the expectation as a leading substring, because the actual 207 // Look for the expectation as a leading substring, because the actual
182 // string will contain the library’s pathname and, on Mac OS X 10.9 208 // string will contain the library’s pathname and, on Mac OS X 10.9
183 // and later, a reason. 209 // and later, a reason.
184 if (annotation.substr(0, expected_annotation_length) == 210 if (annotation.substr(0, expected_annotation_length) ==
185 kExpectedAnnotation) { 211 kExpectedAnnotation) {
186 found = true; 212 found = true;
187 break; 213 break;
188 } 214 }
189 } 215 }
190 216
191 EXPECT_TRUE(found); 217 EXPECT_TRUE(found) << kExpectedAnnotation;
192 } 218 }
193 } 219 }
194 220
195 return ExcServerSuccessfulReturnValue(behavior, false); 221 return ExcServerSuccessfulReturnValue(behavior, false);
196 } 222 }
197 223
198 private: 224 private:
199 // MachMultiprocess: 225 // MachMultiprocess:
200 226
201 void MachMultiprocessParent() override { 227 void MachMultiprocessParent() override {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 MachMessageServer::kReceiveLargeError, 269 MachMessageServer::kReceiveLargeError,
244 kMachMessageTimeoutWaitIndefinitely); 270 kMachMessageTimeoutWaitIndefinitely);
245 EXPECT_EQ(MACH_MSG_SUCCESS, mr) 271 EXPECT_EQ(MACH_MSG_SUCCESS, mr)
246 << MachErrorMessage(mr, "MachMessageServer::Run"); 272 << MachErrorMessage(mr, "MachMessageServer::Run");
247 273
248 switch (test_type_) { 274 switch (test_type_) {
249 case kCrashAbort: 275 case kCrashAbort:
250 SetExpectedChildTermination(kTerminationSignal, SIGABRT); 276 SetExpectedChildTermination(kTerminationSignal, SIGABRT);
251 break; 277 break;
252 278
279 case kCrashModuleInitialization:
280 // This crash is triggered by __builtin_trap(), which shows up as
281 // SIGILL.
282 SetExpectedChildTermination(kTerminationSignal, SIGILL);
283 break;
284
253 case kCrashDyld: 285 case kCrashDyld:
254 // dyld fatal errors result in the execution of an int3 instruction on 286 // dyld fatal errors result in the execution of an int3 instruction on
255 // x86 and a trap instruction on ARM, both of which raise SIGTRAP. 287 // x86 and a trap instruction on ARM, both of which raise SIGTRAP.
256 // 10.9.5 dyld-239.4/src/dyldStartup.s _dyld_fatal_error. 288 // 10.9.5 dyld-239.4/src/dyldStartup.s _dyld_fatal_error.
257 SetExpectedChildTermination(kTerminationSignal, SIGTRAP); 289 SetExpectedChildTermination(kTerminationSignal, SIGTRAP);
258 break; 290 break;
259 291
260 default: 292 default:
261 FAIL(); 293 FAIL();
262 break; 294 break;
(...skipping 23 matching lines...) Expand all
286 CheckedReadFile(ReadPipeHandle(), &c, sizeof(c)); 318 CheckedReadFile(ReadPipeHandle(), &c, sizeof(c));
287 319
288 // Direct an exception message to the exception server running in the 320 // Direct an exception message to the exception server running in the
289 // parent. 321 // parent.
290 ExceptionPorts exception_ports(ExceptionPorts::kTargetTypeTask, 322 ExceptionPorts exception_ports(ExceptionPorts::kTargetTypeTask,
291 mach_task_self()); 323 mach_task_self());
292 ASSERT_TRUE(exception_ports.SetExceptionPort( 324 ASSERT_TRUE(exception_ports.SetExceptionPort(
293 EXC_MASK_CRASH, RemotePort(), EXCEPTION_DEFAULT, THREAD_STATE_NONE)); 325 EXC_MASK_CRASH, RemotePort(), EXCEPTION_DEFAULT, THREAD_STATE_NONE));
294 326
295 switch (test_type_) { 327 switch (test_type_) {
296 case kDontCrash: 328 case kDontCrash: {
297 break; 329 break;
330 }
298 331
299 case kCrashAbort: 332 case kCrashAbort: {
300 abort(); 333 abort();
301 break; 334 break;
335 }
336
337 case kCrashModuleInitialization: {
338 // Load a module that crashes while executing a module initializer.
339 void* dl_handle = dlopen(ModuleWithCrashyInitializer().c_str(),
340 RTLD_LAZY | RTLD_LOCAL);
341
342 // This should have crashed in the dlopen(). If dlopen() failed, the
343 // ASSERT_NE() will show the message. If it succeeded without crashing,
344 // the FAIL() will fail the test.
345 ASSERT_NE(nullptr, dl_handle) << dlerror();
346 FAIL();
347 break;
348 }
302 349
303 case kCrashDyld: { 350 case kCrashDyld: {
304 // Set DYLD_INSERT_LIBRARIES to contain a library that does not exist. 351 // Set DYLD_INSERT_LIBRARIES to contain a library that does not exist.
305 // Unable to load it, dyld will abort with a fatal error. 352 // Unable to load it, dyld will abort with a fatal error.
306 ASSERT_EQ( 353 ASSERT_EQ(
307 0, 354 0,
308 setenv( 355 setenv(
309 "DYLD_INSERT_LIBRARIES", "/var/empty/NoDirectory/NoLibrary", 1)) 356 "DYLD_INSERT_LIBRARIES", "/var/empty/NoDirectory/NoLibrary", 1))
310 << ErrnoMessage("setenv"); 357 << ErrnoMessage("setenv");
311 358
(...skipping 26 matching lines...) Expand all
338 TestMachOImageAnnotationsReader::kDontCrash); 385 TestMachOImageAnnotationsReader::kDontCrash);
339 test_mach_o_image_annotations_reader.Run(); 386 test_mach_o_image_annotations_reader.Run();
340 } 387 }
341 388
342 TEST(MachOImageAnnotationsReader, CrashAbort) { 389 TEST(MachOImageAnnotationsReader, CrashAbort) {
343 TestMachOImageAnnotationsReader test_mach_o_image_annotations_reader( 390 TestMachOImageAnnotationsReader test_mach_o_image_annotations_reader(
344 TestMachOImageAnnotationsReader::kCrashAbort); 391 TestMachOImageAnnotationsReader::kCrashAbort);
345 test_mach_o_image_annotations_reader.Run(); 392 test_mach_o_image_annotations_reader.Run();
346 } 393 }
347 394
395 TEST(MachOImageAnnotationsReader, CrashModuleInitialization) {
396 TestMachOImageAnnotationsReader test_mach_o_image_annotations_reader(
397 TestMachOImageAnnotationsReader::kCrashModuleInitialization);
398 test_mach_o_image_annotations_reader.Run();
399 }
400
348 TEST(MachOImageAnnotationsReader, CrashDyld) { 401 TEST(MachOImageAnnotationsReader, CrashDyld) {
349 TestMachOImageAnnotationsReader test_mach_o_image_annotations_reader( 402 TestMachOImageAnnotationsReader test_mach_o_image_annotations_reader(
350 TestMachOImageAnnotationsReader::kCrashDyld); 403 TestMachOImageAnnotationsReader::kCrashDyld);
351 test_mach_o_image_annotations_reader.Run(); 404 test_mach_o_image_annotations_reader.Run();
352 } 405 }
353 406
354 } // namespace 407 } // namespace
355 } // namespace test 408 } // namespace test
356 } // namespace crashpad 409 } // namespace crashpad
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698