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

Side by Side Diff: test/mac/mach_multiprocess.cc

Issue 1383283003: Add and use scoped-right-returning wrappers for Mach bootstrap routines (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Self-review Created 5 years, 2 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
« no previous file with comments | « no previous file | tools/mac/catch_exception_tool.cc » ('j') | util/mach/mach_extensions.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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,
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 "test/mac/mach_multiprocess.h" 15 #include "test/mac/mach_multiprocess.h"
16 16
17 #include <AvailabilityMacros.h> 17 #include <AvailabilityMacros.h>
18 #include <bsm/libbsm.h> 18 #include <bsm/libbsm.h>
19 #include <servers/bootstrap.h>
20 19
21 #include <string> 20 #include <string>
22 21
23 #include "base/auto_reset.h" 22 #include "base/auto_reset.h"
24 #include "base/logging.h" 23 #include "base/logging.h"
25 #include "base/mac/scoped_mach_port.h" 24 #include "base/mac/scoped_mach_port.h"
26 #include "base/memory/scoped_ptr.h" 25 #include "base/memory/scoped_ptr.h"
27 #include "base/rand_util.h" 26 #include "base/rand_util.h"
28 #include "gtest/gtest.h" 27 #include "gtest/gtest.h"
29 #include "test/errors.h" 28 #include "test/errors.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 ASSERT_NO_FATAL_FAILURE(Multiprocess::PreFork()); 90 ASSERT_NO_FATAL_FAILURE(Multiprocess::PreFork());
92 91
93 // Set up the parent port and register it with the bootstrap server before 92 // Set up the parent port and register it with the bootstrap server before
94 // forking, so that it’s guaranteed to be there when the child attempts to 93 // forking, so that it’s guaranteed to be there when the child attempts to
95 // look it up. 94 // look it up.
96 info_->service_name = "com.googlecode.crashpad.test.mach_multiprocess."; 95 info_->service_name = "com.googlecode.crashpad.test.mach_multiprocess.";
97 for (int index = 0; index < 16; ++index) { 96 for (int index = 0; index < 16; ++index) {
98 info_->service_name.append(1, base::RandInt('A', 'Z')); 97 info_->service_name.append(1, base::RandInt('A', 'Z'));
99 } 98 }
100 99
101 mach_port_t local_port; 100 info_->local_port = BootstrapCheckIn(info_->service_name);
102 kern_return_t kr = bootstrap_check_in(bootstrap_port, 101 ASSERT_NE(kMachPortNull, info_->local_port);
103 info_->service_name.c_str(),
104 &local_port);
105 ASSERT_EQ(BOOTSTRAP_SUCCESS, kr)
106 << BootstrapErrorMessage(kr, "bootstrap_check_in");
107 info_->local_port.reset(local_port);
108 } 102 }
109 103
110 mach_port_t MachMultiprocess::LocalPort() const { 104 mach_port_t MachMultiprocess::LocalPort() const {
111 EXPECT_NE(kMachPortNull, info_->local_port); 105 EXPECT_NE(kMachPortNull, info_->local_port);
112 return info_->local_port; 106 return info_->local_port;
113 } 107 }
114 108
115 mach_port_t MachMultiprocess::RemotePort() const { 109 mach_port_t MachMultiprocess::RemotePort() const {
116 EXPECT_NE(kMachPortNull, info_->remote_port); 110 EXPECT_NE(kMachPortNull, info_->remote_port);
117 return info_->remote_port; 111 return info_->remote_port;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 void MachMultiprocess::MultiprocessChild() { 211 void MachMultiprocess::MultiprocessChild() {
218 ScopedForbidReturn forbid_return;; 212 ScopedForbidReturn forbid_return;;
219 213
220 // local_port is not valid in the forked child process. 214 // local_port is not valid in the forked child process.
221 ignore_result(info_->local_port.release()); 215 ignore_result(info_->local_port.release());
222 216
223 info_->local_port.reset(NewMachPort(MACH_PORT_RIGHT_RECEIVE)); 217 info_->local_port.reset(NewMachPort(MACH_PORT_RIGHT_RECEIVE));
224 ASSERT_NE(kMachPortNull, info_->local_port); 218 ASSERT_NE(kMachPortNull, info_->local_port);
225 219
226 // The remote port can be obtained from the bootstrap server. 220 // The remote port can be obtained from the bootstrap server.
227 mach_port_t remote_port; 221 info_->remote_port = BootstrapLookUp(info_->service_name);
228 kern_return_t kr = bootstrap_look_up( 222 ASSERT_NE(kMachPortNull, info_->remote_port);
229 bootstrap_port, info_->service_name.c_str(), &remote_port);
230 ASSERT_EQ(BOOTSTRAP_SUCCESS, kr)
231 << BootstrapErrorMessage(kr, "bootstrap_look_up");
232 info_->remote_port.reset(remote_port);
233 223
234 // The “hello” message will provide the parent with its remote port, a send 224 // The “hello” message will provide the parent with its remote port, a send
235 // right to the child task’s local port receive right. It will also carry a 225 // right to the child task’s local port receive right. It will also carry a
236 // send right to the child task’s task port. 226 // send right to the child task’s task port.
237 SendHelloMessage message = {}; 227 SendHelloMessage message = {};
238 message.header.msgh_bits = 228 message.header.msgh_bits =
239 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND) | 229 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND) |
240 MACH_MSGH_BITS_COMPLEX; 230 MACH_MSGH_BITS_COMPLEX;
241 message.header.msgh_size = sizeof(message); 231 message.header.msgh_size = sizeof(message);
242 message.header.msgh_remote_port = info_->remote_port; 232 message.header.msgh_remote_port = info_->remote_port;
243 message.header.msgh_local_port = info_->local_port; 233 message.header.msgh_local_port = info_->local_port;
244 message.body.msgh_descriptor_count = 1; 234 message.body.msgh_descriptor_count = 1;
245 message.port_descriptor.name = mach_task_self(); 235 message.port_descriptor.name = mach_task_self();
246 message.port_descriptor.disposition = MACH_MSG_TYPE_COPY_SEND; 236 message.port_descriptor.disposition = MACH_MSG_TYPE_COPY_SEND;
247 message.port_descriptor.type = MACH_MSG_PORT_DESCRIPTOR; 237 message.port_descriptor.type = MACH_MSG_PORT_DESCRIPTOR;
248 238
249 kr = mach_msg(&message.header, 239 kern_return_t kr = mach_msg(&message.header,
250 MACH_SEND_MSG, 240 MACH_SEND_MSG,
251 message.header.msgh_size, 241 message.header.msgh_size,
252 0, 242 0,
253 MACH_PORT_NULL, 243 MACH_PORT_NULL,
254 MACH_MSG_TIMEOUT_NONE, 244 MACH_MSG_TIMEOUT_NONE,
255 MACH_PORT_NULL); 245 MACH_PORT_NULL);
256 ASSERT_EQ(MACH_MSG_SUCCESS, kr) << MachErrorMessage(kr, "mach_msg"); 246 ASSERT_EQ(MACH_MSG_SUCCESS, kr) << MachErrorMessage(kr, "mach_msg");
257 247
258 MachMultiprocessChild(); 248 MachMultiprocessChild();
259 249
260 info_->remote_port.reset(); 250 info_->remote_port.reset();
261 info_->local_port.reset(); 251 info_->local_port.reset();
262 252
263 // Close the write pipe now, for cases where the parent is waiting on it to 253 // Close the write pipe now, for cases where the parent is waiting on it to
264 // be closed as an indication that the child has finished. 254 // be closed as an indication that the child has finished.
265 CloseWritePipe(); 255 CloseWritePipe();
266 256
267 // Wait for the parent process to close its end of the pipe. The child process 257 // Wait for the parent process to close its end of the pipe. The child process
268 // needs to remain alive until then because the parent process will attempt to 258 // needs to remain alive until then because the parent process will attempt to
269 // verify it using the task port it has access to via ChildTask(). 259 // verify it using the task port it has access to via ChildTask().
270 CheckedReadFileAtEOF(ReadPipeHandle()); 260 CheckedReadFileAtEOF(ReadPipeHandle());
271 261
272 if (testing::Test::HasFailure()) { 262 if (testing::Test::HasFailure()) {
273 // Trigger the ScopedForbidReturn destructor. 263 // Trigger the ScopedForbidReturn destructor.
274 return; 264 return;
275 } 265 }
276 266
277 forbid_return.Disarm(); 267 forbid_return.Disarm();
278 } 268 }
279 269
280 } // namespace test 270 } // namespace test
281 } // namespace crashpad 271 } // namespace crashpad
OLDNEW
« no previous file with comments | « no previous file | tools/mac/catch_exception_tool.cc » ('j') | util/mach/mach_extensions.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698