crash-reporter: Attach Chrome logs to crash reports.
When Chrome crashes, gather the last 20 lines of each of the latest two log files in /var/log/chrome and /home/chronos/user/log and include them in the archive file that's attached to crash reports. BUG=chromium:405732 TEST=triggered crashes at the login screen and after logging in and verified that logs were included in crash reports: bdf766f0d6d1e066, a9d410e1a86f996b Change-Id: I09e3cee23af108dc216d64aae85d78751d5649d4 Reviewed-on: https://chromium-review.googlesource.com/216427 Reviewed-by: Ben Chan <benchan@chromium.org> Tested-by: Daniel Erat <derat@chromium.org> Commit-Queue: Daniel Erat <derat@chromium.org>
This commit is contained in:
parent
c8cb4ac7ba
commit
55cb40aa95
|
@ -42,8 +42,25 @@ bool GetDelimitedString(const std::string &str, char ch, size_t offset,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GetDriErrorState(const chromeos::dbus::Proxy &proxy,
|
||||
const FilePath &error_state_path) {
|
||||
// Gets the GPU's error state from debugd and writes it to |error_state_path|.
|
||||
// Returns true on success.
|
||||
bool GetDriErrorState(const FilePath &error_state_path) {
|
||||
chromeos::dbus::BusConnection dbus = chromeos::dbus::GetSystemBusConnection();
|
||||
if (!dbus.HasConnection()) {
|
||||
LOG(ERROR) << "Error connecting to system D-Bus";
|
||||
return false;
|
||||
}
|
||||
|
||||
chromeos::dbus::Proxy proxy(dbus,
|
||||
debugd::kDebugdServiceName,
|
||||
debugd::kDebugdServicePath,
|
||||
debugd::kDebugdInterface);
|
||||
if (!proxy) {
|
||||
LOG(ERROR) << "Error creating D-Bus proxy to interface "
|
||||
<< "'" << debugd::kDebugdServiceName << "'";
|
||||
return false;
|
||||
}
|
||||
|
||||
chromeos::glib::ScopedError error;
|
||||
gchar *error_state = NULL;
|
||||
if (!dbus_g_proxy_call(proxy.gproxy(), debugd::kGetLog,
|
||||
|
@ -88,46 +105,6 @@ bool GetDriErrorState(const chromeos::dbus::Proxy &proxy,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GetAdditionalLogs(const FilePath &log_path) {
|
||||
chromeos::dbus::BusConnection dbus = chromeos::dbus::GetSystemBusConnection();
|
||||
if (!dbus.HasConnection()) {
|
||||
LOG(ERROR) << "Error connecting to system D-Bus";
|
||||
return false;
|
||||
}
|
||||
|
||||
chromeos::dbus::Proxy proxy(dbus,
|
||||
debugd::kDebugdServiceName,
|
||||
debugd::kDebugdServicePath,
|
||||
debugd::kDebugdInterface);
|
||||
if (!proxy) {
|
||||
LOG(ERROR) << "Error creating D-Bus proxy to interface "
|
||||
<< "'" << debugd::kDebugdServiceName << "'";
|
||||
return false;
|
||||
}
|
||||
|
||||
FilePath error_state_path =
|
||||
log_path.DirName().Append("i915_error_state.log.xz");
|
||||
if (!GetDriErrorState(proxy, error_state_path))
|
||||
return false;
|
||||
|
||||
chromeos::ProcessImpl tar_process;
|
||||
tar_process.AddArg(kTarPath);
|
||||
tar_process.AddArg("cfJ");
|
||||
tar_process.AddArg(log_path.value());
|
||||
tar_process.AddStringOption("-C", log_path.DirName().value());
|
||||
tar_process.AddArg(error_state_path.BaseName().value());
|
||||
int res = tar_process.Run();
|
||||
|
||||
base::DeleteFile(error_state_path, false);
|
||||
|
||||
if (res || !base::PathExists(log_path)) {
|
||||
LOG(ERROR) << "Could not tar file " << log_path.value();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
|
@ -158,7 +135,7 @@ bool ChromeCollector::HandleCrash(const FilePath &file_path,
|
|||
std::string dump_basename = FormatDumpBasename(exe_name, time(NULL), pid);
|
||||
FilePath meta_path = GetCrashPath(dir, dump_basename, "meta");
|
||||
FilePath minidump_path = GetCrashPath(dir, dump_basename, "dmp");
|
||||
FilePath log_path = GetCrashPath(dir, dump_basename, "log.tar.xz");
|
||||
FilePath log_path = GetCrashPath(dir, dump_basename, "log.tar.gz");
|
||||
|
||||
std::string data;
|
||||
if (!base::ReadFileToString(file_path, &data)) {
|
||||
|
@ -171,7 +148,7 @@ bool ChromeCollector::HandleCrash(const FilePath &file_path,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (GetAdditionalLogs(log_path)) {
|
||||
if (GetAdditionalLogs(log_path, exe_name)) {
|
||||
int64_t minidump_size = 0;
|
||||
int64_t log_size = 0;
|
||||
if (base::GetFileSize(minidump_path, &minidump_size) &&
|
||||
|
@ -295,5 +272,44 @@ bool ChromeCollector::ParseCrashLog(const std::string &data,
|
|||
return at == data.size();
|
||||
}
|
||||
|
||||
bool ChromeCollector::GetAdditionalLogs(const FilePath &log_path,
|
||||
const std::string &exe_name) {
|
||||
std::vector<base::FilePath> logs_to_compress;
|
||||
|
||||
// Run the command specified by the config file to gather logs.
|
||||
const FilePath gathered_logs_path =
|
||||
log_path.DirName().Append("gathered_logs.txt");
|
||||
if (GetLogContents(log_config_path_, exe_name, gathered_logs_path))
|
||||
logs_to_compress.push_back(gathered_logs_path);
|
||||
|
||||
// Now get the GPU state from debugd.
|
||||
const FilePath dri_error_state_path =
|
||||
log_path.DirName().Append("i915_error_state.log.xz");
|
||||
if (GetDriErrorState(dri_error_state_path))
|
||||
logs_to_compress.push_back(dri_error_state_path);
|
||||
|
||||
if (logs_to_compress.empty())
|
||||
return false;
|
||||
|
||||
chromeos::ProcessImpl tar_process;
|
||||
tar_process.AddArg(kTarPath);
|
||||
tar_process.AddArg("cfz");
|
||||
tar_process.AddArg(log_path.value());
|
||||
tar_process.AddStringOption("-C", log_path.DirName().value());
|
||||
for (size_t i = 0; i < logs_to_compress.size(); ++i)
|
||||
tar_process.AddArg(logs_to_compress[i].BaseName().value());
|
||||
|
||||
int res = tar_process.Run();
|
||||
|
||||
for (size_t i = 0; i < logs_to_compress.size(); ++i)
|
||||
base::DeleteFile(logs_to_compress[i], false);
|
||||
|
||||
if (res || !base::PathExists(log_path)) {
|
||||
LOG(ERROR) << "Could not create tar archive " << log_path.value();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
const char ChromeCollector::kSuccessMagic[] = "_sys_cr_finished";
|
||||
|
|
|
@ -48,6 +48,12 @@ class ChromeCollector : public CrashCollector {
|
|||
const base::FilePath &minidump,
|
||||
const std::string &basename);
|
||||
|
||||
// Gathers additional logs for |exe_name| and compresses them into a .tar.gz
|
||||
// archive at |log_path|. Returns true if the log archive was created
|
||||
// successfully.
|
||||
bool GetAdditionalLogs(const base::FilePath &log_path,
|
||||
const std::string &exe_name);
|
||||
|
||||
FILE *output_file_ptr_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ChromeCollector);
|
||||
|
|
|
@ -20,6 +20,10 @@ update_engine:cat $(ls -1tr /var/log/update_engine | tail -5 | sed s.^./var/log/
|
|||
# so it is handled in the same way as update_engine.
|
||||
cros_installer:cat $(ls -1tr /var/log/update_engine | tail -5 | sed s.^./var/log/update_engine/.) | tail -c 50000
|
||||
|
||||
# Dump the last 20 lines of the last two files in Chrome's system and user log
|
||||
# directories.
|
||||
chrome:for f in $(ls -1rt /var/log/chrome/chrome_[0-9]* | tail -2) $(ls -1rt /home/chronos/u-*/log/chrome_[0-9]* | tail -2); do echo "===$f (tail)==="; tail -20 $f; echo EOF; done
|
||||
|
||||
# The following rule is used for generating additional diagnostics when
|
||||
# collection of user crashes fails. This output should not be too large
|
||||
# as it is stored in memory. The output format specified for 'ps' is the
|
||||
|
|
Loading…
Reference in New Issue