mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 14:06:33 +00:00
Add UMA to exception handler exception catching
Includes mini_chromium DEPS roll for: 88e0a3e Add stub of sparse_histogram.h R=mark@chromium.org BUG=crashpad:100 Change-Id: I4c541a33be0f7f47e972af638d4765bd06682acf Reviewed-on: https://chromium-review.googlesource.com/386385 Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
23d31c4fea
commit
b48e9bfbab
2
DEPS
2
DEPS
@ -25,7 +25,7 @@ deps = {
|
|||||||
'93cc6e2c23e4d5ebd179f388e67aa907d0dfd43d',
|
'93cc6e2c23e4d5ebd179f388e67aa907d0dfd43d',
|
||||||
'crashpad/third_party/mini_chromium/mini_chromium':
|
'crashpad/third_party/mini_chromium/mini_chromium':
|
||||||
Var('chromium_git') + '/chromium/mini_chromium@' +
|
Var('chromium_git') + '/chromium/mini_chromium@' +
|
||||||
'438bd4f4d8d38dd5c31e78a0d605cc4cf6be5229',
|
'88e0a3e1a965c698d7ead8bcfc0cfb6aacdc3524',
|
||||||
'buildtools':
|
'buildtools':
|
||||||
Var('chromium_git') + '/chromium/buildtools.git@' +
|
Var('chromium_git') + '/chromium/buildtools.git@' +
|
||||||
'f8fc76ea5ce4a60cda2fa5d7df3d4a62935b3113',
|
'f8fc76ea5ce4a60cda2fa5d7df3d4a62935b3113',
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "util/mach/mach_message.h"
|
#include "util/mach/mach_message.h"
|
||||||
#include "util/mach/scoped_task_suspend.h"
|
#include "util/mach/scoped_task_suspend.h"
|
||||||
#include "util/mach/symbolic_constants_mach.h"
|
#include "util/mach/symbolic_constants_mach.h"
|
||||||
|
#include "util/misc/metrics.h"
|
||||||
#include "util/misc/tri_state.h"
|
#include "util/misc/tri_state.h"
|
||||||
#include "util/misc/uuid.h"
|
#include "util/misc/uuid.h"
|
||||||
|
|
||||||
@ -64,6 +65,8 @@ kern_return_t CrashReportExceptionHandler::CatchMachException(
|
|||||||
mach_msg_type_number_t* new_state_count,
|
mach_msg_type_number_t* new_state_count,
|
||||||
const mach_msg_trailer_t* trailer,
|
const mach_msg_trailer_t* trailer,
|
||||||
bool* destroy_complex_request) {
|
bool* destroy_complex_request) {
|
||||||
|
Metrics::ExceptionEncountered();
|
||||||
|
Metrics::ExceptionCode(exception);
|
||||||
*destroy_complex_request = true;
|
*destroy_complex_request = true;
|
||||||
|
|
||||||
// The expected behavior is EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES,
|
// The expected behavior is EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES,
|
||||||
@ -74,6 +77,8 @@ kern_return_t CrashReportExceptionHandler::CatchMachException(
|
|||||||
"unexpected exception behavior %s, rejecting",
|
"unexpected exception behavior %s, rejecting",
|
||||||
ExceptionBehaviorToString(
|
ExceptionBehaviorToString(
|
||||||
behavior, kUseFullName | kUnknownIsNumeric | kUseOr).c_str());
|
behavior, kUseFullName | kUnknownIsNumeric | kUseOr).c_str());
|
||||||
|
Metrics::ExceptionCaptureResult(
|
||||||
|
Metrics::CaptureResult::kUnexpectedExceptionBehavior);
|
||||||
return KERN_FAILURE;
|
return KERN_FAILURE;
|
||||||
} else if (behavior != (EXCEPTION_STATE_IDENTITY | kMachExceptionCodes)) {
|
} else if (behavior != (EXCEPTION_STATE_IDENTITY | kMachExceptionCodes)) {
|
||||||
LOG(WARNING) << base::StringPrintf(
|
LOG(WARNING) << base::StringPrintf(
|
||||||
@ -84,6 +89,8 @@ kern_return_t CrashReportExceptionHandler::CatchMachException(
|
|||||||
|
|
||||||
if (task == mach_task_self()) {
|
if (task == mach_task_self()) {
|
||||||
LOG(ERROR) << "cannot suspend myself";
|
LOG(ERROR) << "cannot suspend myself";
|
||||||
|
Metrics::ExceptionCaptureResult(
|
||||||
|
Metrics::CaptureResult::kFailedDueToSuspendSelf);
|
||||||
return KERN_FAILURE;
|
return KERN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +98,7 @@ kern_return_t CrashReportExceptionHandler::CatchMachException(
|
|||||||
|
|
||||||
ProcessSnapshotMac process_snapshot;
|
ProcessSnapshotMac process_snapshot;
|
||||||
if (!process_snapshot.Initialize(task)) {
|
if (!process_snapshot.Initialize(task)) {
|
||||||
|
Metrics::ExceptionCaptureResult(Metrics::CaptureResult::kSnapshotFailed);
|
||||||
return KERN_FAILURE;
|
return KERN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,6 +134,8 @@ kern_return_t CrashReportExceptionHandler::CatchMachException(
|
|||||||
*flavor,
|
*flavor,
|
||||||
old_state,
|
old_state,
|
||||||
old_state_count)) {
|
old_state_count)) {
|
||||||
|
Metrics::ExceptionCaptureResult(
|
||||||
|
Metrics::CaptureResult::kExceptionInitializationFailed);
|
||||||
return KERN_FAILURE;
|
return KERN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,6 +155,8 @@ kern_return_t CrashReportExceptionHandler::CatchMachException(
|
|||||||
CrashReportDatabase::OperationStatus database_status =
|
CrashReportDatabase::OperationStatus database_status =
|
||||||
database_->PrepareNewCrashReport(&new_report);
|
database_->PrepareNewCrashReport(&new_report);
|
||||||
if (database_status != CrashReportDatabase::kNoError) {
|
if (database_status != CrashReportDatabase::kNoError) {
|
||||||
|
Metrics::ExceptionCaptureResult(
|
||||||
|
Metrics::CaptureResult::kPrepareNewCrashReportFailed);
|
||||||
return KERN_FAILURE;
|
return KERN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,6 +170,8 @@ kern_return_t CrashReportExceptionHandler::CatchMachException(
|
|||||||
MinidumpFileWriter minidump;
|
MinidumpFileWriter minidump;
|
||||||
minidump.InitializeFromSnapshot(&process_snapshot);
|
minidump.InitializeFromSnapshot(&process_snapshot);
|
||||||
if (!minidump.WriteEverything(&file_writer)) {
|
if (!minidump.WriteEverything(&file_writer)) {
|
||||||
|
Metrics::ExceptionCaptureResult(
|
||||||
|
Metrics::CaptureResult::kMinidumpWriteFailed);
|
||||||
return KERN_FAILURE;
|
return KERN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,6 +180,8 @@ kern_return_t CrashReportExceptionHandler::CatchMachException(
|
|||||||
UUID uuid;
|
UUID uuid;
|
||||||
database_status = database_->FinishedWritingCrashReport(new_report, &uuid);
|
database_status = database_->FinishedWritingCrashReport(new_report, &uuid);
|
||||||
if (database_status != CrashReportDatabase::kNoError) {
|
if (database_status != CrashReportDatabase::kNoError) {
|
||||||
|
Metrics::ExceptionCaptureResult(
|
||||||
|
Metrics::CaptureResult::kFinishedWritingCrashReportFailed);
|
||||||
return KERN_FAILURE;
|
return KERN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,6 +239,7 @@ kern_return_t CrashReportExceptionHandler::CatchMachException(
|
|||||||
ExcServerCopyState(
|
ExcServerCopyState(
|
||||||
behavior, old_state, old_state_count, new_state, new_state_count);
|
behavior, old_state, old_state_count, new_state, new_state_count);
|
||||||
|
|
||||||
|
Metrics::ExceptionCaptureResult(Metrics::CaptureResult::kSuccess);
|
||||||
return ExcServerSuccessfulReturnValue(exception, behavior, false);
|
return ExcServerSuccessfulReturnValue(exception, behavior, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "minidump/minidump_file_writer.h"
|
#include "minidump/minidump_file_writer.h"
|
||||||
#include "snapshot/win/process_snapshot_win.h"
|
#include "snapshot/win/process_snapshot_win.h"
|
||||||
#include "util/file/file_writer.h"
|
#include "util/file/file_writer.h"
|
||||||
|
#include "util/misc/metrics.h"
|
||||||
#include "util/win/registration_protocol_win.h"
|
#include "util/win/registration_protocol_win.h"
|
||||||
#include "util/win/scoped_process_suspend.h"
|
#include "util/win/scoped_process_suspend.h"
|
||||||
|
|
||||||
@ -46,6 +47,8 @@ unsigned int CrashReportExceptionHandler::ExceptionHandlerServerException(
|
|||||||
WinVMAddress debug_critical_section_address) {
|
WinVMAddress debug_critical_section_address) {
|
||||||
const unsigned int kFailedTerminationCode = 0xffff7002;
|
const unsigned int kFailedTerminationCode = 0xffff7002;
|
||||||
|
|
||||||
|
Metrics::ExceptionEncountered();
|
||||||
|
|
||||||
ScopedProcessSuspend suspend(process);
|
ScopedProcessSuspend suspend(process);
|
||||||
|
|
||||||
ProcessSnapshotWin process_snapshot;
|
ProcessSnapshotWin process_snapshot;
|
||||||
@ -54,6 +57,7 @@ unsigned int CrashReportExceptionHandler::ExceptionHandlerServerException(
|
|||||||
exception_information_address,
|
exception_information_address,
|
||||||
debug_critical_section_address)) {
|
debug_critical_section_address)) {
|
||||||
LOG(WARNING) << "ProcessSnapshotWin::Initialize failed";
|
LOG(WARNING) << "ProcessSnapshotWin::Initialize failed";
|
||||||
|
Metrics::ExceptionCaptureResult(Metrics::CaptureResult::kSnapshotFailed);
|
||||||
return kFailedTerminationCode;
|
return kFailedTerminationCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,6 +66,8 @@ unsigned int CrashReportExceptionHandler::ExceptionHandlerServerException(
|
|||||||
const unsigned int termination_code =
|
const unsigned int termination_code =
|
||||||
process_snapshot.Exception()->Exception();
|
process_snapshot.Exception()->Exception();
|
||||||
|
|
||||||
|
Metrics::ExceptionCode(termination_code);
|
||||||
|
|
||||||
CrashpadInfoClientOptions client_options;
|
CrashpadInfoClientOptions client_options;
|
||||||
process_snapshot.GetCrashpadOptions(&client_options);
|
process_snapshot.GetCrashpadOptions(&client_options);
|
||||||
if (client_options.crashpad_handler_behavior != TriState::kDisabled) {
|
if (client_options.crashpad_handler_behavior != TriState::kDisabled) {
|
||||||
@ -82,6 +88,8 @@ unsigned int CrashReportExceptionHandler::ExceptionHandlerServerException(
|
|||||||
database_->PrepareNewCrashReport(&new_report);
|
database_->PrepareNewCrashReport(&new_report);
|
||||||
if (database_status != CrashReportDatabase::kNoError) {
|
if (database_status != CrashReportDatabase::kNoError) {
|
||||||
LOG(ERROR) << "PrepareNewCrashReport failed";
|
LOG(ERROR) << "PrepareNewCrashReport failed";
|
||||||
|
Metrics::ExceptionCaptureResult(
|
||||||
|
Metrics::CaptureResult::kPrepareNewCrashReportFailed);
|
||||||
return termination_code;
|
return termination_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,6 +104,8 @@ unsigned int CrashReportExceptionHandler::ExceptionHandlerServerException(
|
|||||||
minidump.InitializeFromSnapshot(&process_snapshot);
|
minidump.InitializeFromSnapshot(&process_snapshot);
|
||||||
if (!minidump.WriteEverything(&file_writer)) {
|
if (!minidump.WriteEverything(&file_writer)) {
|
||||||
LOG(ERROR) << "WriteEverything failed";
|
LOG(ERROR) << "WriteEverything failed";
|
||||||
|
Metrics::ExceptionCaptureResult(
|
||||||
|
Metrics::CaptureResult::kMinidumpWriteFailed);
|
||||||
return termination_code;
|
return termination_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,12 +115,15 @@ unsigned int CrashReportExceptionHandler::ExceptionHandlerServerException(
|
|||||||
database_status = database_->FinishedWritingCrashReport(new_report, &uuid);
|
database_status = database_->FinishedWritingCrashReport(new_report, &uuid);
|
||||||
if (database_status != CrashReportDatabase::kNoError) {
|
if (database_status != CrashReportDatabase::kNoError) {
|
||||||
LOG(ERROR) << "FinishedWritingCrashReport failed";
|
LOG(ERROR) << "FinishedWritingCrashReport failed";
|
||||||
|
Metrics::ExceptionCaptureResult(
|
||||||
|
Metrics::CaptureResult::kFinishedWritingCrashReportFailed);
|
||||||
return termination_code;
|
return termination_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
upload_thread_->ReportPending();
|
upload_thread_->ReportPending();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Metrics::ExceptionCaptureResult(Metrics::CaptureResult::kSuccess);
|
||||||
return termination_code;
|
return termination_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,13 +15,32 @@
|
|||||||
#include "util/misc/metrics.h"
|
#include "util/misc/metrics.h"
|
||||||
|
|
||||||
#include "base/metrics/histogram_macros.h"
|
#include "base/metrics/histogram_macros.h"
|
||||||
|
#include "base/metrics/sparse_histogram.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
|
|
||||||
|
// static
|
||||||
void Metrics::CrashReportSize(FileHandle file) {
|
void Metrics::CrashReportSize(FileHandle file) {
|
||||||
const FileOffset size = LoggingFileSizeByHandle(file);
|
const FileOffset size = LoggingFileSizeByHandle(file);
|
||||||
UMA_HISTOGRAM_CUSTOM_COUNTS(
|
UMA_HISTOGRAM_CUSTOM_COUNTS(
|
||||||
"Crashpad.CrashReportSize", size, 0, 5 * 1024 * 1024, 50);
|
"Crashpad.CrashReportSize", size, 0, 5 * 1024 * 1024, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void Metrics::ExceptionCaptureResult(CaptureResult result) {
|
||||||
|
UMA_HISTOGRAM_ENUMERATION(
|
||||||
|
"Crashpad.ExceptionCaptureResult", result, CaptureResult::kMaxValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void Metrics::ExceptionCode(uint32_t code) {
|
||||||
|
UMA_HISTOGRAM_SPARSE_SLOWLY("Crashpad.ExceptionCode",
|
||||||
|
static_cast<int32_t>(code));
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void Metrics::ExceptionEncountered() {
|
||||||
|
UMA_HISTOGRAM_COUNTS("Crashpad.ExceptionEncountered", 1);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace crashpad
|
} // namespace crashpad
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#ifndef CRASHPAD_UTIL_MISC_METRICS_H_
|
#ifndef CRASHPAD_UTIL_MISC_METRICS_H_
|
||||||
#define CRASHPAD_UTIL_MISC_METRICS_H_
|
#define CRASHPAD_UTIL_MISC_METRICS_H_
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
#include "util/file/file_io.h"
|
#include "util/file/file_io.h"
|
||||||
|
|
||||||
@ -32,6 +34,55 @@ class Metrics {
|
|||||||
//! when a new report is written to disk.
|
//! when a new report is written to disk.
|
||||||
static void CrashReportSize(FileHandle file);
|
static void CrashReportSize(FileHandle file);
|
||||||
|
|
||||||
|
//! \brief The result of capturing an exception. These are used as metrics
|
||||||
|
//! enumeration values so new values should always be added at the end.
|
||||||
|
enum class CaptureResult : int {
|
||||||
|
//! \brief The exception capture succeeded normally.
|
||||||
|
kSuccess = 0,
|
||||||
|
|
||||||
|
//! \brief Unexpected exception behavior.
|
||||||
|
//!
|
||||||
|
//! This value is only used on Mac OS X.
|
||||||
|
kUnexpectedExceptionBehavior = 1,
|
||||||
|
|
||||||
|
//! \brief Failed due to attempt to suspend self.
|
||||||
|
//!
|
||||||
|
//! This value is only used on Mac OS X.
|
||||||
|
kFailedDueToSuspendSelf = 2,
|
||||||
|
|
||||||
|
//! \brief The process snapshot could not be captured.
|
||||||
|
kSnapshotFailed = 3,
|
||||||
|
|
||||||
|
//! \brief The exception could not be initialized.
|
||||||
|
kExceptionInitializationFailed = 4,
|
||||||
|
|
||||||
|
//! \brief The attempt to prepare a new crash report in the crash database
|
||||||
|
//! failed.
|
||||||
|
kPrepareNewCrashReportFailed = 5,
|
||||||
|
|
||||||
|
//! \brief Writing the minidump to disk failed.
|
||||||
|
kMinidumpWriteFailed = 6,
|
||||||
|
|
||||||
|
//! \brief There was a database error in attempt to complete the report.
|
||||||
|
kFinishedWritingCrashReportFailed = 7,
|
||||||
|
|
||||||
|
//! \brief The number of values in this enumeration; not a valid value.
|
||||||
|
kMaxValue
|
||||||
|
};
|
||||||
|
|
||||||
|
//! \brief Reports on the outcome of capturing a report in the exception
|
||||||
|
//! handler.
|
||||||
|
static void ExceptionCaptureResult(CaptureResult result);
|
||||||
|
|
||||||
|
//! \brief The exception code for an exception was retrieved.
|
||||||
|
//!
|
||||||
|
//! These values are OS-specific, and correspond to
|
||||||
|
//! MINIDUMP_EXCEPTION::ExceptionCode.
|
||||||
|
static void ExceptionCode(uint32_t exception_code);
|
||||||
|
|
||||||
|
//! \brief The exception handler server started capturing an exception.
|
||||||
|
static void ExceptionEncountered();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(Metrics);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(Metrics);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user