blob: 5143b899592210b014ee569a71c6f61c8a9564ff [file] [log] [blame]
// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "crash-reporter/service_failure_collector.h"
#include <base/files/file_util.h>
#include <base/logging.h>
#include "crash-reporter/util.h"
namespace {
const char kSignatureKey[] = "sig";
} // namespace
using base::FilePath;
using base::StringPrintf;
ServiceFailureCollector::ServiceFailureCollector()
: CrashCollector("service_failure"),
failure_report_path_("/dev/stdin"),
exec_name_("service-failure") {}
ServiceFailureCollector::~ServiceFailureCollector() {}
bool ServiceFailureCollector::LoadServiceFailure(std::string* signature) {
FilePath failure_report_path(failure_report_path_);
if (!base::ReadFileToString(failure_report_path, signature)) {
PLOG(ERROR) << "Could not open " << failure_report_path_;
return false;
}
// The report is a single line with the signature. Chop off the first newline
// character and anything that might follow it.
std::string::size_type end_position = signature->find('\n');
if (end_position != std::string::npos) {
signature->resize(end_position);
}
return !signature->empty();
}
bool ServiceFailureCollector::Collect() {
std::string reason = "normal collection";
bool feedback = true;
if (util::IsDeveloperImage()) {
reason = "always collect from developer builds";
feedback = true;
} else if (!is_feedback_allowed_function_()) {
reason = "no user consent";
feedback = false;
}
LOG(INFO) << "Processing service failure: " << reason;
if (!feedback) {
return true;
}
std::string failure_signature;
if (!LoadServiceFailure(&failure_signature)) {
return true;
}
FilePath crash_directory;
if (!GetCreatedCrashDirectoryByEuid(kRootUid, &crash_directory, nullptr)) {
return true;
}
std::string dump_basename =
FormatDumpBasename(exec_name_ + "-" + service_name_, time(nullptr), 0);
FilePath log_path = GetCrashPath(crash_directory, dump_basename, "log");
FilePath meta_path = GetCrashPath(crash_directory, dump_basename, "meta");
AddCrashMetaUploadData("weight",
StringPrintf("%d", util::GetServiceFailureWeight()));
AddCrashMetaData(kSignatureKey, failure_signature);
bool result = GetLogContents(log_config_path_, exec_name_, log_path);
if (result) {
FinishCrash(meta_path, exec_name_ + "-" + service_name_,
log_path.BaseName().value());
}
return true;
}