| 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 |