OLD | NEW |
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, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 | 14 |
15 #include "util/mach/mach_message_server.h" | 15 #include "util/mach/mach_message_server.h" |
16 | 16 |
17 #include <mach/mach.h> | 17 #include <mach/mach.h> |
18 #include <string.h> | 18 #include <string.h> |
19 | 19 |
20 #include "base/basictypes.h" | 20 #include "base/basictypes.h" |
21 #include "base/mac/scoped_mach_port.h" | 21 #include "base/mac/scoped_mach_port.h" |
22 #include "gtest/gtest.h" | 22 #include "gtest/gtest.h" |
23 #include "util/file/fd_io.h" | 23 #include "util/file/fd_io.h" |
24 #include "util/mach/mach_extensions.h" | 24 #include "util/mach/mach_extensions.h" |
25 #include "util/test/errors.h" | |
26 #include "util/test/mac/mach_errors.h" | 25 #include "util/test/mac/mach_errors.h" |
27 #include "util/test/mac/mach_multiprocess.h" | 26 #include "util/test/mac/mach_multiprocess.h" |
28 | 27 |
29 namespace { | 28 namespace { |
30 | 29 |
31 using namespace crashpad; | 30 using namespace crashpad; |
32 using namespace crashpad::test; | 31 using namespace crashpad::test; |
33 | 32 |
34 class TestMachMessageServer : public MachMessageServer::Interface, | 33 class TestMachMessageServer : public MachMessageServer::Interface, |
35 public MachMultiprocess { | 34 public MachMultiprocess { |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 struct ReplyMessage : public mig_reply_error_t { | 293 struct ReplyMessage : public mig_reply_error_t { |
295 uint32_t number; | 294 uint32_t number; |
296 }; | 295 }; |
297 | 296 |
298 // MachMultiprocess: | 297 // MachMultiprocess: |
299 | 298 |
300 virtual void MachMultiprocessParent() override { | 299 virtual void MachMultiprocessParent() override { |
301 if (options_.parent_wait_for_child_pipe) { | 300 if (options_.parent_wait_for_child_pipe) { |
302 // Wait until the child is done sending what it’s going to send. | 301 // Wait until the child is done sending what it’s going to send. |
303 char c; | 302 char c; |
304 ssize_t rv = ReadFD(ReadPipeFD(), &c, 1); | 303 CheckedReadFD(ReadPipeFD(), &c, 1); |
305 EXPECT_EQ(1, rv) << ErrnoMessage("read"); | |
306 EXPECT_EQ('\0', c); | 304 EXPECT_EQ('\0', c); |
307 } | 305 } |
308 | 306 |
309 kern_return_t kr; | 307 kern_return_t kr; |
310 ASSERT_EQ(options_.expect_server_result, | 308 ASSERT_EQ(options_.expect_server_result, |
311 (kr = MachMessageServer::Run(this, | 309 (kr = MachMessageServer::Run(this, |
312 LocalPort(), | 310 LocalPort(), |
313 options_.server_options, | 311 options_.server_options, |
314 options_.server_persistent, | 312 options_.server_persistent, |
315 options_.server_nonblocking, | 313 options_.server_nonblocking, |
(...skipping 25 matching lines...) Expand all Loading... |
341 // this test environment. | 339 // this test environment. |
342 kr = mach_port_type( | 340 kr = mach_port_type( |
343 mach_task_self(), parent_complex_message_port_, &type); | 341 mach_task_self(), parent_complex_message_port_, &type); |
344 EXPECT_EQ(KERN_INVALID_NAME, kr) | 342 EXPECT_EQ(KERN_INVALID_NAME, kr) |
345 << MachErrorMessage(kr, "mach_port_type"); | 343 << MachErrorMessage(kr, "mach_port_type"); |
346 } | 344 } |
347 | 345 |
348 if (options_.child_wait_for_parent_pipe) { | 346 if (options_.child_wait_for_parent_pipe) { |
349 // Let the child know it’s safe to exit. | 347 // Let the child know it’s safe to exit. |
350 char c = '\0'; | 348 char c = '\0'; |
351 ssize_t rv = WriteFD(WritePipeFD(), &c, 1); | 349 CheckedWriteFD(WritePipeFD(), &c, 1); |
352 EXPECT_EQ(1, rv) << ErrnoMessage("write"); | |
353 } | 350 } |
354 } | 351 } |
355 | 352 |
356 virtual void MachMultiprocessChild() override { | 353 virtual void MachMultiprocessChild() override { |
357 for (size_t index = 0; | 354 for (size_t index = 0; |
358 index < options_.client_send_request_count; | 355 index < options_.client_send_request_count; |
359 ++index) { | 356 ++index) { |
360 if (options_.child_send_all_requests_before_receiving_any_replies) { | 357 if (options_.child_send_all_requests_before_receiving_any_replies) { |
361 // For this test, all of the messages need to go into the queue before | 358 // For this test, all of the messages need to go into the queue before |
362 // the parent is allowed to start processing them. Don’t attempt to | 359 // the parent is allowed to start processing them. Don’t attempt to |
(...skipping 23 matching lines...) Expand all Loading... |
386 ++index) { | 383 ++index) { |
387 ChildWaitForReply(); | 384 ChildWaitForReply(); |
388 if (testing::Test::HasFatalFailure()) { | 385 if (testing::Test::HasFatalFailure()) { |
389 return; | 386 return; |
390 } | 387 } |
391 } | 388 } |
392 } | 389 } |
393 | 390 |
394 if (options_.child_wait_for_parent_pipe) { | 391 if (options_.child_wait_for_parent_pipe) { |
395 char c; | 392 char c; |
396 ssize_t rv = ReadFD(ReadPipeFD(), &c, 1); | 393 CheckedReadFD(ReadPipeFD(), &c, 1); |
397 ASSERT_EQ(1, rv) << ErrnoMessage("read"); | |
398 ASSERT_EQ('\0', c); | 394 ASSERT_EQ('\0', c); |
399 } | 395 } |
400 } | 396 } |
401 | 397 |
402 // In the child process, sends a request message to the server. | 398 // In the child process, sends a request message to the server. |
403 void ChildSendRequest() { | 399 void ChildSendRequest() { |
404 // local_receive_port_owner will the receive right that is created in this | 400 // local_receive_port_owner will the receive right that is created in this |
405 // scope and intended to be destroyed when leaving this scope, after it has | 401 // scope and intended to be destroyed when leaving this scope, after it has |
406 // been carried in a Mach message. | 402 // been carried in a Mach message. |
407 base::mac::ScopedMachReceiveRight local_receive_port_owner; | 403 base::mac::ScopedMachReceiveRight local_receive_port_owner; |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 | 511 |
516 ++replies_; | 512 ++replies_; |
517 } | 513 } |
518 | 514 |
519 // For test types where the child needs to notify the server in the parent | 515 // For test types where the child needs to notify the server in the parent |
520 // that the child is ready, this method will send a byte via the POSIX pipe. | 516 // that the child is ready, this method will send a byte via the POSIX pipe. |
521 // The parent will be waiting in a read() on this pipe, and will proceed to | 517 // The parent will be waiting in a read() on this pipe, and will proceed to |
522 // running MachMessageServer() once it’s received. | 518 // running MachMessageServer() once it’s received. |
523 void ChildNotifyParentViaPipe() { | 519 void ChildNotifyParentViaPipe() { |
524 char c = '\0'; | 520 char c = '\0'; |
525 ssize_t rv = WriteFD(WritePipeFD(), &c, 1); | 521 CheckedWriteFD(WritePipeFD(), &c, 1); |
526 ASSERT_EQ(1, rv) << ErrnoMessage("write"); | |
527 } | 522 } |
528 | 523 |
529 // In the child process, sends a request message to the server and then | 524 // In the child process, sends a request message to the server and then |
530 // receives a reply message. | 525 // receives a reply message. |
531 void ChildSendRequestAndWaitForReply() { | 526 void ChildSendRequestAndWaitForReply() { |
532 ChildSendRequest(); | 527 ChildSendRequest(); |
533 if (testing::Test::HasFatalFailure()) { | 528 if (testing::Test::HasFatalFailure()) { |
534 return; | 529 return; |
535 } | 530 } |
536 | 531 |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 // so a new buffer is allocated to receive the message. The server receives | 794 // so a new buffer is allocated to receive the message. The server receives |
800 // the large request message, processes it, and returns a reply to the client. | 795 // the large request message, processes it, and returns a reply to the client. |
801 TestMachMessageServer::Options options; | 796 TestMachMessageServer::Options options; |
802 options.server_options = MACH_RCV_LARGE; | 797 options.server_options = MACH_RCV_LARGE; |
803 options.client_send_large = true; | 798 options.client_send_large = true; |
804 TestMachMessageServer test_mach_message_server(options); | 799 TestMachMessageServer test_mach_message_server(options); |
805 test_mach_message_server.Test(); | 800 test_mach_message_server.Test(); |
806 } | 801 } |
807 | 802 |
808 } // namespace | 803 } // namespace |
OLD | NEW |