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

Unified Diff: handler/mac/exception_handler_server.cc

Issue 1429353002: mac: Scope crashpad_handler’s SIGTERM handler more broadly (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Rebase Created 5 years, 1 month 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 | « handler/mac/exception_handler_server.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: handler/mac/exception_handler_server.cc
diff --git a/handler/mac/exception_handler_server.cc b/handler/mac/exception_handler_server.cc
index 19038293bf104be39b48310cfa139efe57eaaadc..845b34dd1b326e4bfc400cd97dcd1a3bcbcd5be4 100644
--- a/handler/mac/exception_handler_server.cc
+++ b/handler/mac/exception_handler_server.cc
@@ -14,12 +14,7 @@
#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"
@@ -31,58 +26,12 @@ 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,
+ mach_port_t notify_port,
bool launchd,
UniversalMachExcServer::Interface* exception_interface)
: UniversalMachExcServer::Interface(),
@@ -92,11 +41,9 @@ class ExceptionHandlerServerRun : public UniversalMachExcServer::Interface,
composite_mach_message_server_(),
exception_interface_(exception_interface),
exception_port_(exception_port),
- notify_port_(NewMachPort(MACH_PORT_RIGHT_RECEIVE)),
+ notify_port_(notify_port),
running_(true),
launchd_(launchd) {
- CHECK(notify_port_.is_valid());
-
composite_mach_message_server_.AddHandler(&mach_exc_server_);
composite_mach_message_server_.AddHandler(&notify_server_);
}
@@ -108,9 +55,6 @@ class ExceptionHandlerServerRun : public UniversalMachExcServer::Interface,
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_.
@@ -119,33 +63,11 @@ class ExceptionHandlerServerRun : public UniversalMachExcServer::Interface,
exception_port_,
MACH_NOTIFY_NO_SENDERS,
0,
- notify_port_.get(),
+ notify_port_,
MACH_MSG_TYPE_MAKE_SEND_ONCE,
&previous);
MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_port_request_notification";
-
- if (previous != MACH_PORT_NULL) {
- 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()));
+ base::mac::ScopedMachSendRight previous_owner(previous);
}
// A single CompositeMachMessageServer will dispatch both exception messages
@@ -165,7 +87,7 @@ class ExceptionHandlerServerRun : public UniversalMachExcServer::Interface,
MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_port_insert_member";
kr = mach_port_insert_member(
- mach_task_self(), notify_port_.get(), server_port_set.get());
+ mach_task_self(), notify_port_, server_port_set.get());
MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_port_insert_member";
// Run the server in kOneShot mode so that running_ can be reevaluated after
@@ -249,7 +171,7 @@ class ExceptionHandlerServerRun : public UniversalMachExcServer::Interface,
CompositeMachMessageServer composite_mach_message_server_;
UniversalMachExcServer::Interface* exception_interface_; // weak
mach_port_t exception_port_; // weak
- base::mac::ScopedMachReceiveRight notify_port_;
+ mach_port_t notify_port_; // weak
bool running_;
bool launchd_;
@@ -262,8 +184,10 @@ ExceptionHandlerServer::ExceptionHandlerServer(
base::mac::ScopedMachReceiveRight receive_port,
bool launchd)
: receive_port_(receive_port.Pass()),
+ notify_port_(NewMachPort(MACH_PORT_RIGHT_RECEIVE)),
launchd_(launchd) {
CHECK(receive_port_.is_valid());
+ CHECK(notify_port_.is_valid());
}
ExceptionHandlerServer::~ExceptionHandlerServer() {
@@ -272,8 +196,38 @@ ExceptionHandlerServer::~ExceptionHandlerServer() {
void ExceptionHandlerServer::Run(
UniversalMachExcServer::Interface* exception_interface) {
ExceptionHandlerServerRun run(
- receive_port_.get(), launchd_, exception_interface);
+ receive_port_.get(), notify_port_.get(), launchd_, exception_interface);
run.Run();
}
+void ExceptionHandlerServer::Stop() {
+ // Cause the exception handler server to stop running by sending it a
+ // synthesized no-senders notification.
+ //
+ // 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 = notify_port_.get();
+ 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";
+}
+
} // namespace crashpad
« no previous file with comments | « handler/mac/exception_handler_server.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698