From ec56fc6a38f0e021ef2a970b39c7198b270184eb Mon Sep 17 00:00:00 2001 From: Joshua Peraza Date: Mon, 19 Aug 2019 11:30:12 -0700 Subject: [PATCH] linux: add Get/SetHandlerSocket() These methods are used to connect additional clients to an existing handler process. Bug: crashpad:285 Change-Id: Iefa5b0d8f5fd7d4799140ff9a7c2f79ac65da738 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/1759281 Commit-Queue: Joshua Peraza Reviewed-by: Mark Mentovai --- client/crashpad_client.h | 25 +++++++++++++++++++++++++ client/crashpad_client_linux.cc | 25 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/client/crashpad_client.h b/client/crashpad_client.h index 3db1c9c1..56d738b7 100644 --- a/client/crashpad_client.h +++ b/client/crashpad_client.h @@ -24,6 +24,7 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "build/build_config.h" +#include "util/file/file_io.h" #include "util/misc/capture_context.h" #if defined(OS_MACOSX) @@ -116,6 +117,30 @@ class CrashpadClient { bool restartable, bool asynchronous_start); +#if defined(OS_ANDROID) || defined(OS_LINUX) || DOXYGEN + //! \brief Retrieve the socket and process ID for the handler. + //! + //! `StartHandler()` must have successfully been called before calling this + //! method. + //! + //! \param[out] sock The socket connected to the handler. + //! \param[out] pid The handler's process ID. + //! \return `true` on success. Otherwise `false` with a message logged. + static bool GetHandlerSocket(int* sock, pid_t* pid); + + //! \brief Sets the socket to a presumably-running Crashpad handler process + //! which was started with StartHandler(). + //! + //! This method installs a signal handler to request crash dumps on \a sock. + //! + //! \param[in] sock A socket connected to a Crashpad handler. + //! \param[in] pid The process ID of the handler, used to set the handler as + //! this process' ptracer. 0 indicates it is not necessary to set the + //! handler as this process' ptracer. -1 indicates that the handler's + //! process ID should be determined by communicating over the socket. + static bool SetHandlerSocket(ScopedFileHandle sock, pid_t pid); +#endif // OS_ANDROID || OS_LINUX || DOXYGEN + #if defined(OS_ANDROID) || DOXYGEN //! \brief Installs a signal handler to execute `/system/bin/app_process` and //! load a Java class in response to a crash. diff --git a/client/crashpad_client_linux.cc b/client/crashpad_client_linux.cc index 008f8587..2e2ec30a 100644 --- a/client/crashpad_client_linux.cc +++ b/client/crashpad_client_linux.cc @@ -284,9 +284,19 @@ class RequestCrashDumpHandler : public SignalHandler { return false; } sock_to_handler_.reset(sock.release()); + handler_pid_ = pid; return Install(); } + bool GetHandlerSocket(int* sock, pid_t* pid) { + if (!sock_to_handler_.is_valid()) { + return false; + } + *sock = sock_to_handler_.get(); + *pid = handler_pid_; + return true; + } + void HandleCrashImpl() override { ExceptionHandlerProtocol::ClientInformation info = {}; info.exception_information_address = @@ -302,6 +312,7 @@ class RequestCrashDumpHandler : public SignalHandler { ~RequestCrashDumpHandler() = delete; ScopedFileHandle sock_to_handler_; + pid_t handler_pid_ = -1; DISALLOW_COPY_AND_ASSIGN(RequestCrashDumpHandler); }; @@ -343,6 +354,20 @@ bool CrashpadClient::StartHandler( return signal_handler->Initialize(std::move(client_sock), -1); } +#if defined(OS_ANDROID) || defined(OS_LINUX) +// static +bool CrashpadClient::GetHandlerSocket(int* sock, pid_t* pid) { + auto signal_handler = RequestCrashDumpHandler::Get(); + return signal_handler->GetHandlerSocket(sock, pid); +} + +// static +bool CrashpadClient::SetHandlerSocket(ScopedFileHandle sock, pid_t pid) { + auto signal_handler = RequestCrashDumpHandler::Get(); + return signal_handler->Initialize(std::move(sock), pid); +} +#endif // OS_ANDROID || OS_LINUX + #if defined(OS_ANDROID) // static