mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 14:06:33 +00:00
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:
parent
93366d782a
commit
c96226c6ba
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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_;
|
||||||
|
@ -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)));
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_;
|
||||||
|
@ -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
|
||||||
|
@ -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_
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user