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

Unified Diff: util/test/mac/mach_multiprocess.cc

Issue 506143002: Refactor MachMultiprocess (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Created 6 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « util/test/mac/mach_multiprocess.h ('k') | util/test/mac/mach_multiprocess_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: util/test/mac/mach_multiprocess.cc
diff --git a/util/test/mac/mach_multiprocess.cc b/util/test/mac/mach_multiprocess.cc
index c5e749cf48c2f7ef35797c15c27caa59e1ba8866..d78b86008559e05789c21b7456975723da31954f 100644
--- a/util/test/mac/mach_multiprocess.cc
+++ b/util/test/mac/mach_multiprocess.cc
@@ -17,35 +17,22 @@
#include <AvailabilityMacros.h>
#include <bsm/libbsm.h>
#include <servers/bootstrap.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <sys/wait.h>
#include <string>
#include "base/auto_reset.h"
-#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/mac/scoped_mach_port.h"
#include "base/memory/scoped_ptr.h"
#include "base/rand_util.h"
-#include "base/strings/stringprintf.h"
#include "gtest/gtest.h"
#include "util/mach/bootstrap.h"
+#include "util/misc/scoped_forbid_return.h"
#include "util/test/errors.h"
#include "util/test/mac/mach_errors.h"
namespace {
-class ScopedNotReached {
- public:
- ScopedNotReached() {}
- ~ScopedNotReached() { abort(); }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ScopedNotReached);
-};
-
// The “hello” message contains a send right to the child process’ task port.
struct SendHelloMessage : public mach_msg_base_t {
mach_msg_port_descriptor_t port_descriptor;
@@ -67,25 +54,11 @@ namespace internal {
struct MachMultiprocessInfo {
MachMultiprocessInfo()
: service_name(),
- pipe_c2p_read(-1),
- pipe_c2p_write(-1),
- pipe_p2c_read(-1),
- pipe_p2c_write(-1),
- child_pid(0),
- read_pipe_fd(-1),
- write_pipe_fd(-1),
local_port(MACH_PORT_NULL),
remote_port(MACH_PORT_NULL),
child_task(MACH_PORT_NULL) {}
std::string service_name;
- base::ScopedFD pipe_c2p_read; // child to parent
- base::ScopedFD pipe_c2p_write; // child to parent
- base::ScopedFD pipe_p2c_read; // parent to child
- base::ScopedFD pipe_p2c_write; // parent to child
- pid_t child_pid; // valid only in parent
- int read_pipe_fd; // pipe_c2p_read in parent, pipe_p2c_read in child
- int write_pipe_fd; // pipe_p2c_write in parent, pipe_c2p_write in child
base::mac::ScopedMachReceiveRight local_port;
base::mac::ScopedMachSendRight remote_port;
base::mac::ScopedMachSendRight child_task; // valid only in parent
@@ -93,7 +66,7 @@ struct MachMultiprocessInfo {
} // namespace internal
-MachMultiprocess::MachMultiprocess() : info_(NULL) {
+MachMultiprocess::MachMultiprocess() : Multiprocess(), info_(NULL) {
}
void MachMultiprocess::Run() {
@@ -103,19 +76,17 @@ void MachMultiprocess::Run() {
base::AutoReset<internal::MachMultiprocessInfo*> reset_info(&info_,
info.get());
- int pipe_fds_c2p[2];
- int rv = pipe(pipe_fds_c2p);
- ASSERT_EQ(0, rv) << ErrnoMessage("pipe");
-
- info_->pipe_c2p_read.reset(pipe_fds_c2p[0]);
- info_->pipe_c2p_write.reset(pipe_fds_c2p[1]);
+ return Multiprocess::Run();
+}
- int pipe_fds_p2c[2];
- rv = pipe(pipe_fds_p2c);
- ASSERT_EQ(0, rv) << ErrnoMessage("pipe");
+MachMultiprocess::~MachMultiprocess() {
+}
- info_->pipe_p2c_read.reset(pipe_fds_p2c[0]);
- info_->pipe_p2c_write.reset(pipe_fds_p2c[1]);
+void MachMultiprocess::PreFork() {
+ Multiprocess::PreFork();
+ if (testing::Test::HasFatalFailure()) {
+ return;
+ }
// Set up the parent port and register it with the bootstrap server before
// forking, so that it’s guaranteed to be there when the child attempts to
@@ -131,65 +102,6 @@ void MachMultiprocess::Run() {
ASSERT_EQ(BOOTSTRAP_SUCCESS, kr)
<< BootstrapErrorMessage(kr, "bootstrap_check_in");
info_->local_port.reset(local_port);
-
- pid_t pid = fork();
- ASSERT_GE(pid, 0) << ErrnoMessage("fork");
-
- if (pid > 0) {
- info_->child_pid = pid;
-
- RunParent();
-
- // Waiting for the child happens here instead of in RunParent() because even
- // if RunParent() returns early due to a gtest fatal assertion failure, the
- // child should still be reaped.
-
- // This will make the parent hang up on the child as much as would be
- // visible from the child’s perspective. The child’s side of the pipe will
- // be broken, the child’s remote port will become a dead name, and an
- // attempt by the child to look up the service will fail. If this weren’t
- // done, the child might hang while waiting for a parent that has already
- // triggered a fatal assertion failure to do something.
- info.reset();
- info_ = NULL;
-
- int status;
- pid_t wait_pid = waitpid(pid, &status, 0);
- ASSERT_EQ(pid, wait_pid) << ErrnoMessage("waitpid");
- if (status != 0) {
- std::string message;
- if (WIFEXITED(status)) {
- message = base::StringPrintf("Child exited with code %d",
- WEXITSTATUS(status));
- } else if (WIFSIGNALED(status)) {
- message = base::StringPrintf("Child terminated by signal %d (%s) %s",
- WTERMSIG(status),
- strsignal(WTERMSIG(status)),
- WCOREDUMP(status) ? " (core dumped)" : "");
- }
- ASSERT_EQ(0, status) << message;
- }
- } else {
- RunChild();
- }
-}
-
-MachMultiprocess::~MachMultiprocess() {
-}
-
-pid_t MachMultiprocess::ChildPID() const {
- EXPECT_NE(0, info_->child_pid);
- return info_->child_pid;
-}
-
-int MachMultiprocess::ReadPipeFD() const {
- EXPECT_NE(-1, info_->read_pipe_fd);
- return info_->read_pipe_fd;
-}
-
-int MachMultiprocess::WritePipeFD() const {
- EXPECT_NE(-1, info_->write_pipe_fd);
- return info_->write_pipe_fd;
}
mach_port_t MachMultiprocess::LocalPort() const {
@@ -207,13 +119,7 @@ mach_port_t MachMultiprocess::ChildTask() const {
return info_->child_task;
}
-void MachMultiprocess::RunParent() {
- // The parent uses the read end of c2p and the write end of p2c.
- info_->pipe_c2p_write.reset();
- info_->read_pipe_fd = info_->pipe_c2p_read.get();
- info_->pipe_p2c_read.reset();
- info_->write_pipe_fd = info_->pipe_p2c_write.get();
-
+void MachMultiprocess::MultiprocessParent() {
ReceiveHelloMessage message = {};
kern_return_t kr =
@@ -299,29 +205,18 @@ void MachMultiprocess::RunParent() {
ASSERT_EQ(KERN_SUCCESS, kr) << MachErrorMessage(kr, "pid_for_task");
ASSERT_EQ(ChildPID(), mach_pid);
- Parent();
+ MachMultiprocessParent();
info_->remote_port.reset();
info_->local_port.reset();
-
- info_->read_pipe_fd = -1;
- info_->pipe_c2p_read.reset();
- info_->write_pipe_fd = -1;
- info_->pipe_p2c_write.reset();
}
-void MachMultiprocess::RunChild() {
- ScopedNotReached must_not_leave_this_scope;
+void MachMultiprocess::MultiprocessChild() {
+ ScopedForbidReturn forbid_return;;
// local_port is not valid in the forked child process.
ignore_result(info_->local_port.release());
- // The child uses the write end of c2p and the read end of p2c.
- info_->pipe_c2p_read.reset();
- info_->write_pipe_fd = info_->pipe_c2p_write.get();
- info_->pipe_p2c_write.reset();
- info_->read_pipe_fd = info_->pipe_p2c_read.get();
-
mach_port_t local_port;
kern_return_t kr = mach_port_allocate(
mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &local_port);
@@ -360,22 +255,17 @@ void MachMultiprocess::RunChild() {
MACH_PORT_NULL);
ASSERT_EQ(MACH_MSG_SUCCESS, kr) << MachErrorMessage(kr, "mach_msg");
- Child();
+ MachMultiprocessChild();
info_->remote_port.reset();
info_->local_port.reset();
- info_->write_pipe_fd = -1;
- info_->pipe_c2p_write.reset();
- info_->read_pipe_fd = -1;
- info_->pipe_p2c_read.reset();
-
if (Test::HasFailure()) {
- // Trigger the ScopedNotReached destructor.
+ // Trigger the ScopedForbidReturn destructor.
return;
}
- exit(0);
+ forbid_return.Disarm();
}
} // namespace test
« no previous file with comments | « util/test/mac/mach_multiprocess.h ('k') | util/test/mac/mach_multiprocess_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698