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 |