Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(295)

Unified Diff: crash_reporter.cc

Issue 3179006: Collect and send kernel crash diagnostics (Closed) Base URL: ssh://git@chromiumos-git//crash-reporter.git
Patch Set: Respond to reviews Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « crash_collector_test.cc ('k') | crash_sender » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: crash_reporter.cc
diff --git a/crash_reporter.cc b/crash_reporter.cc
index 0930cea447e19927f893193b6a02db7eaa7cfaaf..e850e3070800555db1818cec65a20b04a30e4244 100644
--- a/crash_reporter.cc
+++ b/crash_reporter.cc
@@ -7,7 +7,9 @@
#include "base/file_util.h"
#include "base/logging.h"
#include "base/string_util.h"
+#include "crash-reporter/kernel_collector.h"
#include "crash-reporter/system_logging.h"
+#include "crash-reporter/unclean_shutdown_collector.h"
#include "crash-reporter/user_collector.h"
#include "gflags/gflags.h"
#include "metrics/metrics_library.h"
@@ -22,69 +24,52 @@ DEFINE_bool(unclean_check, true, "Check for unclean shutdown");
#pragma GCC diagnostic error "-Wstrict-aliasing"
static const char kCrashCounterHistogram[] = "Logging.CrashCounter";
-static const char kEmpty[] = "";
+static const char kUserCrashSignal[] =
+ "org.chromium.CrashReporter.UserCrash";
static const char kUncleanShutdownFile[] =
"/var/lib/crash_reporter/pending_clean_shutdown";
// Enumeration of kinds of crashes to be used in the CrashCounter histogram.
enum CrashKinds {
- kCrashKindKernel = 1,
- kCrashKindUser = 2,
+ kCrashKindUncleanShutdown = 1,
+ kCrashKindUser = 2,
+ kCrashKindKernel = 3,
kCrashKindMax
};
static MetricsLibrary s_metrics_lib;
static SystemLoggingImpl s_system_log;
-static bool IsMetricsCollectionAllowed() {
- // TODO(kmixter): Eventually check system tainted state and
- // move this down in metrics library where it would be explicitly
- // checked when asked to send stats.
+static bool IsFeedbackAllowed() {
+ // Once crosbug.com/5814 is fixed, call the is opted in function
+ // here.
return true;
}
-static void CheckUncleanShutdown() {
- FilePath unclean_file_path(kUncleanShutdownFile);
- if (!file_util::PathExists(unclean_file_path)) {
- return;
- }
- s_system_log.LogWarning("Last shutdown was not clean");
- if (IsMetricsCollectionAllowed()) {
- s_metrics_lib.SendEnumToUMA(std::string(kCrashCounterHistogram),
- kCrashKindKernel,
- kCrashKindMax);
- }
- if (!file_util::Delete(unclean_file_path, false)) {
- s_system_log.LogError("Failed to delete unclean shutdown file %s",
- kUncleanShutdownFile);
- }
-
- // Touch a file to notify the metrics daemon that a kernel crash has
- // been detected so that it can log the time since the last kernel
- // crash.
- static const char kKernelCrashDetectedFile[] = "/tmp/kernel-crash-detected";
- FilePath crash_detected(kKernelCrashDetectedFile);
- file_util::WriteFile(crash_detected, kEmpty, 0);
+static bool TouchFile(const FilePath &file_path) {
+ return file_util::WriteFile(file_path, "", 0) == 0;
}
-static bool PrepareUncleanShutdownCheck() {
- FilePath file_path(kUncleanShutdownFile);
- file_util::CreateDirectory(file_path.DirName());
- return file_util::WriteFile(file_path, kEmpty, 0) == 0;
+static void CountKernelCrash() {
+ s_metrics_lib.SendEnumToUMA(std::string(kCrashCounterHistogram),
+ kCrashKindKernel,
+ kCrashKindMax);
}
-static void SignalCleanShutdown() {
- s_system_log.LogInfo("Clean shutdown signalled");
- file_util::Delete(FilePath(kUncleanShutdownFile), false);
+static void CountUncleanShutdown() {
+ s_metrics_lib.SendEnumToUMA(std::string(kCrashCounterHistogram),
+ kCrashKindUncleanShutdown,
+ kCrashKindMax);
}
static void CountUserCrash() {
- CHECK(IsMetricsCollectionAllowed());
s_metrics_lib.SendEnumToUMA(std::string(kCrashCounterHistogram),
kCrashKindUser,
kCrashKindMax);
-
+ std::string command = StringPrintf(
+ "/usr/bin/dbus-send --type=signal --system / \"%s\"",
+ kUserCrashSignal);
// Announce through D-Bus whenever a user crash happens. This is
// used by the metrics daemon to log active use time between
// crashes.
@@ -93,42 +78,47 @@ static void CountUserCrash() {
// using a dbus library directly. However, this should run
// relatively rarely and longer term we may need to implement a
// better way to do this that doesn't rely on D-Bus.
- int status __attribute__((unused)) =
- system("/usr/bin/dbus-send --type=signal --system / "
- "org.chromium.CrashReporter.UserCrash");
+
+ int status __attribute__((unused)) = system(command.c_str());
}
-int main(int argc, char *argv[]) {
- google::ParseCommandLineFlags(&argc, &argv, true);
- FilePath my_path(argv[0]);
- file_util::AbsolutePath(&my_path);
- s_metrics_lib.Init();
- s_system_log.Initialize(my_path.BaseName().value().c_str());
- UserCollector user_collector;
- user_collector.Initialize(CountUserCrash,
- my_path.value(),
- IsMetricsCollectionAllowed,
- &s_system_log,
- true); // generate_diagnostics
+static int Initialize(KernelCollector *kernel_collector,
+ UserCollector *user_collector,
+ UncleanShutdownCollector *unclean_shutdown_collector) {
+ CHECK(!FLAGS_clean_shutdown) << "Incompatible options";
- if (FLAGS_init) {
- CHECK(!FLAGS_clean_shutdown) << "Incompatible options";
- user_collector.Enable();
- if (FLAGS_unclean_check) {
- CheckUncleanShutdown();
- if (!PrepareUncleanShutdownCheck()) {
- s_system_log.LogError("Unable to create shutdown check file");
- }
- }
- return 0;
+ bool was_kernel_crash = false;
+ bool was_unclean_shutdown = false;
+ if (kernel_collector->IsEnabled()) {
+ was_kernel_crash = kernel_collector->Collect();
}
- if (FLAGS_clean_shutdown) {
- SignalCleanShutdown();
- user_collector.Disable();
- return 0;
+ if (FLAGS_unclean_check) {
+ was_unclean_shutdown = unclean_shutdown_collector->Collect();
+ }
+
+ // Touch a file to notify the metrics daemon that a kernel
+ // crash has been detected so that it can log the time since
+ // the last kernel crash.
+ if (IsFeedbackAllowed()) {
+ if (was_kernel_crash) {
+ TouchFile(FilePath("/tmp/kernel-crash-detected"));
+ } else if (was_unclean_shutdown) {
+ // We only count an unclean shutdown if it did not come with
+ // an associated kernel crash.
+ TouchFile(FilePath("/tmp/unclean-shutdown-detected"));
+ }
}
+ // Must enable the unclean shutdown collector *after* collecting.
+ kernel_collector->Enable();
+ unclean_shutdown_collector->Enable();
+ user_collector->Enable();
+
+ return 0;
+}
+
+static int HandleUserCrash(UserCollector *user_collector) {
// Handle a specific user space crash.
CHECK(FLAGS_signal != -1) << "Signal must be set";
CHECK(FLAGS_pid != -1) << "PID must be set";
@@ -141,9 +131,45 @@ int main(int argc, char *argv[]) {
}
// Handle the crash, get the name of the process from procfs.
- if (!user_collector.HandleCrash(FLAGS_signal, FLAGS_pid, NULL)) {
+ if (!user_collector->HandleCrash(FLAGS_signal, FLAGS_pid, NULL)) {
return 1;
}
-
return 0;
}
+
+
+int main(int argc, char *argv[]) {
+ google::ParseCommandLineFlags(&argc, &argv, true);
+ FilePath my_path(argv[0]);
+ file_util::AbsolutePath(&my_path);
+ s_metrics_lib.Init();
+ s_system_log.Initialize(my_path.BaseName().value().c_str());
+ KernelCollector kernel_collector;
+ kernel_collector.Initialize(CountKernelCrash,
+ IsFeedbackAllowed,
+ &s_system_log);
+ UserCollector user_collector;
+ user_collector.Initialize(CountUserCrash,
+ my_path.value(),
+ IsFeedbackAllowed,
+ &s_system_log,
+ true); // generate_diagnostics
+ UncleanShutdownCollector unclean_shutdown_collector;
+ unclean_shutdown_collector.Initialize(CountUncleanShutdown,
+ IsFeedbackAllowed,
+ &s_system_log);
+
+ if (FLAGS_init) {
+ return Initialize(&kernel_collector,
+ &user_collector,
+ &unclean_shutdown_collector);
+ }
+
+ if (FLAGS_clean_shutdown) {
+ unclean_shutdown_collector.Disable();
+ user_collector.Disable();
+ return 0;
+ }
+
+ return HandleUserCrash(&user_collector);
+}
« no previous file with comments | « crash_collector_test.cc ('k') | crash_sender » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698