crash_collector: Collect i915_error_state for chrome crashes
Since crash_collector runs as chronos for chrome crashes,
it doesn't have permission to read i915_error_state.
Switch to getting it from debugd instead of reading directly.
Also, collect it for all chrome crashes.
BUG=chromium:219121
TEST=Kill chrome, see the log gathered. Uploaded report id 7cbae7f70da9bd3e.
Change-Id: Ic74abea2fc86b16c5a7f0f11df73137d93e5220c
Reviewed-on: https://gerrit.chromium.org/gerrit/61606
Reviewed-by: Albert Chaulk <achaulk@chromium.org>
Commit-Queue: Yuly Novikov <ynovikov@chromium.org>
Tested-by: Yuly Novikov <ynovikov@chromium.org>
diff --git a/crash_reporter/chrome_collector.cc b/crash_reporter/chrome_collector.cc
index 2c9ae6e..8f5ddb3 100644
--- a/crash_reporter/chrome_collector.cc
+++ b/crash_reporter/chrome_collector.cc
@@ -14,8 +14,13 @@
#include <base/string_util.h>
#include "chromeos/process.h"
#include "chromeos/syslog_logging.h"
+#include "chromeos/dbus/dbus.h"
+#include "chromeos/dbus/service_constants.h"
const char kDefaultMinidumpName[] = "upload_file_minidump";
+const char kTarPath[] = "/bin/tar";
+// From //net/crash/collector/collector.h
+const int kDefaultMaxUploadBytes = 1024 * 1024;
namespace {
@@ -31,6 +36,78 @@
return true;
}
+bool GetDriErrorState(const chromeos::dbus::Proxy &proxy,
+ const FilePath &error_state_path) {
+ chromeos::glib::ScopedError error;
+ gchar *error_state = NULL;
+ if (!dbus_g_proxy_call(proxy.gproxy(), debugd::kGetLog,
+ &chromeos::Resetter(&error).lvalue(),
+ G_TYPE_STRING, "i915_error_state", G_TYPE_INVALID,
+ G_TYPE_STRING, &error_state, G_TYPE_INVALID)) {
+ LOG(ERROR) << "Error performing D-Bus proxy call "
+ << "'" << debugd::kGetLog << "'"
+ << ": " << (error ? error->message : "");
+ g_free(error_state);
+ return false;
+ }
+
+ std::string error_state_str(error_state);
+ g_free(error_state);
+
+ if(error_state_str == "<empty>")
+ return false;
+
+ int written;
+ written = file_util::WriteFile(error_state_path, error_state_str.c_str(),
+ error_state_str.length());
+
+ if (written < 0 || (size_t)written != error_state_str.length()) {
+ LOG(ERROR) << "Could not write file " << error_state_path.value();
+ file_util::Delete(error_state_path, false);
+ return false;
+ }
+
+ 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");
+ if (!GetDriErrorState(proxy, error_state_path))
+ 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());
+ tar_process.AddArg(error_state_path.BaseName().value());
+ int res = tar_process.Run();
+
+ file_util::Delete(error_state_path, false);
+
+ if (res || !file_util::PathExists(log_path)) {
+ LOG(ERROR) << "Could not tar file " << log_path.value();
+ return false;
+ }
+
+ return true;
+}
} //namespace
@@ -61,7 +138,7 @@
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");
+ FilePath log_path = GetCrashPath(dir, dump_basename, "log.tgz");
std::string data;
if (!file_util::ReadFileToString(FilePath(file_path), &data)) {
@@ -74,8 +151,20 @@
return false;
}
- if (GetLogContents(FilePath(log_config_path_), exe_name, log_path))
- AddCrashMetaData("log", log_path.value());
+ if (GetAdditionalLogs(log_path)) {
+ int64 minidump_size = 0;
+ int64 log_size = 0;
+ if (file_util::GetFileSize(minidump_path, &minidump_size) &&
+ file_util::GetFileSize(log_path, &log_size) &&
+ minidump_size > 0 && log_size > 0 &&
+ minidump_size + log_size < kDefaultMaxUploadBytes) {
+ AddCrashMetaData("log", log_path.value());
+ } else {
+ LOG(INFO) << "Skipping logs upload to prevent discarding minidump "
+ "because of report size limit < " << minidump_size + log_size;
+ file_util::Delete(log_path, false);
+ }
+ }
// We're done.
WriteCrashMetaData(meta_path, exe_name, minidump_path.value());
diff --git a/crash_reporter/crash_reporter_logs.conf b/crash_reporter/crash_reporter_logs.conf
index 808e71d..9c1a531 100644
--- a/crash_reporter/crash_reporter_logs.conf
+++ b/crash_reporter/crash_reporter_logs.conf
@@ -31,15 +31,6 @@
# run for kernel errors reported through udev events.
crash_reporter-udev-collection-change-card0-drm:for dri in /sys/kernel/debug/dri/*; do echo "===$dri/i915_error_state==="; cat $dri/i915_error_state; done
-# TODO(mkrebs,sabercrombie): Because these can be quite large (600KB
-# compressed), remove this when GPU hangs are no longer an issue, and/or we
-# start collecting "chrome" crashes for normal images.
-# Collect i915 error state for Chrome crashes as well. See
-# crosbug.com/36979. These can be big (i.e. megabytes), so compress them with
-# gzip. Note that the file attached to the crash report will have a ".log"
-# extension, but will have been gzip'ed.
-chrome:for dri in /sys/kernel/debug/dri/*; do echo "===$dri/i915_error_state==="; cat $dri/i915_error_state; done | gzip -c
-
# When trackpad driver cyapa detects some abnormal behavior, we collect
# additional logs from kernel messages.
crash_reporter-udev-collection-change--i2c-cyapa:/usr/sbin/kernel_log_collector.sh cyapa 30