| Index: components/browser_watcher/postmortem_report_collector.cc
|
| diff --git a/components/browser_watcher/postmortem_report_collector.cc b/components/browser_watcher/postmortem_report_collector.cc
|
| index 7f5bf1457b81517991d604bfc1a754b9ef75f950..9732fd4a4e106ffb29a08e67f3a22f0b19888b4e 100644
|
| --- a/components/browser_watcher/postmortem_report_collector.cc
|
| +++ b/components/browser_watcher/postmortem_report_collector.cc
|
| @@ -36,6 +36,16 @@ namespace {
|
|
|
| const char kFieldTrialKeyPrefix[] = "FieldTrial.";
|
|
|
| +// DO NOT CHANGE VALUES. This is logged persistently in a histogram.
|
| +enum SystemSessionAnalysisStatus {
|
| + SYSTEM_SESSION_ANALYSIS_SUCCESS = 0,
|
| + SYSTEM_SESSION_ANALYSIS_NO_TIMESTAMP = 1,
|
| + SYSTEM_SESSION_ANALYSIS_NO_ANALYZER = 2,
|
| + SYSTEM_SESSION_ANALYSIS_FAILED = 3,
|
| + SYSTEM_SESSION_ANALYSIS_OUTSIDE_RANGE = 4,
|
| + SYSTEM_SESSION_ANALYSIS_STATUS_MAX = 5
|
| +};
|
| +
|
| // Collects stability user data from the recorded format to the collected
|
| // format.
|
| void CollectUserData(
|
| @@ -115,6 +125,23 @@ void CollectUserData(
|
| }
|
| }
|
|
|
| +bool GetStartTimestamp(
|
| + const google::protobuf::Map<std::string, TypedValue>& global_data,
|
| + base::Time* time) {
|
| + DCHECK(time);
|
| +
|
| + const auto& it = global_data.find(kStabilityStartTimestamp);
|
| + if (it == global_data.end())
|
| + return false;
|
| +
|
| + const TypedValue& value = it->second;
|
| + if (value.value_case() != TypedValue::kSignedValue)
|
| + return false;
|
| +
|
| + *time = base::Time::FromInternalValue(value.signed_value());
|
| + return true;
|
| +}
|
| +
|
| void CollectModuleInformation(
|
| const std::vector<GlobalActivityTracker::ModuleInfo>& modules,
|
| ProcessState* process_state) {
|
| @@ -153,12 +180,16 @@ void CollectModuleInformation(
|
| PostmortemReportCollector::PostmortemReportCollector(
|
| const std::string& product_name,
|
| const std::string& version_number,
|
| - const std::string& channel_name)
|
| + const std::string& channel_name,
|
| + SystemSessionAnalyzer* analyzer)
|
| : product_name_(product_name),
|
| version_number_(version_number),
|
| - channel_name_(channel_name) {}
|
| + channel_name_(channel_name),
|
| + system_session_analyzer_(analyzer) {}
|
|
|
| -int PostmortemReportCollector::CollectAndSubmitForUpload(
|
| +PostmortemReportCollector::~PostmortemReportCollector() {}
|
| +
|
| +int PostmortemReportCollector::CollectAndSubmitAllPendingReports(
|
| const base::FilePath& debug_info_dir,
|
| const base::FilePath::StringType& debug_file_pattern,
|
| const std::set<base::FilePath>& excluded_debug_files,
|
| @@ -184,7 +215,7 @@ int PostmortemReportCollector::CollectAndSubmitForUpload(
|
| int success_cnt = 0;
|
| for (const FilePath& file : debug_files) {
|
| CollectionStatus status =
|
| - CollectAndSubmit(client_id, file, report_database);
|
| + CollectAndSubmitOneReport(client_id, file, report_database);
|
| // TODO(manzagop): consider making this a stability metric.
|
| UMA_HISTOGRAM_ENUMERATION("ActivityTracker.Collect.Status", status,
|
| COLLECTION_STATUS_MAX);
|
| @@ -215,7 +246,7 @@ std::vector<FilePath> PostmortemReportCollector::GetDebugStateFilePaths(
|
| }
|
|
|
| PostmortemReportCollector::CollectionStatus
|
| -PostmortemReportCollector::CollectAndSubmit(
|
| +PostmortemReportCollector::CollectAndSubmitOneReport(
|
| const crashpad::UUID& client_id,
|
| const FilePath& file,
|
| crashpad::CrashReportDatabase* report_database) {
|
| @@ -227,7 +258,7 @@ PostmortemReportCollector::CollectAndSubmit(
|
| // Collect the data from the debug file to a proto. Note: a non-empty report
|
| // is interpreted here as an unclean exit.
|
| std::unique_ptr<StabilityReport> report_proto;
|
| - CollectionStatus status = Collect(file, &report_proto);
|
| + CollectionStatus status = CollectOneReport(file, &report_proto);
|
| if (status != SUCCESS) {
|
| // The file was empty, or there was an error collecting the data. Detailed
|
| // logging happens within the Collect function.
|
| @@ -279,7 +310,8 @@ PostmortemReportCollector::CollectAndSubmit(
|
| return SUCCESS;
|
| }
|
|
|
| -PostmortemReportCollector::CollectionStatus PostmortemReportCollector::Collect(
|
| +PostmortemReportCollector::CollectionStatus
|
| +PostmortemReportCollector::CollectOneReport(
|
| const base::FilePath& debug_state_file,
|
| std::unique_ptr<StabilityReport>* report) {
|
| DCHECK_NE(nullptr, report);
|
| @@ -310,24 +342,13 @@ PostmortemReportCollector::CollectionStatus PostmortemReportCollector::Collect(
|
| }
|
|
|
| // Collect global user data.
|
| - google::protobuf::Map<std::string, TypedValue>& global_data =
|
| - *(*report)->mutable_global_data();
|
| - CollectUserData(global_data_snapshot, &global_data, report->get());
|
| -
|
| - // Add the reporting Chrome's details to the report.
|
| - global_data[kStabilityReporterChannel].set_string_value(channel_name());
|
| -#if defined(ARCH_CPU_X86)
|
| - global_data[kStabilityReporterPlatform].set_string_value(
|
| - std::string("Win32"));
|
| -#elif defined(ARCH_CPU_X86_64)
|
| - global_data[kStabilityReporterPlatform].set_string_value(
|
| - std::string("Win64"));
|
| -#endif
|
| - global_data[kStabilityReporterProduct].set_string_value(product_name());
|
| - global_data[kStabilityReporterVersion].set_string_value(version_number());
|
| + CollectUserData(global_data_snapshot, (*report)->mutable_global_data(),
|
| + report->get());
|
| + SetReporterDetails(report->get());
|
| + RecordSystemShutdownState(report->get());
|
|
|
| // Collect thread activity data.
|
| - // Note: a single process is instrumented.
|
| + // Note: only the browser process records stability data for now.
|
| ProcessState* process_state = (*report)->add_process_states();
|
| for (; thread_analyzer != nullptr;
|
| thread_analyzer = global_analyzer->GetNextAnalyzer()) {
|
| @@ -352,6 +373,68 @@ PostmortemReportCollector::CollectionStatus PostmortemReportCollector::Collect(
|
| return SUCCESS;
|
| }
|
|
|
| +void PostmortemReportCollector::SetReporterDetails(
|
| + StabilityReport* report) const {
|
| + DCHECK(report);
|
| +
|
| + google::protobuf::Map<std::string, TypedValue>& global_data =
|
| + *(report->mutable_global_data());
|
| +
|
| + // Reporter version details. These are useful as the reporter may be of a
|
| + // different version.
|
| + global_data[kStabilityReporterChannel].set_string_value(channel_name());
|
| +#if defined(ARCH_CPU_X86)
|
| + global_data[kStabilityReporterPlatform].set_string_value(
|
| + std::string("Win32"));
|
| +#elif defined(ARCH_CPU_X86_64)
|
| + global_data[kStabilityReporterPlatform].set_string_value(
|
| + std::string("Win64"));
|
| +#endif
|
| + global_data[kStabilityReporterProduct].set_string_value(product_name());
|
| + global_data[kStabilityReporterVersion].set_string_value(version_number());
|
| +}
|
| +
|
| +void PostmortemReportCollector::RecordSystemShutdownState(
|
| + StabilityReport* report) const {
|
| + DCHECK(report);
|
| +
|
| + // The session state for the stability report, recorded to provided visibility
|
| + // into whether the system session was clean.
|
| + SystemState::SessionState session_state = SystemState::UNKNOWN;
|
| + // The status of the analysis, recorded to provide insight into the success
|
| + // or failure of the analysis.
|
| + SystemSessionAnalysisStatus status = SYSTEM_SESSION_ANALYSIS_SUCCESS;
|
| +
|
| + base::Time time;
|
| + if (!GetStartTimestamp(report->global_data(), &time)) {
|
| + status = SYSTEM_SESSION_ANALYSIS_NO_TIMESTAMP;
|
| + } else if (!system_session_analyzer_) {
|
| + status = SYSTEM_SESSION_ANALYSIS_NO_ANALYZER;
|
| + } else {
|
| + SystemSessionAnalyzer::Status analyzer_status =
|
| + system_session_analyzer_->IsSessionUnclean(time);
|
| + switch (analyzer_status) {
|
| + case SystemSessionAnalyzer::FAILED:
|
| + status = SYSTEM_SESSION_ANALYSIS_FAILED;
|
| + break;
|
| + case SystemSessionAnalyzer::CLEAN:
|
| + session_state = SystemState::CLEAN;
|
| + break;
|
| + case SystemSessionAnalyzer::UNCLEAN:
|
| + session_state = SystemState::UNCLEAN;
|
| + break;
|
| + case SystemSessionAnalyzer::OUTSIDE_RANGE:
|
| + status = SYSTEM_SESSION_ANALYSIS_OUTSIDE_RANGE;
|
| + break;
|
| + }
|
| + }
|
| +
|
| + report->mutable_system_state()->set_session_state(session_state);
|
| + UMA_HISTOGRAM_ENUMERATION(
|
| + "ActivityTracker.Collect.SystemSessionAnalysisStatus", status,
|
| + SYSTEM_SESSION_ANALYSIS_STATUS_MAX);
|
| +}
|
| +
|
| void PostmortemReportCollector::CollectThread(
|
| const base::debug::ThreadActivityAnalyzer::Snapshot& snapshot,
|
| ThreadState* thread_state) {
|
|
|