android/linux: add a client interface to control sanitization

Sanitization is controlled by a SanitizationInformation struct to be
read from the client's memory. The address of this struct is either
passed in a ClientInformation when the client requests a crash dump,
or as a flag to the handler --sanitization_information.

Bug: crashpad:30
Change-Id: I2744f8fb85b4fea7362b2b88faa4bef1da74e36b
Reviewed-on: https://chromium-review.googlesource.com/1083143
Commit-Queue: Joshua Peraza <jperaza@chromium.org>
Reviewed-by: Scott Graham <scottmg@chromium.org>
This commit is contained in:
Joshua Peraza 2018-06-12 08:30:36 -07:00 committed by Commit Bot
parent a42b5269b4
commit d1e6a2130d
18 changed files with 385 additions and 47 deletions

View File

@ -28,6 +28,7 @@
#include "gtest/gtest.h"
#include "snapshot/annotation_snapshot.h"
#include "snapshot/minidump/process_snapshot_minidump.h"
#include "snapshot/sanitized/sanitization_information.h"
#include "test/multiprocess.h"
#include "test/multiprocess_exec.h"
#include "test/scoped_temp_dir.h"
@ -210,7 +211,9 @@ class StartHandlerForClientTest {
StartHandlerForClientTest() = default;
~StartHandlerForClientTest() = default;
bool Initialize() {
bool Initialize(bool sanitize) {
sanitize_ = sanitize;
int socks[2];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) != 0) {
PLOG(ERROR) << "socketpair";
@ -253,19 +256,23 @@ class StartHandlerForClientTest {
ASSERT_TRUE(database);
std::vector<CrashReportDatabase::Report> reports;
ASSERT_EQ(database->GetPendingReports(&reports),
CrashReportDatabase::kNoError);
EXPECT_EQ(reports.size(), 1u);
reports.clear();
ASSERT_EQ(database->GetCompletedReports(&reports),
CrashReportDatabase::kNoError);
EXPECT_EQ(reports.size(), 0u);
reports.clear();
ASSERT_EQ(database->GetPendingReports(&reports),
CrashReportDatabase::kNoError);
if (sanitize_) {
EXPECT_EQ(reports.size(), 0u);
} else {
EXPECT_EQ(reports.size(), 1u);
}
}
bool InstallHandler() {
auto signal_handler = SandboxedHandler::Get();
return signal_handler->Initialize(client_sock_.get());
return signal_handler->Initialize(client_sock_.get(), sanitize_);
}
private:
@ -278,8 +285,9 @@ class StartHandlerForClientTest {
return instance;
}
bool Initialize(FileHandle client_sock) {
bool Initialize(FileHandle client_sock, bool sanitize) {
client_sock_ = client_sock;
sanitize_ = sanitize;
return Signals::InstallCrashHandlers(HandleCrash, 0, nullptr);
}
@ -302,11 +310,20 @@ class StartHandlerForClientTest {
context);
exception_information.thread_id = syscall(SYS_gettid);
ClientInformation info = {};
ClientInformation info;
info.exception_information_address =
FromPointerCast<decltype(info.exception_information_address)>(
&exception_information);
SanitizationInformation sanitization_info = {};
if (state->sanitize_) {
info.sanitization_information_address =
FromPointerCast<VMAddress>(&sanitization_info);
// Target a non-module address to prevent a crash dump.
sanitization_info.target_module_address =
FromPointerCast<VMAddress>(&sanitization_info);
}
ExceptionHandlerClient handler_client(state->client_sock_);
CHECK_EQ(handler_client.RequestCrashDump(info), 0);
@ -314,6 +331,7 @@ class StartHandlerForClientTest {
}
FileHandle client_sock_;
bool sanitize_;
DISALLOW_COPY_AND_ASSIGN(SandboxedHandler);
};
@ -321,6 +339,7 @@ class StartHandlerForClientTest {
ScopedTempDir temp_dir_;
ScopedFileHandle client_sock_;
ScopedFileHandle server_sock_;
bool sanitize_;
DISALLOW_COPY_AND_ASSIGN(StartHandlerForClientTest);
};
@ -331,9 +350,9 @@ class StartHandlerForChildTest : public Multiprocess {
StartHandlerForChildTest() = default;
~StartHandlerForChildTest() = default;
bool Initialize() {
bool Initialize(bool sanitize) {
SetExpectedChildTerminationBuiltinTrap();
return test_state_.Initialize();
return test_state_.Initialize(sanitize);
}
private:
@ -361,7 +380,13 @@ class StartHandlerForChildTest : public Multiprocess {
TEST(CrashpadClient, StartHandlerForChild) {
StartHandlerForChildTest test;
ASSERT_TRUE(test.Initialize());
ASSERT_TRUE(test.Initialize(/* sanitize= */ false));
test.Run();
}
TEST(CrashpadClient, SanitizedChild) {
StartHandlerForChildTest test;
ASSERT_TRUE(test.Initialize(/* sanitize= */ true));
test.Run();
}

View File

@ -144,6 +144,8 @@ void Usage(const base::FilePath& me) {
" --trace-parent-with-exception=EXCEPTION_INFORMATION_ADDRESS\n"
" request a dump for the handler's parent process\n"
" --initial-client-fd=FD a socket connected to a client.\n"
" --sanitization_information=SANITIZATION_INFORMATION_ADDRESS\n"
" the address of a SanitizationInformation struct.\n"
#endif // OS_LINUX || OS_ANDROID
" --url=URL send crash reports to this Breakpad server URL,\n"
" only if uploads are enabled for the database\n"
@ -167,6 +169,7 @@ struct Options {
#elif defined(OS_LINUX) || defined(OS_ANDROID)
VMAddress exception_information_address;
int initial_client_fd;
VMAddress sanitization_information_address;
#elif defined(OS_WIN)
std::string pipe_name;
InitialClientData initial_client_data;
@ -535,6 +538,7 @@ int HandlerMain(int argc,
#if defined(OS_LINUX) || defined(OS_ANDROID)
kOptionTraceParentWithException,
kOptionInitialClientFD,
kOptionSanitizationInformation,
#endif
kOptionURL,
@ -590,6 +594,10 @@ int HandlerMain(int argc,
nullptr,
kOptionTraceParentWithException},
{"initial-client-fd", required_argument, nullptr, kOptionInitialClientFD},
{"sanitization-information",
required_argument,
nullptr,
kOptionSanitizationInformation},
#endif // OS_LINUX || OS_ANDROID
{"url", required_argument, nullptr, kOptionURL},
{"help", no_argument, nullptr, kOptionHelp},
@ -608,6 +616,7 @@ int HandlerMain(int argc,
#if defined(OS_LINUX) || defined(OS_ANDROID)
options.exception_information_address = 0;
options.initial_client_fd = kInvalidFileHandle;
options.sanitization_information_address = 0;
#endif
int opt;
@ -714,6 +723,15 @@ int HandlerMain(int argc,
}
break;
}
case kOptionSanitizationInformation: {
if (!StringToNumber(optarg,
&options.sanitization_information_address)) {
ToolSupport::UsageHint(me,
"failed to parse --sanitization-information");
return ExitFailure();
}
break;
}
#endif // OS_LINUX || OS_ANDROID
case kOptionURL: {
options.url = optarg;
@ -762,9 +780,15 @@ int HandlerMain(int argc,
#elif defined(OS_LINUX) || defined(OS_ANDROID)
if (!options.exception_information_address &&
options.initial_client_fd == kInvalidFileHandle) {
ToolSupport::UsageHint(
me, "--trace-parent-with-exception or --initial_client_fd is required");
return ExitFailure();
}
if (options.sanitization_information_address &&
!options.exception_information_address) {
ToolSupport::UsageHint(
me,
"--exception_information_address or --initial_client_fd is required");
"--sanitization_information requires --trace-parent-with-exception");
return ExitFailure();
}
#endif // OS_MACOSX
@ -844,9 +868,12 @@ int HandlerMain(int argc,
#if defined(OS_LINUX) || defined(OS_ANDROID)
if (options.exception_information_address) {
return exception_handler.HandleException(getppid(),
options.exception_information_address) ?
EXIT_SUCCESS : ExitFailure();
ClientInformation info;
info.exception_information_address = options.exception_information_address;
info.sanitization_information_address =
options.sanitization_information_address;
return exception_handler.HandleException(getppid(), info) ? EXIT_SUCCESS
: ExitFailure();
}
#endif // OS_LINUX || OS_ANDROID

View File

@ -21,6 +21,8 @@
#include "minidump/minidump_file_writer.h"
#include "snapshot/crashpad_info_client_options.h"
#include "snapshot/linux/process_snapshot_linux.h"
#include "snapshot/sanitized/process_snapshot_sanitized.h"
#include "snapshot/sanitized/sanitization_information.h"
#include "util/linux/direct_ptrace_connection.h"
#include "util/linux/ptrace_client.h"
#include "util/misc/metrics.h"
@ -43,7 +45,7 @@ CrashReportExceptionHandler::~CrashReportExceptionHandler() = default;
bool CrashReportExceptionHandler::HandleException(
pid_t client_process_id,
VMAddress exception_info_address) {
const ClientInformation& info) {
Metrics::ExceptionEncountered();
DirectPtraceConnection connection;
@ -53,12 +55,12 @@ bool CrashReportExceptionHandler::HandleException(
return false;
}
return HandleExceptionWithConnection(&connection, exception_info_address);
return HandleExceptionWithConnection(&connection, info);
}
bool CrashReportExceptionHandler::HandleExceptionWithBroker(
pid_t client_process_id,
VMAddress exception_info_address,
const ClientInformation& info,
int broker_sock) {
Metrics::ExceptionEncountered();
@ -69,19 +71,20 @@ bool CrashReportExceptionHandler::HandleExceptionWithBroker(
return false;
}
return HandleExceptionWithConnection(&client, exception_info_address);
return HandleExceptionWithConnection(&client, info);
}
bool CrashReportExceptionHandler::HandleExceptionWithConnection(
PtraceConnection* connection,
VMAddress exception_info_address) {
const ClientInformation& info) {
ProcessSnapshotLinux process_snapshot;
if (!process_snapshot.Initialize(connection)) {
Metrics::ExceptionCaptureResult(Metrics::CaptureResult::kSnapshotFailed);
return false;
}
if (!process_snapshot.InitializeException(exception_info_address)) {
if (!process_snapshot.InitializeException(
info.exception_information_address)) {
Metrics::ExceptionCaptureResult(
Metrics::CaptureResult::kExceptionInitializationFailed);
return false;
@ -116,10 +119,50 @@ bool CrashReportExceptionHandler::HandleExceptionWithConnection(
process_snapshot.SetReportID(new_report->ReportID());
ProcessSnapshot* snapshot = nullptr;
ProcessSnapshotSanitized sanitized;
std::vector<std::string> whitelist;
if (info.sanitization_information_address) {
SanitizationInformation sanitization_info;
ProcessMemoryRange range;
if (!range.Initialize(connection->Memory(), connection->Is64Bit()) ||
!range.Read(info.sanitization_information_address,
sizeof(sanitization_info),
&sanitization_info)) {
Metrics::ExceptionCaptureResult(
Metrics::CaptureResult::kSanitizationInitializationFailed);
return false;
}
if (sanitization_info.annotations_whitelist_address &&
!ReadAnnotationsWhitelist(
range,
sanitization_info.annotations_whitelist_address,
&whitelist)) {
Metrics::ExceptionCaptureResult(
Metrics::CaptureResult::kSanitizationInitializationFailed);
return false;
}
if (!sanitized.Initialize(&process_snapshot,
sanitization_info.annotations_whitelist_address
? &whitelist
: nullptr,
sanitization_info.target_module_address,
sanitization_info.sanitize_stacks)) {
Metrics::ExceptionCaptureResult(
Metrics::CaptureResult::kSkippedDueToSanitization);
return true;
}
snapshot = &sanitized;
} else {
snapshot = &process_snapshot;
}
MinidumpFileWriter minidump;
minidump.InitializeFromSnapshot(&process_snapshot);
AddUserExtensionStreams(
user_stream_data_sources_, &process_snapshot, &minidump);
minidump.InitializeFromSnapshot(snapshot);
AddUserExtensionStreams(user_stream_data_sources_, snapshot, &minidump);
if (!minidump.WriteEverything(new_report->Writer())) {
LOG(ERROR) << "WriteEverything failed";

View File

@ -23,6 +23,7 @@
#include "handler/crash_report_upload_thread.h"
#include "handler/linux/exception_handler_server.h"
#include "handler/user_stream_data_source.h"
#include "util/linux/exception_handler_protocol.h"
#include "util/linux/ptrace_connection.h"
#include "util/misc/address_types.h"
@ -63,15 +64,15 @@ class CrashReportExceptionHandler : public ExceptionHandlerServer::Delegate {
// ExceptionHandlerServer::Delegate:
bool HandleException(pid_t client_process_id,
VMAddress exception_info_address) override;
const ClientInformation& info) override;
bool HandleExceptionWithBroker(pid_t client_process_id,
VMAddress exception_info_address,
const ClientInformation& info,
int broker_sock) override;
private:
bool HandleExceptionWithConnection(PtraceConnection* connection,
VMAddress exception_info_address);
const ClientInformation& info);
CrashReportDatabase* database_; // weak
CrashReportUploadThread* upload_thread_; // weak

View File

@ -446,15 +446,12 @@ bool ExceptionHandlerServer::HandleCrashDumpRequest(
ServerToClientMessage::kTypeCrashDumpFailed);
case PtraceStrategyDecider::Strategy::kDirectPtrace:
delegate_->HandleException(client_process_id,
client_info.exception_information_address);
delegate_->HandleException(client_process_id, client_info);
break;
case PtraceStrategyDecider::Strategy::kUseBroker:
delegate_->HandleExceptionWithBroker(
client_process_id,
client_info.exception_information_address,
client_sock);
client_process_id, client_info, client_sock);
break;
}

View File

@ -71,23 +71,20 @@ class ExceptionHandlerServer {
//! \brief Called on receipt of a crash dump request from a client.
//!
//! \param[in] client_process_id The process ID of the crashing client.
//! \param[in] exception_information_address The address in the client's
//! address space of an ExceptionInformation struct.
//! \param[in] info Information on the client.
//! \return `true` on success. `false` on failure with a message logged.
virtual bool HandleException(pid_t client_process_id,
VMAddress exception_information_address) = 0;
const ClientInformation& info) = 0;
//! \brief Called on the receipt of a crash dump request from a client for a
//! crash that should be mediated by a PtraceBroker.
//!
//! \param[in] client_process_id The process ID of the crashing client.
//! \param[in] exception_information_address The address in the client's
//! address space of an ExceptionInformation struct.
//! \param[in] info Information on the client.
//! \param[in] broker_sock A socket connected to the PtraceBroker.
//! \return `true` on success. `false` on failure with a message logged.
virtual bool HandleExceptionWithBroker(
pid_t client_process_id,
VMAddress exception_information_address,
virtual bool HandleExceptionWithBroker(pid_t client_process_id,
const ClientInformation& info,
int broker_sock) = 0;
protected:

View File

@ -101,25 +101,25 @@ class TestDelegate : public ExceptionHandlerServer::Delegate {
}
bool HandleException(pid_t client_process_id,
VMAddress exception_information_address) override {
const ClientInformation& info) override {
DirectPtraceConnection connection;
bool connected = connection.Initialize(client_process_id);
EXPECT_TRUE(connected);
last_exception_address_ = exception_information_address;
last_exception_address_ = info.exception_information_address;
last_client_ = client_process_id;
sem_.Signal();
return connected;
}
bool HandleExceptionWithBroker(pid_t client_process_id,
VMAddress exception_information_address,
const ClientInformation& info,
int broker_sock) override {
PtraceClient client;
bool connected = client.Initialize(broker_sock, client_process_id);
EXPECT_TRUE(connected);
last_exception_address_ = exception_information_address,
last_exception_address_ = info.exception_information_address,
last_client_ = client_process_id;
sem_.Signal();
return connected;

View File

@ -128,6 +128,8 @@ static_library("snapshot") {
"sanitized/module_snapshot_sanitized.h",
"sanitized/process_snapshot_sanitized.cc",
"sanitized/process_snapshot_sanitized.h",
"sanitized/sanitization_information.cc",
"sanitized/sanitization_information.h",
"sanitized/thread_snapshot_sanitized.cc",
"sanitized/thread_snapshot_sanitized.h",
]
@ -338,6 +340,7 @@ source_set("snapshot_test") {
"linux/process_reader_linux_test.cc",
"linux/system_snapshot_linux_test.cc",
"sanitized/process_snapshot_sanitized_test.cc",
"sanitized/sanitization_information_test.cc",
]
} else {
sources += [ "crashpad_info_client_options_test.cc" ]

View File

@ -0,0 +1,61 @@
// Copyright 2018 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "snapshot/sanitized/sanitization_information.h"
#include "client/annotation.h"
namespace crashpad {
namespace {
template <typename Pointer>
bool ReadWhitelist(const ProcessMemoryRange& memory,
VMAddress whitelist_address,
std::vector<std::string>* whitelist) {
if (!whitelist_address) {
return true;
}
std::vector<std::string> local_whitelist;
Pointer name_address;
while (memory.Read(whitelist_address, sizeof(name_address), &name_address)) {
if (!name_address) {
whitelist->swap(local_whitelist);
return true;
}
std::string name;
if (!memory.ReadCStringSizeLimited(
name_address, Annotation::kNameMaxLength, &name)) {
return false;
}
local_whitelist.push_back(name);
whitelist_address += sizeof(Pointer);
}
return false;
}
} // namespace
bool ReadAnnotationsWhitelist(const ProcessMemoryRange& memory,
VMAddress whitelist_address,
std::vector<std::string>* whitelist) {
return memory.Is64Bit()
? ReadWhitelist<uint64_t>(memory, whitelist_address, whitelist)
: ReadWhitelist<uint32_t>(memory, whitelist_address, whitelist);
}
} // namespace crashpad

View File

@ -0,0 +1,68 @@
// Copyright 2018 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef CRASHPAD_SNAPSHOT_SANITIZED_SANITIZATION_INFORMATION_H_
#define CRASHPAD_SNAPSHOT_SANITIZED_SANITIZATION_INFORMATION_H_
#include <stdint.h>
#include <string>
#include <vector>
#include "util/misc/address_types.h"
#include "util/process/process_memory_range.h"
namespace crashpad {
#pragma pack(push, 1)
//! \brief Struture containing information about how snapshots should be
//! sanitized.
//!
//! \see ProcessSnapshotSanitized
struct SanitizationInformation {
//! \brief The address in the client process' address space of a nullptr
//! terminated array of NUL-terminated strings. The string values are the
//! names of whitelisted annotations. This value is 0 if there is no
//! whitelist and all annotations are allowed.
VMAddress annotations_whitelist_address;
//! \brief An address in the client process' address space within a module to
//! target. When a target module is used, crash dumps are discarded unless
//! the crashing thread's program counter or pointer-aligned values on the
//! crashing thread's stack point into the target module. This value is 0
//! if there is no target module.
VMAddress target_module_address;
//! \brief Non-zero if stacks should be sanitized for possible PII.
uint8_t sanitize_stacks;
};
#pragma pack(pop)
//! \brief Reads an annotations whitelist from another process.
//!
//! \param[in] memory A memory reader for the target process.
//! \param[in] whitelist_address The address in the target process' address
//! space of a nullptr terminated array of NUL-terminated strings.
//! \param[out] whitelist The whitelist read, valid only if this function
//! returns `true`.
//! \return `true` on success, `false` on failure with a message logged.
bool ReadAnnotationsWhitelist(const ProcessMemoryRange& memory,
VMAddress whitelist_address,
std::vector<std::string>* whitelist);
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_SANITIZED_SANITIZATION_INFORMATION_H_

View File

@ -0,0 +1,70 @@
// Copyright 2018 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "snapshot/sanitized/sanitization_information.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "util/misc/from_pointer_cast.h"
#include "util/process/process_memory_linux.h"
namespace crashpad {
namespace test {
namespace {
class WhitelistTest : public testing::Test {
public:
void SetUp() override {
ASSERT_TRUE(memory_.Initialize(getpid()));
#if defined(ARCH_CPU_64_BITS)
ASSERT_TRUE(range_.Initialize(&memory_, true));
#else
ASSERT_TRUE(range_.Initialize(&memory_, false));
#endif
}
protected:
bool ReadWhitelist(const char* const* address) {
return ReadAnnotationsWhitelist(
range_, FromPointerCast<VMAddress>(address), &whitelist_);
}
ProcessMemoryLinux memory_;
ProcessMemoryRange range_;
std::vector<std::string> whitelist_;
};
const char* const kEmptyWhitelist[] = {nullptr};
TEST_F(WhitelistTest, EmptyWhitelist) {
ASSERT_TRUE(ReadWhitelist(kEmptyWhitelist));
EXPECT_EQ(whitelist_, std::vector<std::string>());
}
const char* const kNonEmptyWhitelist[] = {"string1",
"another_string",
"",
nullptr};
TEST_F(WhitelistTest, NonEmptyWhitelist) {
ASSERT_TRUE(ReadWhitelist(kNonEmptyWhitelist));
ASSERT_EQ(whitelist_.size(), arraysize(kNonEmptyWhitelist) - 1);
for (size_t index = 0; index < arraysize(kNonEmptyWhitelist) - 1; ++index) {
EXPECT_EQ(whitelist_[index], kNonEmptyWhitelist[index]);
}
}
} // namespace
} // namespace test
} // namespace crashpad

View File

@ -129,6 +129,8 @@
'sanitized/module_snapshot_sanitized.h',
'sanitized/process_snapshot_sanitized.cc',
'sanitized/process_snapshot_sanitized.h',
'sanitized/sanitization_information.cc',
'sanitized/sanitization_information.h',
'sanitized/thread_snapshot_sanitized.cc',
'sanitized/thread_snapshot_sanitized.h',
'snapshot_constants.h',

View File

@ -93,6 +93,7 @@
'minidump/process_snapshot_minidump_test.cc',
'posix/timezone_test.cc',
'sanitized/process_snapshot_sanitized_test.cc',
'sanitized/sanitization_information_test.cc',
'win/cpu_context_win_test.cc',
'win/exception_snapshot_win_test.cc',
'win/extra_memory_ranges_test.cc',

View File

@ -281,6 +281,7 @@ static_library("util") {
"linux/direct_ptrace_connection.h",
"linux/exception_handler_client.cc",
"linux/exception_handler_client.h",
"linux/exception_handler_protocol.cc",
"linux/exception_handler_protocol.h",
"linux/exception_information.h",
"linux/memory_map.cc",

View File

@ -0,0 +1,25 @@
// Copyright 2018 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "util/linux/exception_handler_protocol.h"
namespace crashpad {
ClientInformation::ClientInformation()
: exception_information_address(0), sanitization_information_address(0) {}
ClientToServerMessage::ClientToServerMessage()
: version(kVersion), type(kCrashDumpRequest), client_info() {}
} // namespace crashpad

View File

@ -35,17 +35,27 @@ enum Bool : char { kBoolFalse, kBoolTrue };
//! \brief Information about a client registered with an ExceptionHandlerServer.
struct ClientInformation {
//! \brief Constructs this object.
ClientInformation();
//! \brief The address in the client's address space of an
//! ExceptionInformation struct.
VMAddress exception_information_address;
//! \brief The address in the client's address space of a
//! SanitizationInformation struct, or 0 if there is no such struct.
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 = kVersion;
int32_t version;
enum Type : uint32_t {
//! \brief Used to request a crash dump for the sending client.

View File

@ -129,6 +129,12 @@ class Metrics {
//! This value is only used on Linux/Android.
kBrokeredPtraceFailed = 9,
//! \brief Sanitization was requested but could not be initialized.
kSanitizationInitializationFailed = 10,
//! \brief Sanitization caused this crash dump to be skipped.
kSkippedDueToSanitization = 11,
//! \brief The number of values in this enumeration; not a valid value.
kMaxValue
};

View File

@ -60,6 +60,7 @@
'linux/direct_ptrace_connection.h',
'linux/exception_handler_client.cc',
'linux/exception_handler_client.h',
'linux/exception_handler_protocol.cc',
'linux/exception_handler_protocol.h',
'linux/exception_information.h',
'linux/memory_map.cc',