Steve Fung | 6c34c25 | 2015-08-20 00:27:30 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2012 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 16 | |
Ken Mixter | a324932 | 2011-03-03 08:47:38 -0800 | [diff] [blame] | 17 | #include <fcntl.h> // for open |
| 18 | |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 19 | #include <string> |
Simon Que | f70060c | 2012-04-09 19:07:07 -0700 | [diff] [blame] | 20 | #include <vector> |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 21 | |
Ben Chan | ab6cc90 | 2014-09-05 08:21:06 -0700 | [diff] [blame] | 22 | #include <base/files/file_util.h> |
Steve Fung | 12e61ca | 2015-09-15 16:36:33 -0700 | [diff] [blame] | 23 | #include <base/guid.h> |
Albert Chaulk | 426fcc0 | 2013-05-02 15:38:31 -0700 | [diff] [blame] | 24 | #include <base/logging.h> |
Mike Frysinger | a557c11 | 2014-02-05 22:55:39 -0500 | [diff] [blame] | 25 | #include <base/strings/string_split.h> |
| 26 | #include <base/strings/string_util.h> |
| 27 | #include <base/strings/stringprintf.h> |
Todd Poynor | 8361935 | 2015-12-02 14:38:43 -0800 | [diff] [blame] | 28 | #include <binder/IServiceManager.h> |
Alex Vakulenko | 74dc624 | 2015-10-13 09:23:34 -0700 | [diff] [blame] | 29 | #include <brillo/flag_helper.h> |
Alex Vakulenko | 74dc624 | 2015-10-13 09:23:34 -0700 | [diff] [blame] | 30 | #include <brillo/syslog_logging.h> |
Todd Poynor | 8361935 | 2015-12-02 14:38:43 -0800 | [diff] [blame] | 31 | #include <metrics/metrics_collector_service_client.h> |
Ben Chan | 7e77690 | 2014-06-18 13:19:51 -0700 | [diff] [blame] | 32 | #include <metrics/metrics_library.h> |
Todd Poynor | 8361935 | 2015-12-02 14:38:43 -0800 | [diff] [blame] | 33 | #include <utils/String16.h> |
| 34 | |
Ben Chan | 7e77690 | 2014-06-18 13:19:51 -0700 | [diff] [blame] | 35 | |
Steve Fung | 129bea5 | 2015-07-23 13:11:15 -0700 | [diff] [blame] | 36 | #include "kernel_collector.h" |
| 37 | #include "kernel_warning_collector.h" |
Steve Fung | 129bea5 | 2015-07-23 13:11:15 -0700 | [diff] [blame] | 38 | #include "unclean_shutdown_collector.h" |
| 39 | #include "user_collector.h" |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 40 | |
Steve Fung | c490e0f | 2016-01-04 14:26:15 -0800 | [diff] [blame] | 41 | #if !defined(__ANDROID__) |
| 42 | #include "udev_collector.h" |
| 43 | #endif |
| 44 | |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 45 | static const char kCrashCounterHistogram[] = "Logging.CrashCounter"; |
Chris Masone | d3ac796 | 2012-02-24 14:38:57 -0800 | [diff] [blame] | 46 | static const char kKernelCrashDetected[] = "/var/run/kernel-crash-detected"; |
| 47 | static const char kUncleanShutdownDetected[] = |
| 48 | "/var/run/unclean-shutdown-detected"; |
Steve Fung | 12e61ca | 2015-09-15 16:36:33 -0700 | [diff] [blame] | 49 | static const char kGUIDFileName[] = "/data/misc/crash_reporter/guid"; |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 50 | |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 51 | // Enumeration of kinds of crashes to be used in the CrashCounter histogram. |
| 52 | enum CrashKinds { |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 53 | kCrashKindUncleanShutdown = 1, |
| 54 | kCrashKindUser = 2, |
| 55 | kCrashKindKernel = 3, |
Simon Que | acc7938 | 2012-05-04 18:10:09 -0700 | [diff] [blame] | 56 | kCrashKindUdev = 4, |
Luigi Semenzato | 6fdc0b4 | 2013-04-11 17:22:13 -0700 | [diff] [blame] | 57 | kCrashKindKernelWarning = 5, |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 58 | kCrashKindMax |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 59 | }; |
| 60 | |
| 61 | static MetricsLibrary s_metrics_lib; |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 62 | |
Todd Poynor | 8361935 | 2015-12-02 14:38:43 -0800 | [diff] [blame] | 63 | using android::brillo::metrics::IMetricsCollectorService; |
Simon Que | 9f90aca | 2013-02-19 17:19:52 -0800 | [diff] [blame] | 64 | using base::FilePath; |
Mike Frysinger | a557c11 | 2014-02-05 22:55:39 -0500 | [diff] [blame] | 65 | using base::StringPrintf; |
Simon Que | 9f90aca | 2013-02-19 17:19:52 -0800 | [diff] [blame] | 66 | |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 67 | static bool IsFeedbackAllowed() { |
Ken Mixter | ee849c5 | 2010-09-30 15:30:10 -0700 | [diff] [blame] | 68 | return s_metrics_lib.AreMetricsEnabled(); |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 69 | } |
| 70 | |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 71 | static bool TouchFile(const FilePath &file_path) { |
Ben Chan | f30c641 | 2014-05-22 23:09:01 -0700 | [diff] [blame] | 72 | return base::WriteFile(file_path, "", 0) == 0; |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 73 | } |
| 74 | |
Simon Que | 6f03549 | 2012-06-27 17:28:14 -0700 | [diff] [blame] | 75 | static void SendCrashMetrics(CrashKinds type, const char* name) { |
Ken Mixter | 1d3c304 | 2011-01-22 06:16:40 -0800 | [diff] [blame] | 76 | // TODO(kmixter): We can remove this histogram as part of |
| 77 | // crosbug.com/11163. |
Simon Que | 6f03549 | 2012-06-27 17:28:14 -0700 | [diff] [blame] | 78 | s_metrics_lib.SendEnumToUMA(kCrashCounterHistogram, type, kCrashKindMax); |
| 79 | s_metrics_lib.SendCrashToUMA(name); |
| 80 | } |
| 81 | |
| 82 | static void CountKernelCrash() { |
| 83 | SendCrashMetrics(kCrashKindKernel, "kernel"); |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 84 | } |
| 85 | |
Simon Que | acc7938 | 2012-05-04 18:10:09 -0700 | [diff] [blame] | 86 | static void CountUdevCrash() { |
| 87 | SendCrashMetrics(kCrashKindUdev, "udevcrash"); |
| 88 | } |
| 89 | |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 90 | static void CountUncleanShutdown() { |
Simon Que | 6f03549 | 2012-06-27 17:28:14 -0700 | [diff] [blame] | 91 | SendCrashMetrics(kCrashKindUncleanShutdown, "uncleanshutdown"); |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 92 | } |
| 93 | |
| 94 | static void CountUserCrash() { |
Simon Que | 6f03549 | 2012-06-27 17:28:14 -0700 | [diff] [blame] | 95 | SendCrashMetrics(kCrashKindUser, "user"); |
Todd Poynor | 8361935 | 2015-12-02 14:38:43 -0800 | [diff] [blame] | 96 | // Tell the metrics collector about the user crash, in order to log active |
| 97 | // use time between crashes. |
| 98 | MetricsCollectorServiceClient metrics_collector_service; |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 99 | |
Todd Poynor | 8361935 | 2015-12-02 14:38:43 -0800 | [diff] [blame] | 100 | if (metrics_collector_service.Init()) |
| 101 | metrics_collector_service.notifyUserCrash(); |
| 102 | else |
| 103 | LOG(ERROR) << "Failed to send user crash notification to metrics_collector"; |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 104 | } |
| 105 | |
Albert Chaulk | 426fcc0 | 2013-05-02 15:38:31 -0700 | [diff] [blame] | 106 | |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 107 | static int Initialize(KernelCollector *kernel_collector, |
| 108 | UserCollector *user_collector, |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 109 | UncleanShutdownCollector *unclean_shutdown_collector, |
| 110 | const bool unclean_check, |
| 111 | const bool clean_shutdown) { |
| 112 | CHECK(!clean_shutdown) << "Incompatible options"; |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 113 | |
Steve Fung | 12e61ca | 2015-09-15 16:36:33 -0700 | [diff] [blame] | 114 | // Try to read the GUID from kGUIDFileName. If the file doesn't exist, is |
| 115 | // blank, or the read fails, generate a new GUID and write it to the file. |
| 116 | std::string guid; |
| 117 | base::FilePath filepath(kGUIDFileName); |
| 118 | if (!base::ReadFileToString(filepath, &guid) || guid.empty()) { |
| 119 | guid = base::GenerateGUID(); |
| 120 | // If we can't read or write the file, log an error. However it is not |
| 121 | // a fatal error, as the crash server will assign a random GUID based |
| 122 | // on a hash of the IP address if one is not provided in the report. |
| 123 | if (base::WriteFile(filepath, guid.c_str(), guid.size()) <= 0) { |
| 124 | LOG(ERROR) << "Could not write guid " << guid << " to file " |
| 125 | << filepath.value(); |
| 126 | } |
| 127 | } |
| 128 | |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 129 | bool was_kernel_crash = false; |
| 130 | bool was_unclean_shutdown = false; |
Hugh Dickins | f174fc0 | 2010-09-08 20:55:26 -0700 | [diff] [blame] | 131 | kernel_collector->Enable(); |
Ben Chan | 3c6b82c | 2014-07-23 14:52:14 -0700 | [diff] [blame] | 132 | if (kernel_collector->is_enabled()) { |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 133 | was_kernel_crash = kernel_collector->Collect(); |
| 134 | } |
| 135 | |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 136 | if (unclean_check) { |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 137 | was_unclean_shutdown = unclean_shutdown_collector->Collect(); |
| 138 | } |
| 139 | |
| 140 | // Touch a file to notify the metrics daemon that a kernel |
| 141 | // crash has been detected so that it can log the time since |
| 142 | // the last kernel crash. |
| 143 | if (IsFeedbackAllowed()) { |
| 144 | if (was_kernel_crash) { |
Chris Masone | d3ac796 | 2012-02-24 14:38:57 -0800 | [diff] [blame] | 145 | TouchFile(FilePath(kKernelCrashDetected)); |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 146 | } else if (was_unclean_shutdown) { |
| 147 | // We only count an unclean shutdown if it did not come with |
| 148 | // an associated kernel crash. |
Chris Masone | d3ac796 | 2012-02-24 14:38:57 -0800 | [diff] [blame] | 149 | TouchFile(FilePath(kUncleanShutdownDetected)); |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 150 | } |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 151 | } |
| 152 | |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 153 | // Must enable the unclean shutdown collector *after* collecting. |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 154 | unclean_shutdown_collector->Enable(); |
| 155 | user_collector->Enable(); |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 156 | |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 157 | return 0; |
| 158 | } |
| 159 | |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 160 | static int HandleUserCrash(UserCollector *user_collector, |
| 161 | const std::string& user, const bool crash_test) { |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 162 | // Handle a specific user space crash. |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 163 | CHECK(!user.empty()) << "--user= must be set"; |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 164 | |
| 165 | // Make it possible to test what happens when we crash while |
| 166 | // handling a crash. |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 167 | if (crash_test) { |
Mike Frysinger | 9a7ce9f | 2013-01-19 11:03:37 -0500 | [diff] [blame] | 168 | *(volatile char *)0 = 0; |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 169 | return 0; |
| 170 | } |
| 171 | |
Ken Mixter | d49d362 | 2011-02-09 18:23:00 -0800 | [diff] [blame] | 172 | // Accumulate logs to help in diagnosing failures during user collection. |
Alex Vakulenko | 74dc624 | 2015-10-13 09:23:34 -0700 | [diff] [blame] | 173 | brillo::LogToString(true); |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 174 | // Handle the crash, get the name of the process from procfs. |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 175 | bool handled = user_collector->HandleCrash(user, nullptr); |
Alex Vakulenko | 74dc624 | 2015-10-13 09:23:34 -0700 | [diff] [blame] | 176 | brillo::LogToString(false); |
Ken Mixter | d49d362 | 2011-02-09 18:23:00 -0800 | [diff] [blame] | 177 | if (!handled) |
Ken Mixter | 777484c | 2010-07-23 16:22:44 -0700 | [diff] [blame] | 178 | return 1; |
Chris Sosa | e4a8603 | 2010-06-16 17:08:34 -0700 | [diff] [blame] | 179 | return 0; |
| 180 | } |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 181 | |
Steve Fung | c490e0f | 2016-01-04 14:26:15 -0800 | [diff] [blame] | 182 | #if !defined(__ANDROID__) |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 183 | static int HandleUdevCrash(UdevCollector *udev_collector, |
| 184 | const std::string& udev_event) { |
Simon Que | f70060c | 2012-04-09 19:07:07 -0700 | [diff] [blame] | 185 | // Handle a crash indicated by a udev event. |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 186 | CHECK(!udev_event.empty()) << "--udev= must be set"; |
Simon Que | f70060c | 2012-04-09 19:07:07 -0700 | [diff] [blame] | 187 | |
| 188 | // Accumulate logs to help in diagnosing failures during user collection. |
Alex Vakulenko | 74dc624 | 2015-10-13 09:23:34 -0700 | [diff] [blame] | 189 | brillo::LogToString(true); |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 190 | bool handled = udev_collector->HandleCrash(udev_event); |
Alex Vakulenko | 74dc624 | 2015-10-13 09:23:34 -0700 | [diff] [blame] | 191 | brillo::LogToString(false); |
Simon Que | f70060c | 2012-04-09 19:07:07 -0700 | [diff] [blame] | 192 | if (!handled) |
| 193 | return 1; |
| 194 | return 0; |
| 195 | } |
Steve Fung | c490e0f | 2016-01-04 14:26:15 -0800 | [diff] [blame] | 196 | #endif |
Simon Que | f70060c | 2012-04-09 19:07:07 -0700 | [diff] [blame] | 197 | |
Luigi Semenzato | 6fdc0b4 | 2013-04-11 17:22:13 -0700 | [diff] [blame] | 198 | static int HandleKernelWarning(KernelWarningCollector |
| 199 | *kernel_warning_collector) { |
| 200 | // Accumulate logs to help in diagnosing failures during collection. |
Alex Vakulenko | 74dc624 | 2015-10-13 09:23:34 -0700 | [diff] [blame] | 201 | brillo::LogToString(true); |
Luigi Semenzato | 6fdc0b4 | 2013-04-11 17:22:13 -0700 | [diff] [blame] | 202 | bool handled = kernel_warning_collector->Collect(); |
Alex Vakulenko | 74dc624 | 2015-10-13 09:23:34 -0700 | [diff] [blame] | 203 | brillo::LogToString(false); |
Luigi Semenzato | 6fdc0b4 | 2013-04-11 17:22:13 -0700 | [diff] [blame] | 204 | if (!handled) |
| 205 | return 1; |
| 206 | return 0; |
| 207 | } |
| 208 | |
Ken Mixter | afcf808 | 2010-10-26 14:45:01 -0700 | [diff] [blame] | 209 | // Interactive/diagnostics mode for generating kernel crash signatures. |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 210 | static int GenerateKernelSignature(KernelCollector *kernel_collector, |
| 211 | const std::string& kernel_signature_file) { |
Ken Mixter | afcf808 | 2010-10-26 14:45:01 -0700 | [diff] [blame] | 212 | std::string kcrash_contents; |
| 213 | std::string signature; |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 214 | if (!base::ReadFileToString(FilePath(kernel_signature_file), |
Mike Frysinger | a557c11 | 2014-02-05 22:55:39 -0500 | [diff] [blame] | 215 | &kcrash_contents)) { |
Ken Mixter | afcf808 | 2010-10-26 14:45:01 -0700 | [diff] [blame] | 216 | fprintf(stderr, "Could not read file.\n"); |
| 217 | return 1; |
| 218 | } |
| 219 | if (!kernel_collector->ComputeKernelStackSignature( |
| 220 | kcrash_contents, |
| 221 | &signature, |
| 222 | true)) { |
| 223 | fprintf(stderr, "Signature could not be generated.\n"); |
| 224 | return 1; |
| 225 | } |
| 226 | printf("Kernel crash signature is \"%s\".\n", signature.c_str()); |
| 227 | return 0; |
| 228 | } |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 229 | |
Ken Mixter | a324932 | 2011-03-03 08:47:38 -0800 | [diff] [blame] | 230 | // Ensure stdout, stdin, and stderr are open file descriptors. If |
| 231 | // they are not, any code which writes to stderr/stdout may write out |
| 232 | // to files opened during execution. In particular, when |
| 233 | // crash_reporter is run by the kernel coredump pipe handler (via |
| 234 | // kthread_create/kernel_execve), it will not have file table entries |
| 235 | // 1 and 2 (stdout and stderr) populated. We populate them here. |
| 236 | static void OpenStandardFileDescriptors() { |
| 237 | int new_fd = -1; |
| 238 | // We open /dev/null to fill in any of the standard [0, 2] file |
| 239 | // descriptors. We leave these open for the duration of the |
| 240 | // process. This works because open returns the lowest numbered |
| 241 | // invalid fd. |
| 242 | do { |
| 243 | new_fd = open("/dev/null", 0); |
Ben Chan | 7e77690 | 2014-06-18 13:19:51 -0700 | [diff] [blame] | 244 | CHECK_GE(new_fd, 0) << "Unable to open /dev/null"; |
Ken Mixter | a324932 | 2011-03-03 08:47:38 -0800 | [diff] [blame] | 245 | } while (new_fd >= 0 && new_fd <= 2); |
| 246 | close(new_fd); |
| 247 | } |
| 248 | |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 249 | int main(int argc, char *argv[]) { |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 250 | DEFINE_bool(init, false, "Initialize crash logging"); |
| 251 | DEFINE_bool(clean_shutdown, false, "Signal clean shutdown"); |
| 252 | DEFINE_string(generate_kernel_signature, "", |
| 253 | "Generate signature from given kcrash file"); |
| 254 | DEFINE_bool(crash_test, false, "Crash test"); |
| 255 | DEFINE_string(user, "", "User crash info (pid:signal:exec_name)"); |
| 256 | DEFINE_bool(unclean_check, true, "Check for unclean shutdown"); |
Steve Fung | c490e0f | 2016-01-04 14:26:15 -0800 | [diff] [blame] | 257 | |
| 258 | #if !defined(__ANDROID__) |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 259 | DEFINE_string(udev, "", "Udev event description (type:device:subsystem)"); |
Steve Fung | c490e0f | 2016-01-04 14:26:15 -0800 | [diff] [blame] | 260 | #endif |
| 261 | |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 262 | DEFINE_bool(kernel_warning, false, "Report collected kernel warning"); |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 263 | DEFINE_string(pid, "", "PID of crashing process"); |
| 264 | DEFINE_string(uid, "", "UID of crashing process"); |
| 265 | DEFINE_string(exe, "", "Executable name of crashing process"); |
| 266 | DEFINE_bool(core2md_failure, false, "Core2md failure test"); |
| 267 | DEFINE_bool(directory_failure, false, "Spool directory failure test"); |
| 268 | DEFINE_string(filter_in, "", |
| 269 | "Ignore all crashes but this for testing"); |
| 270 | |
Ken Mixter | a324932 | 2011-03-03 08:47:38 -0800 | [diff] [blame] | 271 | OpenStandardFileDescriptors(); |
Mike Frysinger | a557c11 | 2014-02-05 22:55:39 -0500 | [diff] [blame] | 272 | FilePath my_path = base::MakeAbsoluteFilePath(FilePath(argv[0])); |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 273 | s_metrics_lib.Init(); |
Alex Vakulenko | 74dc624 | 2015-10-13 09:23:34 -0700 | [diff] [blame] | 274 | brillo::FlagHelper::Init(argc, argv, "Chromium OS Crash Reporter"); |
| 275 | brillo::OpenLog(my_path.BaseName().value().c_str(), true); |
| 276 | brillo::InitLog(brillo::kLogToSyslog); |
Mike Frysinger | f19b518 | 2013-05-17 19:36:47 -0400 | [diff] [blame] | 277 | |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 278 | KernelCollector kernel_collector; |
Lei Zhang | 9b1f300 | 2014-04-24 02:10:57 -0700 | [diff] [blame] | 279 | kernel_collector.Initialize(CountKernelCrash, IsFeedbackAllowed); |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 280 | UserCollector user_collector; |
| 281 | user_collector.Initialize(CountUserCrash, |
| 282 | my_path.value(), |
| 283 | IsFeedbackAllowed, |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 284 | true, // generate_diagnostics |
| 285 | FLAGS_core2md_failure, |
| 286 | FLAGS_directory_failure, |
| 287 | FLAGS_filter_in); |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 288 | UncleanShutdownCollector unclean_shutdown_collector; |
| 289 | unclean_shutdown_collector.Initialize(CountUncleanShutdown, |
Ken Mixter | a324932 | 2011-03-03 08:47:38 -0800 | [diff] [blame] | 290 | IsFeedbackAllowed); |
Steve Fung | c490e0f | 2016-01-04 14:26:15 -0800 | [diff] [blame] | 291 | |
| 292 | #if !defined(__ANDROID__) |
Simon Que | acc7938 | 2012-05-04 18:10:09 -0700 | [diff] [blame] | 293 | UdevCollector udev_collector; |
| 294 | udev_collector.Initialize(CountUdevCrash, IsFeedbackAllowed); |
Steve Fung | c490e0f | 2016-01-04 14:26:15 -0800 | [diff] [blame] | 295 | #endif |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 296 | |
Luigi Semenzato | 6fdc0b4 | 2013-04-11 17:22:13 -0700 | [diff] [blame] | 297 | KernelWarningCollector kernel_warning_collector; |
Luigi Semenzato | 20980d7 | 2013-05-28 14:29:43 -0700 | [diff] [blame] | 298 | kernel_warning_collector.Initialize(CountUdevCrash, IsFeedbackAllowed); |
Luigi Semenzato | 6fdc0b4 | 2013-04-11 17:22:13 -0700 | [diff] [blame] | 299 | |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 300 | if (FLAGS_init) { |
| 301 | return Initialize(&kernel_collector, |
| 302 | &user_collector, |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 303 | &unclean_shutdown_collector, |
| 304 | FLAGS_unclean_check, |
| 305 | FLAGS_clean_shutdown); |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 306 | } |
| 307 | |
| 308 | if (FLAGS_clean_shutdown) { |
| 309 | unclean_shutdown_collector.Disable(); |
| 310 | user_collector.Disable(); |
| 311 | return 0; |
| 312 | } |
| 313 | |
Ken Mixter | afcf808 | 2010-10-26 14:45:01 -0700 | [diff] [blame] | 314 | if (!FLAGS_generate_kernel_signature.empty()) { |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 315 | return GenerateKernelSignature(&kernel_collector, |
| 316 | FLAGS_generate_kernel_signature); |
Ken Mixter | afcf808 | 2010-10-26 14:45:01 -0700 | [diff] [blame] | 317 | } |
| 318 | |
Steve Fung | c490e0f | 2016-01-04 14:26:15 -0800 | [diff] [blame] | 319 | #if !defined(__ANDROID__) |
Simon Que | f70060c | 2012-04-09 19:07:07 -0700 | [diff] [blame] | 320 | if (!FLAGS_udev.empty()) { |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 321 | return HandleUdevCrash(&udev_collector, FLAGS_udev); |
Simon Que | f70060c | 2012-04-09 19:07:07 -0700 | [diff] [blame] | 322 | } |
Steve Fung | c490e0f | 2016-01-04 14:26:15 -0800 | [diff] [blame] | 323 | #endif |
Simon Que | f70060c | 2012-04-09 19:07:07 -0700 | [diff] [blame] | 324 | |
Luigi Semenzato | 6fdc0b4 | 2013-04-11 17:22:13 -0700 | [diff] [blame] | 325 | if (FLAGS_kernel_warning) { |
| 326 | return HandleKernelWarning(&kernel_warning_collector); |
| 327 | } |
| 328 | |
Steve Fung | d6169a2 | 2014-08-11 15:52:23 -0700 | [diff] [blame] | 329 | return HandleUserCrash(&user_collector, FLAGS_user, FLAGS_crash_test); |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 330 | } |