| 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 <set> |
| 21 |
| 20 #include "base/basictypes.h" | 22 #include "base/basictypes.h" |
| 21 #include "base/mac/scoped_mach_port.h" | 23 #include "base/mac/scoped_mach_port.h" |
| 22 #include "gtest/gtest.h" | 24 #include "gtest/gtest.h" |
| 23 #include "util/file/fd_io.h" | 25 #include "util/file/fd_io.h" |
| 24 #include "util/mach/mach_extensions.h" | 26 #include "util/mach/mach_extensions.h" |
| 25 #include "util/test/mac/mach_errors.h" | 27 #include "util/test/mac/mach_errors.h" |
| 26 #include "util/test/mac/mach_multiprocess.h" | 28 #include "util/test/mac/mach_multiprocess.h" |
| 27 | 29 |
| 28 namespace crashpad { | 30 namespace crashpad { |
| 29 namespace test { | 31 namespace test { |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND, MACH_MSG_TYPE_MOVE_SEND) | | 217 MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND, MACH_MSG_TYPE_MOVE_SEND) | |
| 216 (options_.client_send_complex ? MACH_MSGH_BITS_COMPLEX : 0); | 218 (options_.client_send_complex ? MACH_MSGH_BITS_COMPLEX : 0); |
| 217 EXPECT_EQ(expect_msgh_bits, request->header.msgh_bits); | 219 EXPECT_EQ(expect_msgh_bits, request->header.msgh_bits); |
| 218 EXPECT_EQ(options_.client_send_large ? sizeof(LargeRequestMessage) : | 220 EXPECT_EQ(options_.client_send_large ? sizeof(LargeRequestMessage) : |
| 219 sizeof(RequestMessage), | 221 sizeof(RequestMessage), |
| 220 request->header.msgh_size); | 222 request->header.msgh_size); |
| 221 if (options_.client_reply_port_type == Options::kReplyPortNormal) { | 223 if (options_.client_reply_port_type == Options::kReplyPortNormal) { |
| 222 EXPECT_EQ(RemotePort(), request->header.msgh_remote_port); | 224 EXPECT_EQ(RemotePort(), request->header.msgh_remote_port); |
| 223 } | 225 } |
| 224 EXPECT_EQ(LocalPort(), request->header.msgh_local_port); | 226 EXPECT_EQ(LocalPort(), request->header.msgh_local_port); |
| 225 EXPECT_EQ(kRequestMessageId, request->header.msgh_id); | 227 EXPECT_EQ(kRequestMessageID, request->header.msgh_id); |
| 226 if (options_.client_send_complex) { | 228 if (options_.client_send_complex) { |
| 227 EXPECT_EQ(1u, request->body.msgh_descriptor_count); | 229 EXPECT_EQ(1u, request->body.msgh_descriptor_count); |
| 228 EXPECT_NE(kMachPortNull, request->port_descriptor.name); | 230 EXPECT_NE(kMachPortNull, request->port_descriptor.name); |
| 229 parent_complex_message_port_ = request->port_descriptor.name; | 231 parent_complex_message_port_ = request->port_descriptor.name; |
| 230 EXPECT_EQ(implicit_cast<mach_msg_type_name_t>(MACH_MSG_TYPE_MOVE_SEND), | 232 EXPECT_EQ(implicit_cast<mach_msg_type_name_t>(MACH_MSG_TYPE_MOVE_SEND), |
| 231 request->port_descriptor.disposition); | 233 request->port_descriptor.disposition); |
| 232 EXPECT_EQ( | 234 EXPECT_EQ( |
| 233 implicit_cast<mach_msg_descriptor_type_t>(MACH_MSG_PORT_DESCRIPTOR), | 235 implicit_cast<mach_msg_descriptor_type_t>(MACH_MSG_PORT_DESCRIPTOR), |
| 234 request->port_descriptor.type); | 236 request->port_descriptor.type); |
| 235 } else { | 237 } else { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 259 trailer->msgh_trailer_type); | 261 trailer->msgh_trailer_type); |
| 260 EXPECT_EQ(MACH_MSG_TRAILER_MINIMUM_SIZE, trailer->msgh_trailer_size); | 262 EXPECT_EQ(MACH_MSG_TRAILER_MINIMUM_SIZE, trailer->msgh_trailer_size); |
| 261 | 263 |
| 262 ++requests_; | 264 ++requests_; |
| 263 | 265 |
| 264 ReplyMessage* reply = reinterpret_cast<ReplyMessage*>(out); | 266 ReplyMessage* reply = reinterpret_cast<ReplyMessage*>(out); |
| 265 reply->Head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0); | 267 reply->Head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0); |
| 266 reply->Head.msgh_size = sizeof(*reply); | 268 reply->Head.msgh_size = sizeof(*reply); |
| 267 reply->Head.msgh_remote_port = request->header.msgh_remote_port; | 269 reply->Head.msgh_remote_port = request->header.msgh_remote_port; |
| 268 reply->Head.msgh_local_port = MACH_PORT_NULL; | 270 reply->Head.msgh_local_port = MACH_PORT_NULL; |
| 269 reply->Head.msgh_id = kReplyMessageId; | 271 reply->Head.msgh_id = kReplyMessageID; |
| 270 reply->NDR = NDR_record; | 272 reply->NDR = NDR_record; |
| 271 reply->RetCode = options_.server_mig_retcode; | 273 reply->RetCode = options_.server_mig_retcode; |
| 272 reply->number = replies_++; | 274 reply->number = replies_++; |
| 273 | 275 |
| 274 return true; | 276 return true; |
| 275 } | 277 } |
| 276 | 278 |
| 279 std::set<mach_msg_id_t> MachMessageServerRequestIDs() override { |
| 280 const mach_msg_id_t request_ids[] = {kRequestMessageID}; |
| 281 return std::set<mach_msg_id_t>( |
| 282 &request_ids[0], &request_ids[arraysize(request_ids)]); |
| 283 } |
| 284 |
| 277 mach_msg_size_t MachMessageServerRequestSize() override { | 285 mach_msg_size_t MachMessageServerRequestSize() override { |
| 278 return sizeof(RequestMessage); | 286 return sizeof(RequestMessage); |
| 279 } | 287 } |
| 280 | 288 |
| 281 mach_msg_size_t MachMessageServerReplySize() override { | 289 mach_msg_size_t MachMessageServerReplySize() override { |
| 282 return sizeof(ReplyMessage); | 290 return sizeof(ReplyMessage); |
| 283 } | 291 } |
| 284 | 292 |
| 285 private: | 293 private: |
| 286 struct RequestMessage : public mach_msg_base_t { | 294 struct RequestMessage : public mach_msg_base_t { |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 // looks at the right, it will have become a dead name. | 470 // looks at the right, it will have become a dead name. |
| 463 kr = mach_port_allocate(mach_task_self(), | 471 kr = mach_port_allocate(mach_task_self(), |
| 464 MACH_PORT_RIGHT_RECEIVE, | 472 MACH_PORT_RIGHT_RECEIVE, |
| 465 &request.header.msgh_local_port); | 473 &request.header.msgh_local_port); |
| 466 ASSERT_EQ(KERN_SUCCESS, kr) | 474 ASSERT_EQ(KERN_SUCCESS, kr) |
| 467 << MachErrorMessage(kr, "mach_port_allocate"); | 475 << MachErrorMessage(kr, "mach_port_allocate"); |
| 468 local_receive_port_owner.reset(request.header.msgh_local_port); | 476 local_receive_port_owner.reset(request.header.msgh_local_port); |
| 469 break; | 477 break; |
| 470 } | 478 } |
| 471 } | 479 } |
| 472 request.header.msgh_id = kRequestMessageId; | 480 request.header.msgh_id = kRequestMessageID; |
| 473 if (options_.client_send_complex) { | 481 if (options_.client_send_complex) { |
| 474 // Allocate a new receive right in this process and make a send right that | 482 // Allocate a new receive right in this process and make a send right that |
| 475 // will appear in the parent process. This is used to test that the server | 483 // will appear in the parent process. This is used to test that the server |
| 476 // properly handles ownership of resources received in complex messages. | 484 // properly handles ownership of resources received in complex messages. |
| 477 request.body.msgh_descriptor_count = 1; | 485 request.body.msgh_descriptor_count = 1; |
| 478 kr = mach_port_allocate(mach_task_self(), | 486 kr = mach_port_allocate(mach_task_self(), |
| 479 MACH_PORT_RIGHT_RECEIVE, | 487 MACH_PORT_RIGHT_RECEIVE, |
| 480 &request.port_descriptor.name); | 488 &request.port_descriptor.name); |
| 481 ASSERT_EQ(KERN_SUCCESS, kr) | 489 ASSERT_EQ(KERN_SUCCESS, kr) |
| 482 << MachErrorMessage(kr, "mach_port_allocate"); | 490 << MachErrorMessage(kr, "mach_port_allocate"); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 LocalPort(), | 535 LocalPort(), |
| 528 MACH_MSG_TIMEOUT_NONE, | 536 MACH_MSG_TIMEOUT_NONE, |
| 529 MACH_PORT_NULL); | 537 MACH_PORT_NULL); |
| 530 ASSERT_EQ(MACH_MSG_SUCCESS, kr) << MachErrorMessage(kr, "mach_msg"); | 538 ASSERT_EQ(MACH_MSG_SUCCESS, kr) << MachErrorMessage(kr, "mach_msg"); |
| 531 | 539 |
| 532 ASSERT_EQ(implicit_cast<mach_msg_bits_t>( | 540 ASSERT_EQ(implicit_cast<mach_msg_bits_t>( |
| 533 MACH_MSGH_BITS(0, MACH_MSG_TYPE_MOVE_SEND)), reply.Head.msgh_bits); | 541 MACH_MSGH_BITS(0, MACH_MSG_TYPE_MOVE_SEND)), reply.Head.msgh_bits); |
| 534 ASSERT_EQ(sizeof(ReplyMessage), reply.Head.msgh_size); | 542 ASSERT_EQ(sizeof(ReplyMessage), reply.Head.msgh_size); |
| 535 ASSERT_EQ(kMachPortNull, reply.Head.msgh_remote_port); | 543 ASSERT_EQ(kMachPortNull, reply.Head.msgh_remote_port); |
| 536 ASSERT_EQ(LocalPort(), reply.Head.msgh_local_port); | 544 ASSERT_EQ(LocalPort(), reply.Head.msgh_local_port); |
| 537 ASSERT_EQ(kReplyMessageId, reply.Head.msgh_id); | 545 ASSERT_EQ(kReplyMessageID, reply.Head.msgh_id); |
| 538 ASSERT_EQ(0, memcmp(&reply.NDR, &NDR_record, sizeof(NDR_record))); | 546 ASSERT_EQ(0, memcmp(&reply.NDR, &NDR_record, sizeof(NDR_record))); |
| 539 ASSERT_EQ(options_.server_mig_retcode, reply.RetCode); | 547 ASSERT_EQ(options_.server_mig_retcode, reply.RetCode); |
| 540 ASSERT_EQ(replies_, reply.number); | 548 ASSERT_EQ(replies_, reply.number); |
| 541 ASSERT_EQ(implicit_cast<mach_msg_trailer_type_t>(MACH_MSG_TRAILER_FORMAT_0), | 549 ASSERT_EQ(implicit_cast<mach_msg_trailer_type_t>(MACH_MSG_TRAILER_FORMAT_0), |
| 542 reply.trailer.msgh_trailer_type); | 550 reply.trailer.msgh_trailer_type); |
| 543 ASSERT_EQ(MACH_MSG_TRAILER_MINIMUM_SIZE, reply.trailer.msgh_trailer_size); | 551 ASSERT_EQ(MACH_MSG_TRAILER_MINIMUM_SIZE, reply.trailer.msgh_trailer_size); |
| 544 | 552 |
| 545 ++replies_; | 553 ++replies_; |
| 546 } | 554 } |
| 547 | 555 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 577 base::mac::ScopedMachReceiveRight child_complex_message_port_; | 585 base::mac::ScopedMachReceiveRight child_complex_message_port_; |
| 578 | 586 |
| 579 // The send right received in the parent process. This right is stored in a | 587 // The send right received in the parent process. This right is stored in a |
| 580 // member variable to test that resources carried in complex messages are | 588 // member variable to test that resources carried in complex messages are |
| 581 // properly destroyed in the server when expected. | 589 // properly destroyed in the server when expected. |
| 582 mach_port_t parent_complex_message_port_; | 590 mach_port_t parent_complex_message_port_; |
| 583 | 591 |
| 584 static uint32_t requests_; | 592 static uint32_t requests_; |
| 585 static uint32_t replies_; | 593 static uint32_t replies_; |
| 586 | 594 |
| 587 static const mach_msg_id_t kRequestMessageId = 16237; | 595 static const mach_msg_id_t kRequestMessageID = 16237; |
| 588 static const mach_msg_id_t kReplyMessageId = kRequestMessageId + 100; | 596 static const mach_msg_id_t kReplyMessageID = kRequestMessageID + 100; |
| 589 | 597 |
| 590 DISALLOW_COPY_AND_ASSIGN(TestMachMessageServer); | 598 DISALLOW_COPY_AND_ASSIGN(TestMachMessageServer); |
| 591 }; | 599 }; |
| 592 | 600 |
| 593 uint32_t TestMachMessageServer::requests_; | 601 uint32_t TestMachMessageServer::requests_; |
| 594 uint32_t TestMachMessageServer::replies_; | 602 uint32_t TestMachMessageServer::replies_; |
| 595 const mach_msg_id_t TestMachMessageServer::kRequestMessageId; | 603 const mach_msg_id_t TestMachMessageServer::kRequestMessageID; |
| 596 const mach_msg_id_t TestMachMessageServer::kReplyMessageId; | 604 const mach_msg_id_t TestMachMessageServer::kReplyMessageID; |
| 597 | 605 |
| 598 TEST(MachMessageServer, Basic) { | 606 TEST(MachMessageServer, Basic) { |
| 599 // The client sends one message to the server, which will wait indefinitely in | 607 // The client sends one message to the server, which will wait indefinitely in |
| 600 // blocking mode for it. | 608 // blocking mode for it. |
| 601 TestMachMessageServer::Options options; | 609 TestMachMessageServer::Options options; |
| 602 TestMachMessageServer test_mach_message_server(options); | 610 TestMachMessageServer test_mach_message_server(options); |
| 603 test_mach_message_server.Test(); | 611 test_mach_message_server.Test(); |
| 604 } | 612 } |
| 605 | 613 |
| 606 TEST(MachMessageServer, NonblockingNoMessage) { | 614 TEST(MachMessageServer, NonblockingNoMessage) { |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 845 options.expect_server_transaction_count = 0; | 853 options.expect_server_transaction_count = 0; |
| 846 options.client_send_large = true; | 854 options.client_send_large = true; |
| 847 options.client_expect_reply = false; | 855 options.client_expect_reply = false; |
| 848 TestMachMessageServer test_mach_message_server(options); | 856 TestMachMessageServer test_mach_message_server(options); |
| 849 test_mach_message_server.Test(); | 857 test_mach_message_server.Test(); |
| 850 } | 858 } |
| 851 | 859 |
| 852 } // namespace | 860 } // namespace |
| 853 } // namespace test | 861 } // namespace test |
| 854 } // namespace crashpad | 862 } // namespace crashpad |
| OLD | NEW |