mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 22:16:13 +00:00
mac: Add a mode to crashpad_handler to run from launchd
By invoking crashpad_handler with --mach-service instead of --handshake-fd, the handler will run as a well-behaved launchd job. The launchd job may be as a launch agent or launch daemon, or be submitted to launchd by on_demand_service_tool. BUG=crashpad:25 R=rsesek@chromium.org Review URL: https://codereview.chromium.org/1414533006 .
This commit is contained in:
parent
ee6fc23fb3
commit
809affe793
@ -42,10 +42,9 @@ class CrashpadClient {
|
||||
//! handshake to configure it.
|
||||
//!
|
||||
//! This method does not actually direct any crashes to the Crashpad handler,
|
||||
//! because there may be alternative ways to use an existing Crashpad handler
|
||||
//! without having to start one. To begin directing crashes to the handler,
|
||||
//! started by this method, call UseHandler() after this method returns
|
||||
//! successfully.
|
||||
//! because there are alternative ways to use an existing Crashpad handler. To
|
||||
//! begin directing crashes to the handler started by this method, call
|
||||
//! UseHandler() after this method returns successfully.
|
||||
//!
|
||||
//! On Mac OS X, this method starts a Crashpad handler and obtains a Mach
|
||||
//! send right corresponding to a receive right held by the handler process.
|
||||
@ -76,6 +75,37 @@ class CrashpadClient {
|
||||
const std::vector<std::string>& arguments,
|
||||
bool restartable);
|
||||
|
||||
#if defined(OS_MACOSX) || DOXYGEN
|
||||
//! \brief Sets the process’ crash handler to a Mach service registered with
|
||||
//! the bootstrap server.
|
||||
//!
|
||||
//! This method does not actually direct any crashes to the Crashpad handler,
|
||||
//! because there are alternative ways to start or use an existing Crashpad
|
||||
//! handler. To begin directing crashes to the handler set by this method,
|
||||
//! call UseHandler() after this method returns successfully.
|
||||
//!
|
||||
//! This method is only defined on OS X.
|
||||
//!
|
||||
//! \param[in] service_name The service name of a Crashpad exception handler
|
||||
//! service previously registered with the bootstrap server.
|
||||
//!
|
||||
//! \return `true` on success, `false` on failure with a message logged.
|
||||
bool SetHandlerMachService(const std::string& service_name);
|
||||
|
||||
//! \brief Sets the process’ crash handler to a Mach port.
|
||||
//!
|
||||
//! This method does not actually direct any crashes to the Crashpad handler,
|
||||
//! because there are alternative ways to start or use an existing Crashpad
|
||||
//! handler. To begin directing crashes to the handler set by this method,
|
||||
//! call UseHandler() after this method.
|
||||
//!
|
||||
//! This method is only defined on OS X.
|
||||
//!
|
||||
//! \param[in] exception_port An `exception_port_t` corresponding to a
|
||||
//! Crashpad exception handler service.
|
||||
void SetHandlerMachPort(base::mac::ScopedMachSendRight exception_port);
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN) || DOXYGEN
|
||||
//! \brief Sets the IPC pipe of a presumably-running Crashpad handler process
|
||||
//! which was started with StartHandler() or by other compatible means
|
||||
@ -83,6 +113,8 @@ class CrashpadClient {
|
||||
//! handler. However, just like StartHandler(), crashes are not serviced
|
||||
//! until UseHandler() is called.
|
||||
//!
|
||||
//! This method is only defined on Windows.
|
||||
//!
|
||||
//! \param[in] ipc_pipe The full name of the crash handler IPC pipe. This is
|
||||
//! a string of the form `"\\.\pipe\NAME"`.
|
||||
//!
|
||||
@ -115,7 +147,8 @@ class CrashpadClient {
|
||||
//! \brief Configures the process to direct its crashes to a Crashpad handler.
|
||||
//!
|
||||
//! The Crashpad handler must previously have been started by StartHandler()
|
||||
//! or configured by SetHandlerIPCPipe().
|
||||
//! or configured by SetHandlerMachService(), SetHandlerMachPort(), or
|
||||
//! SetHandlerIPCPipe().
|
||||
//!
|
||||
//! On Mac OS X, this method sets the task’s exception port for `EXC_CRASH`,
|
||||
//! `EXC_RESOURCE`, and `EXC_GUARD` exceptions to the Mach send right obtained
|
||||
|
@ -517,20 +517,37 @@ bool CrashpadClient::StartHandler(
|
||||
// The “restartable” behavior can only be selected on OS X 10.10 and later. In
|
||||
// previous OS versions, if the initial client were to crash while attempting
|
||||
// to restart the handler, it would become an unkillable process.
|
||||
exception_port_ = HandlerStarter::InitialStart(
|
||||
base::mac::ScopedMachSendRight exception_port(HandlerStarter::InitialStart(
|
||||
handler,
|
||||
database,
|
||||
url,
|
||||
annotations,
|
||||
arguments,
|
||||
restartable && MacOSXMinorVersion() >= 10);
|
||||
if (!exception_port_.is_valid()) {
|
||||
restartable && MacOSXMinorVersion() >= 10));
|
||||
if (!exception_port.is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SetHandlerMachPort(exception_port.Pass());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CrashpadClient::SetHandlerMachService(const std::string& service_name) {
|
||||
base::mac::ScopedMachSendRight exception_port(BootstrapLookUp(service_name));
|
||||
if (!exception_port.is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SetHandlerMachPort(exception_port.Pass());
|
||||
return true;
|
||||
}
|
||||
|
||||
void CrashpadClient::SetHandlerMachPort(
|
||||
base::mac::ScopedMachSendRight exception_port) {
|
||||
DCHECK(exception_port.is_valid());
|
||||
exception_port_ = exception_port.Pass();
|
||||
}
|
||||
|
||||
bool CrashpadClient::UseHandler() {
|
||||
DCHECK(exception_port_.is_valid());
|
||||
|
||||
|
@ -33,13 +33,21 @@ collection server. Uploads are disabled by default, and can only be enabled by a
|
||||
Crashpad client using the Crashpad client library, typically in response to a
|
||||
user requesting this behavior.
|
||||
|
||||
On OS X, this server is normally started by its initial client, and it performs
|
||||
a handshake with this client via a pipe established by the client that is
|
||||
inherited by the server, referenced by the *--handshake-fd* argument. During the
|
||||
handshake, the server furnishes the client with a send right that the client may
|
||||
use as an exception port. The server retains the corresponding receive right,
|
||||
which it monitors for exception messages. When the receive right loses all
|
||||
senders, the server exits after allowing any upload in progress to complete.
|
||||
On OS X, this server may be started by its initial client, in which case it
|
||||
performs a handshake with this client via a pipe established by the client that
|
||||
is inherited by the server, referenced by the *--handshake-fd* argument. During
|
||||
the handshake, the server furnishes the client with a send right that the client
|
||||
may use as an exception port. The server retains the corresponding receive
|
||||
right, which it monitors for exception messages. When the receive right loses
|
||||
all senders, the server exits after allowing any upload in progress to complete.
|
||||
|
||||
Alternatively, on OS X, this server may be started from launchd(8), where it
|
||||
receives the Mach service name in a *--mach-service* argument. It checks in with
|
||||
the bootstrap server under this service name, and clients may look it up with
|
||||
the bootstrap server under this service name. It monitors this service for
|
||||
exception messages. Upon receipt of +SIGTERM+, the server exits after allowing
|
||||
any upload in progress to complete. +SIGTERM+ is normally sent by launchd(8)
|
||||
when it determines that the server should exit.
|
||||
|
||||
On Windows, clients register with this server by communicating with it via the
|
||||
named pipe identified by the *--pipe-name* argument. During registration, a
|
||||
@ -51,10 +59,10 @@ to exit cleanly without crashing. When the server loses all clients and
|
||||
to complete.
|
||||
|
||||
It is not normally appropriate to invoke this program directly. Usually, it will
|
||||
be invoked by a Crashpad client using the Crashpad client library. Arbitrary
|
||||
programs may be run with a Crashpad handler by using
|
||||
man_link:run_with_crashpad[1] to establish the Crashpad client environment
|
||||
before running a program.
|
||||
be invoked by a Crashpad client using the Crashpad client library, or started by
|
||||
another system service. On OS X, arbitrary programs may be run with a Crashpad
|
||||
handler by using man_link:run_with_crashpad[1] to establish the Crashpad client
|
||||
environment before running a program.
|
||||
|
||||
== Options
|
||||
*--annotation*='KEY=VALUE'::
|
||||
@ -84,7 +92,18 @@ of 'PATH' exists.
|
||||
|
||||
*--handshake-fd*='FD'::
|
||||
Perform the handshake with the initial client on the file descriptor at 'FD'.
|
||||
This option is required. This option is only valid on Mac OS X.
|
||||
Either this option or *--mach-service*, but not both, is required. This option
|
||||
is only valid on OS X.
|
||||
|
||||
*--mach-service*='SERVICE'::
|
||||
Check in with the bootstrap server under the name 'SERVICE'. Either this option
|
||||
or *--handshake-fd*, but not both, is required. This option is only valid on OS
|
||||
X.
|
||||
+
|
||||
'SERVICE' may already be reserved with the bootstrap server in cases where this
|
||||
tool is started by launchd(8) as a result of a message being sent to a service
|
||||
declared in a job’s +MachServices+ dictionary (see launchd.plist(5)). The
|
||||
service name may also be completely unknown to the system.
|
||||
|
||||
*--persistent*::
|
||||
Continue running after the last client exits. If this option is not specified,
|
||||
|
@ -14,7 +14,12 @@
|
||||
|
||||
#include "handler/mac/exception_handler_server.h"
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include "base/auto_reset.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/scoped_generic.h"
|
||||
#include "base/mac/mach_logging.h"
|
||||
#include "util/mach/composite_mach_message_server.h"
|
||||
#include "util/mach/mach_extensions.h"
|
||||
@ -26,11 +31,59 @@ namespace crashpad {
|
||||
|
||||
namespace {
|
||||
|
||||
struct ResetSIGTERMTraits {
|
||||
static struct sigaction* InvalidValue() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void Free(struct sigaction* sa) {
|
||||
int rv = sigaction(SIGTERM, sa, nullptr);
|
||||
PLOG_IF(ERROR, rv != 0) << "sigaction";
|
||||
}
|
||||
};
|
||||
using ScopedResetSIGTERM =
|
||||
base::ScopedGeneric<struct sigaction*, ResetSIGTERMTraits>;
|
||||
|
||||
mach_port_t g_signal_notify_port;
|
||||
|
||||
// This signal handler is only operative when being run from launchd. It causes
|
||||
// the exception handler server to stop running by sending it a synthesized
|
||||
// no-senders notification.
|
||||
void HandleSIGTERM(int sig, siginfo_t* siginfo, void* context) {
|
||||
DCHECK(g_signal_notify_port);
|
||||
|
||||
// mach_no_senders_notification_t defines the receive side of this structure,
|
||||
// with a trailer element that’s undesirable for the send side.
|
||||
struct {
|
||||
mach_msg_header_t header;
|
||||
NDR_record_t ndr;
|
||||
mach_msg_type_number_t mscount;
|
||||
} no_senders_notification = {};
|
||||
no_senders_notification.header.msgh_bits =
|
||||
MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND_ONCE, 0);
|
||||
no_senders_notification.header.msgh_size = sizeof(no_senders_notification);
|
||||
no_senders_notification.header.msgh_remote_port = g_signal_notify_port;
|
||||
no_senders_notification.header.msgh_local_port = MACH_PORT_NULL;
|
||||
no_senders_notification.header.msgh_id = MACH_NOTIFY_NO_SENDERS;
|
||||
no_senders_notification.ndr = NDR_record;
|
||||
no_senders_notification.mscount = 0;
|
||||
|
||||
kern_return_t kr = mach_msg(&no_senders_notification.header,
|
||||
MACH_SEND_MSG,
|
||||
sizeof(no_senders_notification),
|
||||
0,
|
||||
MACH_PORT_NULL,
|
||||
MACH_MSG_TIMEOUT_NONE,
|
||||
MACH_PORT_NULL);
|
||||
MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_msg";
|
||||
}
|
||||
|
||||
class ExceptionHandlerServerRun : public UniversalMachExcServer::Interface,
|
||||
public NotifyServer::DefaultInterface {
|
||||
public:
|
||||
ExceptionHandlerServerRun(
|
||||
mach_port_t exception_port,
|
||||
bool launchd,
|
||||
UniversalMachExcServer::Interface* exception_interface)
|
||||
: UniversalMachExcServer::Interface(),
|
||||
NotifyServer::DefaultInterface(),
|
||||
@ -40,7 +93,8 @@ class ExceptionHandlerServerRun : public UniversalMachExcServer::Interface,
|
||||
exception_interface_(exception_interface),
|
||||
exception_port_(exception_port),
|
||||
notify_port_(NewMachPort(MACH_PORT_RIGHT_RECEIVE)),
|
||||
running_(true) {
|
||||
running_(true),
|
||||
launchd_(launchd) {
|
||||
CHECK(notify_port_.is_valid());
|
||||
|
||||
composite_mach_message_server_.AddHandler(&mach_exc_server_);
|
||||
@ -53,11 +107,15 @@ class ExceptionHandlerServerRun : public UniversalMachExcServer::Interface,
|
||||
void Run() {
|
||||
DCHECK(running_);
|
||||
|
||||
kern_return_t kr;
|
||||
scoped_ptr<base::AutoReset<mach_port_t>> reset_signal_notify_port;
|
||||
struct sigaction old_sa;
|
||||
ScopedResetSIGTERM reset_sigterm;
|
||||
if (!launchd_) {
|
||||
// Request that a no-senders notification for exception_port_ be sent to
|
||||
// notify_port_.
|
||||
mach_port_t previous;
|
||||
kern_return_t kr =
|
||||
mach_port_request_notification(mach_task_self(),
|
||||
kr = mach_port_request_notification(mach_task_self(),
|
||||
exception_port_,
|
||||
MACH_NOTIFY_NO_SENDERS,
|
||||
0,
|
||||
@ -70,6 +128,25 @@ class ExceptionHandlerServerRun : public UniversalMachExcServer::Interface,
|
||||
kr = mach_port_deallocate(mach_task_self(), previous);
|
||||
MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_port_deallocate";
|
||||
}
|
||||
} else {
|
||||
// A real no-senders notification would never be triggered, because
|
||||
// launchd maintains a send right to the service. When launchd wants the
|
||||
// job to exit, it will send a SIGTERM. See launchd.plist(5).
|
||||
//
|
||||
// Set up a SIGTERM handler that will cause Run() to return (incidentally,
|
||||
// by sending a synthetic no-senders notification).
|
||||
struct sigaction sa = {};
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sa.sa_sigaction = HandleSIGTERM;
|
||||
int rv = sigaction(SIGTERM, &sa, &old_sa);
|
||||
PCHECK(rv == 0) << "sigaction";
|
||||
reset_sigterm.reset(&old_sa);
|
||||
|
||||
DCHECK(!g_signal_notify_port);
|
||||
reset_signal_notify_port.reset(new base::AutoReset<mach_port_t>(
|
||||
&g_signal_notify_port, notify_port_.get()));
|
||||
}
|
||||
|
||||
// A single CompositeMachMessageServer will dispatch both exception messages
|
||||
// and the no-senders notification. Put both receive rights into a port set.
|
||||
@ -81,6 +158,7 @@ class ExceptionHandlerServerRun : public UniversalMachExcServer::Interface,
|
||||
// the proper send right.
|
||||
base::mac::ScopedMachPortSet server_port_set(
|
||||
NewMachPort(MACH_PORT_RIGHT_PORT_SET));
|
||||
CHECK(server_port_set.is_valid());
|
||||
|
||||
kr = mach_port_insert_member(
|
||||
mach_task_self(), exception_port_, server_port_set.get());
|
||||
@ -173,6 +251,7 @@ class ExceptionHandlerServerRun : public UniversalMachExcServer::Interface,
|
||||
mach_port_t exception_port_; // weak
|
||||
base::mac::ScopedMachReceiveRight notify_port_;
|
||||
bool running_;
|
||||
bool launchd_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerServerRun);
|
||||
};
|
||||
@ -180,8 +259,10 @@ class ExceptionHandlerServerRun : public UniversalMachExcServer::Interface,
|
||||
} // namespace
|
||||
|
||||
ExceptionHandlerServer::ExceptionHandlerServer(
|
||||
base::mac::ScopedMachReceiveRight receive_port)
|
||||
: receive_port_(receive_port.Pass()) {
|
||||
base::mac::ScopedMachReceiveRight receive_port,
|
||||
bool launchd)
|
||||
: receive_port_(receive_port.Pass()),
|
||||
launchd_(launchd) {
|
||||
CHECK(receive_port_.is_valid());
|
||||
}
|
||||
|
||||
@ -190,7 +271,8 @@ ExceptionHandlerServer::~ExceptionHandlerServer() {
|
||||
|
||||
void ExceptionHandlerServer::Run(
|
||||
UniversalMachExcServer::Interface* exception_interface) {
|
||||
ExceptionHandlerServerRun run(receive_port_.get(), exception_interface);
|
||||
ExceptionHandlerServerRun run(
|
||||
receive_port_.get(), launchd_, exception_interface);
|
||||
run.Run();
|
||||
}
|
||||
|
||||
|
@ -32,20 +32,26 @@ class ExceptionHandlerServer {
|
||||
//!
|
||||
//! \param[in] receive_port The port that exception messages and no-senders
|
||||
//! notifications will be received on.
|
||||
explicit ExceptionHandlerServer(
|
||||
base::mac::ScopedMachReceiveRight receive_port);
|
||||
//! \param[in] launchd If `true`, the exception handler is being run from
|
||||
//! launchd. \a receive_port is not monitored for no-senders
|
||||
//! notifications, and instead, the expected “quit” signal is receipt of
|
||||
//! `SIGTERM`.
|
||||
ExceptionHandlerServer(base::mac::ScopedMachReceiveRight receive_port,
|
||||
bool launchd);
|
||||
~ExceptionHandlerServer();
|
||||
|
||||
//! \brief Runs the exception-handling server.
|
||||
//!
|
||||
//! \param[in] exception_interface An object to send exception messages to.
|
||||
//!
|
||||
//! This method monitors the receive port for exception messages and
|
||||
//! no-senders notifications. It continues running until it has no more
|
||||
//! clients, indicated by the receipt of a no-senders notification. It is
|
||||
//! important to assure that a send right exists in a client (or has been
|
||||
//! queued by `mach_msg()` to be sent to a client) prior to calling this
|
||||
//! method, or it will detect that it is sender-less and return immediately.
|
||||
//! This method monitors the receive port for exception messages and, if
|
||||
//! not being run by launchd, no-senders notifications. It continues running
|
||||
//! until it has no more clients, indicated by the receipt of a no-senders
|
||||
//! notification, or if being run by launchd, receipt of `SIGTERM`. When not
|
||||
//! being run by launchd, it is important to assure that a send right exists
|
||||
//! in a client (or has been queued by `mach_msg()` to be sent to a client)
|
||||
//! prior to calling this method, or it will detect that it is sender-less and
|
||||
//! return immediately.
|
||||
//!
|
||||
//! All exception messages will be passed to \a exception_interface.
|
||||
//!
|
||||
@ -59,6 +65,7 @@ class ExceptionHandlerServer {
|
||||
|
||||
private:
|
||||
base::mac::ScopedMachReceiveRight receive_port_;
|
||||
bool launchd_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerServer);
|
||||
};
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "handler/mac/crash_report_exception_handler.h"
|
||||
#include "handler/mac/exception_handler_server.h"
|
||||
#include "util/mach/child_port_handshake.h"
|
||||
#include "util/mach/mach_extensions.h"
|
||||
#include "util/posix/close_stdio.h"
|
||||
#elif defined(OS_WIN)
|
||||
#include <windows.h>
|
||||
@ -57,6 +58,7 @@ void Usage(const base::FilePath& me) {
|
||||
" --database=PATH store the crash report database at PATH\n"
|
||||
#if defined(OS_MACOSX)
|
||||
" --handshake-fd=FD establish communication with the client over FD\n"
|
||||
" --mach-service=SERVICE register SERVICE with the bootstrap server\n"
|
||||
" --reset-own-crash-exception-port-to-system-default\n"
|
||||
" reset the server's exception handler to default\n"
|
||||
#elif defined(OS_WIN)
|
||||
@ -83,6 +85,7 @@ int HandlerMain(int argc, char* argv[]) {
|
||||
kOptionDatabase,
|
||||
#if defined(OS_MACOSX)
|
||||
kOptionHandshakeFD,
|
||||
kOptionMachService,
|
||||
kOptionResetOwnCrashExceptionPortToSystemDefault,
|
||||
#elif defined(OS_WIN)
|
||||
kOptionPersistent,
|
||||
@ -101,6 +104,7 @@ int HandlerMain(int argc, char* argv[]) {
|
||||
const char* database;
|
||||
#if defined(OS_MACOSX)
|
||||
int handshake_fd;
|
||||
std::string mach_service;
|
||||
bool reset_own_crash_exception_port_to_system_default;
|
||||
#elif defined(OS_WIN)
|
||||
bool persistent;
|
||||
@ -117,6 +121,7 @@ int HandlerMain(int argc, char* argv[]) {
|
||||
{"database", required_argument, nullptr, kOptionDatabase},
|
||||
#if defined(OS_MACOSX)
|
||||
{"handshake-fd", required_argument, nullptr, kOptionHandshakeFD},
|
||||
{"mach-service", required_argument, nullptr, kOptionMachService},
|
||||
{"reset-own-crash-exception-port-to-system-default",
|
||||
no_argument,
|
||||
nullptr,
|
||||
@ -162,6 +167,10 @@ int HandlerMain(int argc, char* argv[]) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kOptionMachService: {
|
||||
options.mach_service = optarg;
|
||||
break;
|
||||
}
|
||||
case kOptionResetOwnCrashExceptionPortToSystemDefault: {
|
||||
options.reset_own_crash_exception_port_to_system_default = true;
|
||||
break;
|
||||
@ -198,8 +207,13 @@ int HandlerMain(int argc, char* argv[]) {
|
||||
argv += optind;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
if (options.handshake_fd < 0) {
|
||||
ToolSupport::UsageHint(me, "--handshake-fd is required");
|
||||
if (options.handshake_fd < 0 && options.mach_service.empty()) {
|
||||
ToolSupport::UsageHint(me, "--handshake-fd or --mach-service is required");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (options.handshake_fd >= 0 && !options.mach_service.empty()) {
|
||||
ToolSupport::UsageHint(
|
||||
me, "--handshake-fd and --mach-service are incompatible");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
#elif defined(OS_WIN)
|
||||
@ -220,21 +234,32 @@ int HandlerMain(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
if (options.mach_service.empty()) {
|
||||
// Don’t do this when being run by launchd. See launchd.plist(5).
|
||||
CloseStdinAndStdout();
|
||||
}
|
||||
|
||||
if (options.reset_own_crash_exception_port_to_system_default) {
|
||||
CrashpadClient::UseSystemDefaultHandler();
|
||||
}
|
||||
|
||||
base::mac::ScopedMachReceiveRight receive_right(
|
||||
base::mac::ScopedMachReceiveRight receive_right;
|
||||
|
||||
if (options.handshake_fd >= 0) {
|
||||
receive_right.reset(
|
||||
ChildPortHandshake::RunServerForFD(
|
||||
base::ScopedFD(options.handshake_fd),
|
||||
ChildPortHandshake::PortRightType::kReceiveRight));
|
||||
} else if (!options.mach_service.empty()) {
|
||||
receive_right = BootstrapCheckIn(options.mach_service);
|
||||
}
|
||||
|
||||
if (!receive_right.is_valid()) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ExceptionHandlerServer exception_handler_server(receive_right.Pass());
|
||||
ExceptionHandlerServer exception_handler_server(
|
||||
receive_right.Pass(), !options.mach_service.empty());
|
||||
#elif defined(OS_WIN)
|
||||
ExceptionHandlerServer exception_handler_server(options.pipe_name,
|
||||
options.persistent);
|
||||
|
Loading…
x
Reference in New Issue
Block a user