linux: move handler protocol types into a class

This patch adds the class ExceptionHandlerProtocol to contain all the
relevant types, but should not make any functional changes.

Change-Id: I65ada239a6bf3195899fdd96f005c042cdd59749
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/1575796
Commit-Queue: Joshua Peraza <jperaza@chromium.org>
Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Joshua Peraza 2019-04-23 09:59:29 -07:00 committed by Commit Bot
parent 93366d782a
commit c96226c6ba
14 changed files with 181 additions and 146 deletions

View File

@ -342,7 +342,7 @@ class StartHandlerForClientTest {
context); context);
exception_information.thread_id = syscall(SYS_gettid); exception_information.thread_id = syscall(SYS_gettid);
ClientInformation info; ExceptionHandlerProtocol::ClientInformation info;
info.exception_information_address = info.exception_information_address =
FromPointerCast<decltype(info.exception_information_address)>( FromPointerCast<decltype(info.exception_information_address)>(
&exception_information); &exception_information);

View File

@ -880,7 +880,7 @@ int HandlerMain(int argc,
#if defined(OS_LINUX) || defined(OS_ANDROID) #if defined(OS_LINUX) || defined(OS_ANDROID)
if (options.exception_information_address) { if (options.exception_information_address) {
ClientInformation info; ExceptionHandlerProtocol::ClientInformation info;
info.exception_information_address = options.exception_information_address; info.exception_information_address = options.exception_information_address;
info.sanitization_information_address = info.sanitization_information_address =
options.sanitization_information_address; options.sanitization_information_address;

View File

@ -45,7 +45,7 @@ CrashReportExceptionHandler::~CrashReportExceptionHandler() = default;
bool CrashReportExceptionHandler::HandleException( bool CrashReportExceptionHandler::HandleException(
pid_t client_process_id, pid_t client_process_id,
const ClientInformation& info, const ExceptionHandlerProtocol::ClientInformation& info,
VMAddress requesting_thread_stack_address, VMAddress requesting_thread_stack_address,
pid_t* requesting_thread_id, pid_t* requesting_thread_id,
UUID* local_report_id) { UUID* local_report_id) {
@ -67,7 +67,7 @@ bool CrashReportExceptionHandler::HandleException(
bool CrashReportExceptionHandler::HandleExceptionWithBroker( bool CrashReportExceptionHandler::HandleExceptionWithBroker(
pid_t client_process_id, pid_t client_process_id,
const ClientInformation& info, const ExceptionHandlerProtocol::ClientInformation& info,
int broker_sock, int broker_sock,
UUID* local_report_id) { UUID* local_report_id) {
Metrics::ExceptionEncountered(); Metrics::ExceptionEncountered();
@ -85,7 +85,7 @@ bool CrashReportExceptionHandler::HandleExceptionWithBroker(
bool CrashReportExceptionHandler::HandleExceptionWithConnection( bool CrashReportExceptionHandler::HandleExceptionWithConnection(
PtraceConnection* connection, PtraceConnection* connection,
const ClientInformation& info, const ExceptionHandlerProtocol::ClientInformation& info,
VMAddress requesting_thread_stack_address, VMAddress requesting_thread_stack_address,
pid_t* requesting_thread_id, pid_t* requesting_thread_id,
UUID* local_report_id) { UUID* local_report_id) {

View File

@ -65,22 +65,24 @@ class CrashReportExceptionHandler : public ExceptionHandlerServer::Delegate {
// ExceptionHandlerServer::Delegate: // ExceptionHandlerServer::Delegate:
bool HandleException(pid_t client_process_id, bool HandleException(pid_t client_process_id,
const ClientInformation& info, const ExceptionHandlerProtocol::ClientInformation& info,
VMAddress requesting_thread_stack_address = 0, VMAddress requesting_thread_stack_address = 0,
pid_t* requesting_thread_id = nullptr, pid_t* requesting_thread_id = nullptr,
UUID* local_report_id = nullptr) override; UUID* local_report_id = nullptr) override;
bool HandleExceptionWithBroker(pid_t client_process_id, bool HandleExceptionWithBroker(
const ClientInformation& info, pid_t client_process_id,
int broker_sock, const ExceptionHandlerProtocol::ClientInformation& info,
UUID* local_report_id = nullptr) override; int broker_sock,
UUID* local_report_id = nullptr) override;
private: private:
bool HandleExceptionWithConnection(PtraceConnection* connection, bool HandleExceptionWithConnection(
const ClientInformation& info, PtraceConnection* connection,
VMAddress requesting_thread_stack_address, const ExceptionHandlerProtocol::ClientInformation& info,
pid_t* requesting_thread_id, VMAddress requesting_thread_stack_address,
UUID* local_report_id = nullptr); pid_t* requesting_thread_id,
UUID* local_report_id = nullptr);
CrashReportDatabase* database_; // weak CrashReportDatabase* database_; // weak
CrashReportUploadThread* upload_thread_; // weak CrashReportUploadThread* upload_thread_; // weak

View File

@ -110,10 +110,13 @@ bool HaveCapSysPtrace() {
return (cap_data.effective & (1 << CAP_SYS_PTRACE)) != 0; return (cap_data.effective & (1 << CAP_SYS_PTRACE)) != 0;
} }
bool SendMessageToClient(int client_sock, ServerToClientMessage::Type type) { bool SendMessageToClient(
ServerToClientMessage message = {}; int client_sock,
ExceptionHandlerProtocol::ServerToClientMessage::Type type) {
ExceptionHandlerProtocol::ServerToClientMessage message = {};
message.type = type; message.type = type;
if (type == ServerToClientMessage::kTypeSetPtracer) { if (type ==
ExceptionHandlerProtocol::ServerToClientMessage::kTypeSetPtracer) {
message.pid = getpid(); message.pid = getpid();
} }
return LoggingWriteFile(client_sock, &message, sizeof(message)); return LoggingWriteFile(client_sock, &message, sizeof(message));
@ -134,11 +137,12 @@ class PtraceStrategyDeciderImpl : public PtraceStrategyDecider {
case PtraceScope::kRestricted: case PtraceScope::kRestricted:
if (!SendMessageToClient(sock, if (!SendMessageToClient(sock,
ServerToClientMessage::kTypeSetPtracer)) { ExceptionHandlerProtocol::
ServerToClientMessage::kTypeSetPtracer)) {
return Strategy::kError; return Strategy::kError;
} }
Errno status; ExceptionHandlerProtocol::Errno status;
if (!LoggingReadFileExactly(sock, &status, sizeof(status))) { if (!LoggingReadFileExactly(sock, &status, sizeof(status))) {
return Strategy::kError; return Strategy::kError;
} }
@ -170,12 +174,13 @@ class PtraceStrategyDeciderImpl : public PtraceStrategyDecider {
private: private:
static Strategy TryForkingBroker(int client_sock) { static Strategy TryForkingBroker(int client_sock) {
if (!SendMessageToClient(client_sock, if (!SendMessageToClient(
ServerToClientMessage::kTypeForkBroker)) { client_sock,
ExceptionHandlerProtocol::ServerToClientMessage::kTypeForkBroker)) {
return Strategy::kError; return Strategy::kError;
} }
Errno status; ExceptionHandlerProtocol::Errno status;
if (!LoggingReadFileExactly(client_sock, &status, sizeof(status))) { if (!LoggingReadFileExactly(client_sock, &status, sizeof(status))) {
return Strategy::kError; return Strategy::kError;
} }
@ -369,7 +374,7 @@ bool ExceptionHandlerServer::UninstallClientSocket(Event* event) {
} }
bool ExceptionHandlerServer::ReceiveClientMessage(Event* event) { bool ExceptionHandlerServer::ReceiveClientMessage(Event* event) {
ClientToServerMessage message; ExceptionHandlerProtocol::ClientToServerMessage message;
iovec iov; iovec iov;
iov.iov_base = &message; iov.iov_base = &message;
iov.iov_len = sizeof(message); iov.iov_len = sizeof(message);
@ -405,15 +410,17 @@ bool ExceptionHandlerServer::ReceiveClientMessage(Event* event) {
return false; return false;
} }
if (msg.msg_iov[0].iov_len != sizeof(ClientToServerMessage)) { if (msg.msg_iov[0].iov_len !=
sizeof(ExceptionHandlerProtocol::ClientToServerMessage)) {
LOG(ERROR) << "unexpected message size " << msg.msg_iov[0].iov_len; LOG(ERROR) << "unexpected message size " << msg.msg_iov[0].iov_len;
return false; return false;
} }
auto client_msg = auto client_msg =
reinterpret_cast<ClientToServerMessage*>(msg.msg_iov[0].iov_base); reinterpret_cast<ExceptionHandlerProtocol::ClientToServerMessage*>(
msg.msg_iov[0].iov_base);
switch (client_msg->type) { switch (client_msg->type) {
case ClientToServerMessage::kCrashDumpRequest: case ExceptionHandlerProtocol::ClientToServerMessage::kCrashDumpRequest:
return HandleCrashDumpRequest(msg, return HandleCrashDumpRequest(msg,
client_msg->client_info, client_msg->client_info,
client_msg->requesting_thread_stack_address, client_msg->requesting_thread_stack_address,
@ -427,7 +434,7 @@ bool ExceptionHandlerServer::ReceiveClientMessage(Event* event) {
bool ExceptionHandlerServer::HandleCrashDumpRequest( bool ExceptionHandlerServer::HandleCrashDumpRequest(
const msghdr& msg, const msghdr& msg,
const ClientInformation& client_info, const ExceptionHandlerProtocol::ClientInformation& client_info,
VMAddress requesting_thread_stack_address, VMAddress requesting_thread_stack_address,
int client_sock) { int client_sock) {
cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
@ -459,8 +466,10 @@ bool ExceptionHandlerServer::HandleCrashDumpRequest(
return false; return false;
case PtraceStrategyDecider::Strategy::kNoPtrace: case PtraceStrategyDecider::Strategy::kNoPtrace:
return SendMessageToClient(client_sock, return SendMessageToClient(
ServerToClientMessage::kTypeCrashDumpFailed); client_sock,
ExceptionHandlerProtocol::ServerToClientMessage::
kTypeCrashDumpFailed);
case PtraceStrategyDecider::Strategy::kDirectPtrace: case PtraceStrategyDecider::Strategy::kDirectPtrace:
delegate_->HandleException( delegate_->HandleException(
@ -473,8 +482,9 @@ bool ExceptionHandlerServer::HandleCrashDumpRequest(
break; break;
} }
return SendMessageToClient(client_sock, return SendMessageToClient(
ServerToClientMessage::kTypeCrashDumpComplete); client_sock,
ExceptionHandlerProtocol::ServerToClientMessage::kTypeCrashDumpComplete);
} }
} // namespace crashpad } // namespace crashpad

View File

@ -82,11 +82,12 @@ class ExceptionHandlerServer {
//! \param[out] local_report_id The unique identifier for the report created //! \param[out] local_report_id The unique identifier for the report created
//! in the local report database. Optional. //! in the local report database. Optional.
//! \return `true` on success. `false` on failure with a message logged. //! \return `true` on success. `false` on failure with a message logged.
virtual bool HandleException(pid_t client_process_id, virtual bool HandleException(
const ClientInformation& info, pid_t client_process_id,
VMAddress requesting_thread_stack_address = 0, const ExceptionHandlerProtocol::ClientInformation& info,
pid_t* requesting_thread_id = nullptr, VMAddress requesting_thread_stack_address = 0,
UUID* local_report_id = nullptr) = 0; pid_t* requesting_thread_id = nullptr,
UUID* local_report_id = nullptr) = 0;
//! \brief Called on the receipt of a crash dump request from a client for a //! \brief Called on the receipt of a crash dump request from a client for a
//! crash that should be mediated by a PtraceBroker. //! crash that should be mediated by a PtraceBroker.
@ -97,10 +98,11 @@ class ExceptionHandlerServer {
//! \param[out] local_report_id The unique identifier for the report created //! \param[out] local_report_id The unique identifier for the report created
//! in the local report database. Optional. //! in the local report database. Optional.
//! \return `true` on success. `false` on failure with a message logged. //! \return `true` on success. `false` on failure with a message logged.
virtual bool HandleExceptionWithBroker(pid_t client_process_id, virtual bool HandleExceptionWithBroker(
const ClientInformation& info, pid_t client_process_id,
int broker_sock, const ExceptionHandlerProtocol::ClientInformation& info,
UUID* local_report_id = nullptr) = 0; int broker_sock,
UUID* local_report_id = nullptr) = 0;
protected: protected:
~Delegate() {} ~Delegate() {}
@ -147,10 +149,11 @@ class ExceptionHandlerServer {
bool InstallClientSocket(ScopedFileHandle socket); bool InstallClientSocket(ScopedFileHandle socket);
bool UninstallClientSocket(Event* event); bool UninstallClientSocket(Event* event);
bool ReceiveClientMessage(Event* event); bool ReceiveClientMessage(Event* event);
bool HandleCrashDumpRequest(const msghdr& msg, bool HandleCrashDumpRequest(
const ClientInformation& client_info, const msghdr& msg,
VMAddress requesting_thread_stack_address, const ExceptionHandlerProtocol::ClientInformation& client_info,
int client_sock); VMAddress requesting_thread_stack_address,
int client_sock);
std::unordered_map<int, std::unique_ptr<Event>> clients_; std::unordered_map<int, std::unique_ptr<Event>> clients_;
std::unique_ptr<Event> shutdown_event_; std::unique_ptr<Event> shutdown_event_;

View File

@ -103,7 +103,7 @@ class TestDelegate : public ExceptionHandlerServer::Delegate {
} }
bool HandleException(pid_t client_process_id, bool HandleException(pid_t client_process_id,
const ClientInformation& info, const ExceptionHandlerProtocol::ClientInformation& info,
VMAddress requesting_thread_stack_address, VMAddress requesting_thread_stack_address,
pid_t* requesting_thread_id = nullptr, pid_t* requesting_thread_id = nullptr,
UUID* local_report_id = nullptr) override { UUID* local_report_id = nullptr) override {
@ -134,10 +134,11 @@ class TestDelegate : public ExceptionHandlerServer::Delegate {
return true; return true;
} }
bool HandleExceptionWithBroker(pid_t client_process_id, bool HandleExceptionWithBroker(
const ClientInformation& info, pid_t client_process_id,
int broker_sock, const ExceptionHandlerProtocol::ClientInformation& info,
UUID* local_report_id = nullptr) override { int broker_sock,
UUID* local_report_id = nullptr) override {
PtraceClient client; PtraceClient client;
bool connected = client.Initialize(broker_sock, client_process_id); bool connected = client.Initialize(broker_sock, client_process_id);
EXPECT_TRUE(connected); EXPECT_TRUE(connected);
@ -165,10 +166,11 @@ class MockPtraceStrategyDecider : public PtraceStrategyDecider {
Strategy ChooseStrategy(int sock, const ucred& client_credentials) override { Strategy ChooseStrategy(int sock, const ucred& client_credentials) override {
if (strategy_ == Strategy::kUseBroker) { if (strategy_ == Strategy::kUseBroker) {
ServerToClientMessage message = {}; ExceptionHandlerProtocol::ServerToClientMessage message = {};
message.type = ServerToClientMessage::kTypeForkBroker; message.type =
ExceptionHandlerProtocol::ServerToClientMessage::kTypeForkBroker;
Errno status; ExceptionHandlerProtocol::Errno status;
bool result = LoggingWriteFile(sock, &message, sizeof(message)) && bool result = LoggingWriteFile(sock, &message, sizeof(message)) &&
LoggingReadFileExactly(sock, &status, sizeof(status)); LoggingReadFileExactly(sock, &status, sizeof(status));
EXPECT_TRUE(result); EXPECT_TRUE(result);
@ -220,7 +222,7 @@ class ExceptionHandlerServerTest : public testing::Test {
~CrashDumpTest() = default; ~CrashDumpTest() = default;
void MultiprocessParent() override { void MultiprocessParent() override {
ClientInformation info; ExceptionHandlerProtocol::ClientInformation info;
ASSERT_TRUE( ASSERT_TRUE(
LoggingReadFileExactly(ReadPipeHandle(), &info, sizeof(info))); LoggingReadFileExactly(ReadPipeHandle(), &info, sizeof(info)));
@ -239,7 +241,7 @@ class ExceptionHandlerServerTest : public testing::Test {
void MultiprocessChild() override { void MultiprocessChild() override {
ASSERT_EQ(close(server_test_->sock_to_client_), 0); ASSERT_EQ(close(server_test_->sock_to_client_), 0);
ClientInformation info; ExceptionHandlerProtocol::ClientInformation info;
info.exception_information_address = 42; info.exception_information_address = 42;
ASSERT_TRUE(LoggingWriteFile(WritePipeHandle(), &info, sizeof(info))); ASSERT_TRUE(LoggingWriteFile(WritePipeHandle(), &info, sizeof(info)));

View File

@ -35,7 +35,8 @@ ExceptionHandlerClient::ExceptionHandlerClient(int sock)
ExceptionHandlerClient::~ExceptionHandlerClient() = default; ExceptionHandlerClient::~ExceptionHandlerClient() = default;
int ExceptionHandlerClient::RequestCrashDump(const ClientInformation& info) { int ExceptionHandlerClient::RequestCrashDump(
const ExceptionHandlerProtocol::ClientInformation& info) {
VMAddress sp = FromPointerCast<VMAddress>(&sp); VMAddress sp = FromPointerCast<VMAddress>(&sp);
int status = SendCrashDumpRequest(info, sp); int status = SendCrashDumpRequest(info, sp);
@ -64,10 +65,12 @@ void ExceptionHandlerClient::SetCanSetPtracer(bool can_set_ptracer) {
can_set_ptracer_ = can_set_ptracer; can_set_ptracer_ = can_set_ptracer;
} }
int ExceptionHandlerClient::SendCrashDumpRequest(const ClientInformation& info, int ExceptionHandlerClient::SendCrashDumpRequest(
VMAddress stack_pointer) { const ExceptionHandlerProtocol::ClientInformation& info,
ClientToServerMessage message; VMAddress stack_pointer) {
message.type = ClientToServerMessage::kCrashDumpRequest; ExceptionHandlerProtocol::ClientToServerMessage message;
message.type =
ExceptionHandlerProtocol::ClientToServerMessage::kCrashDumpRequest;
message.requesting_thread_stack_address = stack_pointer; message.requesting_thread_stack_address = stack_pointer;
message.client_info = info; message.client_info = info;
@ -105,19 +108,19 @@ int ExceptionHandlerClient::SendCrashDumpRequest(const ClientInformation& info,
} }
int ExceptionHandlerClient::WaitForCrashDumpComplete() { int ExceptionHandlerClient::WaitForCrashDumpComplete() {
ServerToClientMessage message; ExceptionHandlerProtocol::ServerToClientMessage message;
// If the server hangs up, ReadFileExactly will return false without setting // If the server hangs up, ReadFileExactly will return false without setting
// errno. // errno.
errno = 0; errno = 0;
while (ReadFileExactly(server_sock_, &message, sizeof(message))) { while (ReadFileExactly(server_sock_, &message, sizeof(message))) {
switch (message.type) { switch (message.type) {
case ServerToClientMessage::kTypeForkBroker: { case ExceptionHandlerProtocol::ServerToClientMessage::kTypeForkBroker: {
Signals::InstallDefaultHandler(SIGCHLD); Signals::InstallDefaultHandler(SIGCHLD);
pid_t pid = fork(); pid_t pid = fork();
if (pid <= 0) { if (pid <= 0) {
Errno error = pid < 0 ? errno : 0; ExceptionHandlerProtocol::Errno error = pid < 0 ? errno : 0;
if (!WriteFile(server_sock_, &error, sizeof(error))) { if (!WriteFile(server_sock_, &error, sizeof(error))) {
return errno; return errno;
} }
@ -148,16 +151,18 @@ int ExceptionHandlerClient::WaitForCrashDumpComplete() {
continue; continue;
} }
case ServerToClientMessage::kTypeSetPtracer: { case ExceptionHandlerProtocol::ServerToClientMessage::kTypeSetPtracer: {
Errno result = SetPtracer(message.pid); ExceptionHandlerProtocol::Errno result = SetPtracer(message.pid);
if (!WriteFile(server_sock_, &result, sizeof(result))) { if (!WriteFile(server_sock_, &result, sizeof(result))) {
return errno; return errno;
} }
continue; continue;
} }
case ServerToClientMessage::kTypeCrashDumpComplete: case ExceptionHandlerProtocol::ServerToClientMessage::
case ServerToClientMessage::kTypeCrashDumpFailed: kTypeCrashDumpComplete:
case ExceptionHandlerProtocol::ServerToClientMessage::
kTypeCrashDumpFailed:
return 0; return 0;
} }

View File

@ -38,7 +38,7 @@ class ExceptionHandlerClient {
//! //!
//! \param[in] info Information about this client. //! \param[in] info Information about this client.
//! \return 0 on success or an error code on failure. //! \return 0 on success or an error code on failure.
int RequestCrashDump(const ClientInformation& info); int RequestCrashDump(const ExceptionHandlerProtocol::ClientInformation& info);
//! \brief Uses `prctl(PR_SET_PTRACER, ...)` to set the process with //! \brief Uses `prctl(PR_SET_PTRACER, ...)` to set the process with
//! process ID \a pid as the ptracer for this process. //! process ID \a pid as the ptracer for this process.
@ -53,8 +53,9 @@ class ExceptionHandlerClient {
void SetCanSetPtracer(bool can_set_ptracer); void SetCanSetPtracer(bool can_set_ptracer);
private: private:
int SendCrashDumpRequest(const ClientInformation& info, int SendCrashDumpRequest(
VMAddress stack_pointer); const ExceptionHandlerProtocol::ClientInformation& info,
VMAddress stack_pointer);
int WaitForCrashDumpComplete(); int WaitForCrashDumpComplete();
int server_sock_; int server_sock_;

View File

@ -16,10 +16,10 @@
namespace crashpad { namespace crashpad {
ClientInformation::ClientInformation() ExceptionHandlerProtocol::ClientInformation::ClientInformation()
: exception_information_address(0), sanitization_information_address(0) {} : exception_information_address(0), sanitization_information_address(0) {}
ClientToServerMessage::ClientToServerMessage() ExceptionHandlerProtocol::ClientToServerMessage::ClientToServerMessage()
: version(kVersion), type(kCrashDumpRequest), client_info() {} : version(kVersion), type(kCrashDumpRequest), client_info() {}
} // namespace crashpad } // namespace crashpad

View File

@ -19,81 +19,90 @@
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#include "base/macros.h"
#include "util/file/file_io.h" #include "util/file/file_io.h"
#include "util/misc/address_types.h" #include "util/misc/address_types.h"
namespace crashpad { namespace crashpad {
class ExceptionHandlerProtocol {
public:
#pragma pack(push, 1) #pragma pack(push, 1)
//! \brief The type used for error reporting. //! \brief The type used for error reporting.
using Errno = int32_t; using Errno = int32_t;
static_assert(sizeof(Errno) >= sizeof(errno), "Errno type is too small"); static_assert(sizeof(Errno) >= sizeof(errno), "Errno type is too small");
//! \brief A boolean status suitable for communication between processes. //! \brief A boolean status suitable for communication between processes.
enum Bool : char { kBoolFalse, kBoolTrue }; enum Bool : char { kBoolFalse, kBoolTrue };
//! \brief Information about a client registered with an ExceptionHandlerServer. //! \brief Information about a client registered with an
struct ClientInformation { //! ExceptionHandlerServer.
//! \brief Constructs this object. struct ClientInformation {
ClientInformation(); //! \brief Constructs this object.
ClientInformation();
//! \brief The address in the client's address space of an //! \brief The address in the client's address space of an
//! ExceptionInformation struct. //! ExceptionInformation struct.
VMAddress exception_information_address; VMAddress exception_information_address;
//! \brief The address in the client's address space of a //! \brief The address in the client's address space of a
//! SanitizationInformation struct, or 0 if there is no such struct. //! SanitizationInformation struct, or 0 if there is no such struct.
VMAddress sanitization_information_address; VMAddress sanitization_information_address;
};
//! \brief The message passed from client to server.
struct ClientToServerMessage {
static constexpr int32_t kVersion = 1;
//! \brief Constructs this object.
ClientToServerMessage();
//! \brief Indicates what message version is being used.
int32_t version;
//! \brief A stack address of the thread sending the message.
VMAddress requesting_thread_stack_address;
enum Type : uint32_t {
//! \brief Used to request a crash dump for the sending client.
kCrashDumpRequest
} type;
union {
//! \brief Valid for type == kCrashDumpRequest
ClientInformation client_info;
}; };
};
//! \brief The message passed from server to client. //! \brief The message passed from client to server.
struct ServerToClientMessage { struct ClientToServerMessage {
enum Type : uint32_t { static constexpr int32_t kVersion = 1;
//! \brief Indicates that the client should fork a PtraceBroker process.
kTypeForkBroker,
//! \brief Inidicates that the client should set allow the handler to trace //! \brief Constructs this object.
//! it using PR_SET_PTRACER. ClientToServerMessage();
kTypeSetPtracer,
//! \brief Indicates that the handler has completed a requested crash dump. //! \brief Indicates what message version is being used.
kTypeCrashDumpComplete, int32_t version;
//! \brief Indicicates that the handler was unable to produce a crash dump. //! \brief A stack address of the thread sending the message.
kTypeCrashDumpFailed VMAddress requesting_thread_stack_address;
} type;
//! \brief The handler's process ID. Valid for kTypeSetPtracer. enum Type : uint32_t {
pid_t pid; //! \brief Used to request a crash dump for the sending client.
}; kCrashDumpRequest
} type;
union {
//! \brief Valid for type == kCrashDumpRequest
ClientInformation client_info;
};
};
//! \brief The message passed from server to client.
struct ServerToClientMessage {
enum Type : uint32_t {
//! \brief Indicates that the client should fork a PtraceBroker process.
kTypeForkBroker,
//! \brief Inidicates that the client should set allow the handler to
//! trace it using PR_SET_PTRACER.
kTypeSetPtracer,
//! \brief Indicates that the handler has completed a requested crash
//! dump.
kTypeCrashDumpComplete,
//! \brief Indicicates that the handler was unable to produce a crash
//! dump.
kTypeCrashDumpFailed
} type;
//! \brief The handler's process ID. Valid for kTypeSetPtracer.
pid_t pid;
};
#pragma pack(pop) #pragma pack(pop)
DISALLOW_IMPLICIT_CONSTRUCTORS(ExceptionHandlerProtocol);
};
} // namespace crashpad } // namespace crashpad
#endif // CRASHPAD_UTIL_LINUX_EXCEPTION_HANDLER_PROTOCOL_H_ #endif // CRASHPAD_UTIL_LINUX_EXCEPTION_HANDLER_PROTOCOL_H_

View File

@ -139,9 +139,10 @@ int PtraceBroker::RunImpl() {
attach_on_stack = true; attach_on_stack = true;
} }
Bool status = kBoolFalse; ExceptionHandlerProtocol::Bool status =
ExceptionHandlerProtocol::kBoolFalse;
if (attach->ResetAttach(request.tid)) { if (attach->ResetAttach(request.tid)) {
status = kBoolTrue; status = ExceptionHandlerProtocol::kBoolTrue;
if (!attach_on_stack) { if (!attach_on_stack) {
++attach_count_; ++attach_count_;
} }
@ -151,21 +152,23 @@ int PtraceBroker::RunImpl() {
return errno; return errno;
} }
if (status == kBoolFalse) { if (status == ExceptionHandlerProtocol::kBoolFalse) {
Errno error = errno; ExceptionHandlerProtocol::Errno error = errno;
if (!WriteFile(sock_, &error, sizeof(error))) { if (!WriteFile(sock_, &error, sizeof(error))) {
return errno; return errno;
} }
} }
if (attach_on_stack && status == kBoolTrue) { if (attach_on_stack && status == ExceptionHandlerProtocol::kBoolTrue) {
return RunImpl(); return RunImpl();
} }
continue; continue;
} }
case Request::kTypeIs64Bit: { case Request::kTypeIs64Bit: {
Bool is_64_bit = ptracer_.Is64Bit() ? kBoolTrue : kBoolFalse; ExceptionHandlerProtocol::Bool is_64_bit =
ptracer_.Is64Bit() ? ExceptionHandlerProtocol::kBoolTrue
: ExceptionHandlerProtocol::kBoolFalse;
if (!WriteFile(sock_, &is_64_bit, sizeof(is_64_bit))) { if (!WriteFile(sock_, &is_64_bit, sizeof(is_64_bit))) {
return errno; return errno;
} }
@ -175,15 +178,15 @@ int PtraceBroker::RunImpl() {
case Request::kTypeGetThreadInfo: { case Request::kTypeGetThreadInfo: {
GetThreadInfoResponse response; GetThreadInfoResponse response;
response.success = ptracer_.GetThreadInfo(request.tid, &response.info) response.success = ptracer_.GetThreadInfo(request.tid, &response.info)
? kBoolTrue ? ExceptionHandlerProtocol::kBoolTrue
: kBoolFalse; : ExceptionHandlerProtocol::kBoolFalse;
if (!WriteFile(sock_, &response, sizeof(response))) { if (!WriteFile(sock_, &response, sizeof(response))) {
return errno; return errno;
} }
if (response.success == kBoolFalse) { if (response.success == ExceptionHandlerProtocol::kBoolFalse) {
Errno error = errno; ExceptionHandlerProtocol::Errno error = errno;
if (!WriteFile(sock_, &error, sizeof(error))) { if (!WriteFile(sock_, &error, sizeof(error))) {
return errno; return errno;
} }
@ -249,7 +252,7 @@ int PtraceBroker::RunImpl() {
} }
} }
int PtraceBroker::SendError(Errno err) { int PtraceBroker::SendError(ExceptionHandlerProtocol::Errno err) {
return WriteFile(sock_, &err, sizeof(err)) ? 0 : errno; return WriteFile(sock_, &err, sizeof(err)) ? 0 : errno;
} }

View File

@ -146,7 +146,7 @@ class PtraceBroker {
ThreadInfo info; ThreadInfo info;
//! \brief Specifies the success or failure of this call. //! \brief Specifies the success or failure of this call.
Bool success; ExceptionHandlerProtocol::Bool success;
}; };
#pragma pack(pop) #pragma pack(pop)
@ -196,7 +196,7 @@ class PtraceBroker {
bool AllocateAttachments(); bool AllocateAttachments();
void ReleaseAttachments(); void ReleaseAttachments();
int RunImpl(); int RunImpl();
int SendError(Errno err); int SendError(ExceptionHandlerProtocol::Errno err);
int SendReadError(ReadError err); int SendReadError(ReadError err);
int SendOpenResult(OpenResult result); int SendOpenResult(OpenResult result);
int SendFileContents(FileHandle handle); int SendFileContents(FileHandle handle);

View File

@ -31,7 +31,7 @@ namespace crashpad {
namespace { namespace {
bool ReceiveAndLogError(int sock, const std::string& operation) { bool ReceiveAndLogError(int sock, const std::string& operation) {
Errno error; ExceptionHandlerProtocol::Errno error;
if (!LoggingReadFileExactly(sock, &error, sizeof(error))) { if (!LoggingReadFileExactly(sock, &error, sizeof(error))) {
return false; return false;
} }
@ -69,12 +69,12 @@ bool AttachImpl(int sock, pid_t tid) {
return false; return false;
} }
Bool success; ExceptionHandlerProtocol::Bool success;
if (!LoggingReadFileExactly(sock, &success, sizeof(success))) { if (!LoggingReadFileExactly(sock, &success, sizeof(success))) {
return false; return false;
} }
if (success != kBoolTrue) { if (success != ExceptionHandlerProtocol::kBoolTrue) {
ReceiveAndLogError(sock, "PtraceBroker Attach"); ReceiveAndLogError(sock, "PtraceBroker Attach");
return false; return false;
} }
@ -159,11 +159,11 @@ bool PtraceClient::Initialize(int sock, pid_t pid, bool try_direct_memory) {
return false; return false;
} }
Bool is_64_bit; ExceptionHandlerProtocol::Bool is_64_bit;
if (!LoggingReadFileExactly(sock_, &is_64_bit, sizeof(is_64_bit))) { if (!LoggingReadFileExactly(sock_, &is_64_bit, sizeof(is_64_bit))) {
return false; return false;
} }
is_64_bit_ = is_64_bit == kBoolTrue; is_64_bit_ = is_64_bit == ExceptionHandlerProtocol::kBoolTrue;
if (try_direct_memory) { if (try_direct_memory) {
auto direct_mem = std::make_unique<ProcessMemoryLinux>(); auto direct_mem = std::make_unique<ProcessMemoryLinux>();
@ -209,7 +209,7 @@ bool PtraceClient::GetThreadInfo(pid_t tid, ThreadInfo* info) {
return false; return false;
} }
if (response.success == kBoolTrue) { if (response.success == ExceptionHandlerProtocol::kBoolTrue) {
*info = response.info; *info = response.info;
return true; return true;
} }