Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "crash-reporter/user_collector.h" | 5 #include "crash-reporter/user_collector.h" |
| 6 | 6 |
| 7 #include <grp.h> // For struct group. | 7 #include <grp.h> // For struct group. |
| 8 #include <pwd.h> // For struct passwd. | 8 #include <pwd.h> // For struct passwd. |
| 9 #include <sys/types.h> // For getpwuid_r, getgrnam_r, WEXITSTATUS. | 9 #include <sys/types.h> // For getpwuid_r, getgrnam_r, WEXITSTATUS. |
| 10 | 10 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 DEFINE_string(filter_in, "", | 23 DEFINE_string(filter_in, "", |
| 24 "Ignore all crashes but this for testing"); | 24 "Ignore all crashes but this for testing"); |
| 25 #pragma GCC diagnostic error "-Wstrict-aliasing" | 25 #pragma GCC diagnostic error "-Wstrict-aliasing" |
| 26 | 26 |
| 27 static const char kCollectionErrorSignature[] = | 27 static const char kCollectionErrorSignature[] = |
| 28 "crash_reporter-user-collection"; | 28 "crash_reporter-user-collection"; |
| 29 // This procfs file is used to cause kernel core file writing to | 29 // This procfs file is used to cause kernel core file writing to |
| 30 // instead pipe the core file into a user space process. See | 30 // instead pipe the core file into a user space process. See |
| 31 // core(5) man page. | 31 // core(5) man page. |
| 32 static const char kCorePatternFile[] = "/proc/sys/kernel/core_pattern"; | 32 static const char kCorePatternFile[] = "/proc/sys/kernel/core_pattern"; |
| 33 static const char kCorePipeLimitFile[] = "/proc/sys/kernel/core_pipe_limit"; | |
| 34 // Set core_pipe_limit to 4 so that we can catch a few unrelated concurrent | |
| 35 // crashes, but finite to avoid infinitely recursing on crash handling. | |
| 36 static const char kCorePipeLimit[] = "4"; | |
|
petkov
2010/12/14 18:58:58
the CL description says more than 2 crashes.
| |
| 33 static const char kCoreToMinidumpConverterPath[] = "/usr/bin/core2md"; | 37 static const char kCoreToMinidumpConverterPath[] = "/usr/bin/core2md"; |
| 34 static const char kLeaveCoreFile[] = "/root/.leave_core"; | 38 static const char kLeaveCoreFile[] = "/root/.leave_core"; |
| 35 | 39 |
| 40 static const char kDefaultLogConfig[] = "/etc/crash_reporter_logs.conf"; | |
| 41 | |
| 36 const char *UserCollector::kUserId = "Uid:\t"; | 42 const char *UserCollector::kUserId = "Uid:\t"; |
| 37 const char *UserCollector::kGroupId = "Gid:\t"; | 43 const char *UserCollector::kGroupId = "Gid:\t"; |
| 38 | 44 |
| 39 UserCollector::UserCollector() | 45 UserCollector::UserCollector() |
| 40 : generate_diagnostics_(false), | 46 : generate_diagnostics_(false), |
| 41 core_pattern_file_(kCorePatternFile), | 47 core_pattern_file_(kCorePatternFile), |
| 48 core_pipe_limit_file_(kCorePipeLimitFile), | |
| 42 initialized_(false) { | 49 initialized_(false) { |
| 43 } | 50 } |
| 44 | 51 |
| 45 void UserCollector::Initialize( | 52 void UserCollector::Initialize( |
| 46 UserCollector::CountCrashFunction count_crash_function, | 53 UserCollector::CountCrashFunction count_crash_function, |
| 47 const std::string &our_path, | 54 const std::string &our_path, |
| 48 UserCollector::IsFeedbackAllowedFunction is_feedback_allowed_function, | 55 UserCollector::IsFeedbackAllowedFunction is_feedback_allowed_function, |
| 49 SystemLogging *logger, | 56 SystemLogging *logger, |
| 50 bool generate_diagnostics) { | 57 bool generate_diagnostics) { |
| 51 CrashCollector::Initialize(count_crash_function, | 58 CrashCollector::Initialize(count_crash_function, |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 64 return StringPrintf("|%s --signal=%%s --pid=%%p", our_path_.c_str()); | 71 return StringPrintf("|%s --signal=%%s --pid=%%p", our_path_.c_str()); |
| 65 } else { | 72 } else { |
| 66 return "core"; | 73 return "core"; |
| 67 } | 74 } |
| 68 } | 75 } |
| 69 | 76 |
| 70 bool UserCollector::SetUpInternal(bool enabled) { | 77 bool UserCollector::SetUpInternal(bool enabled) { |
| 71 CHECK(initialized_); | 78 CHECK(initialized_); |
| 72 logger_->LogInfo("%s user crash handling", | 79 logger_->LogInfo("%s user crash handling", |
| 73 enabled ? "Enabling" : "Disabling"); | 80 enabled ? "Enabling" : "Disabling"); |
| 81 if (file_util::WriteFile(FilePath(core_pipe_limit_file_), | |
| 82 kCorePipeLimit, | |
| 83 strlen(kCorePipeLimit)) != | |
| 84 static_cast<int>(strlen(kCorePipeLimit))) { | |
| 85 logger_->LogError("Unable to write %s", core_pipe_limit_file_.c_str()); | |
| 86 return false; | |
| 87 } | |
| 74 std::string pattern = GetPattern(enabled); | 88 std::string pattern = GetPattern(enabled); |
| 75 if (file_util::WriteFile(FilePath(core_pattern_file_), | 89 if (file_util::WriteFile(FilePath(core_pattern_file_), |
| 76 pattern.c_str(), | 90 pattern.c_str(), |
| 77 pattern.length()) != | 91 pattern.length()) != |
| 78 static_cast<int>(pattern.length())) { | 92 static_cast<int>(pattern.length())) { |
| 79 logger_->LogError("Unable to write %s", core_pattern_file_.c_str()); | 93 logger_->LogError("Unable to write %s", core_pattern_file_.c_str()); |
| 80 return false; | 94 return false; |
| 81 } | 95 } |
| 82 return true; | 96 return true; |
| 83 } | 97 } |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 325 } | 339 } |
| 326 | 340 |
| 327 // Directory like /tmp/crash_reporter.1234 which contains the | 341 // Directory like /tmp/crash_reporter.1234 which contains the |
| 328 // procfs entries and other temporary files used during conversion. | 342 // procfs entries and other temporary files used during conversion. |
| 329 FilePath container_dir = FilePath("/tmp").Append( | 343 FilePath container_dir = FilePath("/tmp").Append( |
| 330 StringPrintf("crash_reporter.%d", pid)); | 344 StringPrintf("crash_reporter.%d", pid)); |
| 331 std::string dump_basename = FormatDumpBasename(exec, time(NULL), pid); | 345 std::string dump_basename = FormatDumpBasename(exec, time(NULL), pid); |
| 332 FilePath core_path = GetCrashPath(crash_path, dump_basename, "core"); | 346 FilePath core_path = GetCrashPath(crash_path, dump_basename, "core"); |
| 333 FilePath meta_path = GetCrashPath(crash_path, dump_basename, "meta"); | 347 FilePath meta_path = GetCrashPath(crash_path, dump_basename, "meta"); |
| 334 FilePath minidump_path = GetCrashPath(crash_path, dump_basename, "dmp"); | 348 FilePath minidump_path = GetCrashPath(crash_path, dump_basename, "dmp"); |
| 349 FilePath log_path = GetCrashPath(crash_path, dump_basename, "log"); | |
| 350 | |
| 351 if (GetLogContents(FilePath(kDefaultLogConfig), exec, log_path)) | |
| 352 AddCrashMetaData("log", log_path.value()); | |
| 335 | 353 |
| 336 if (!ConvertCoreToMinidump(pid, container_dir, core_path, | 354 if (!ConvertCoreToMinidump(pid, container_dir, core_path, |
| 337 minidump_path)) { | 355 minidump_path)) { |
| 338 logger_->LogInfo("Leaving core file at %s due to conversion error", | 356 logger_->LogInfo("Leaving core file at %s due to conversion error", |
| 339 core_path.value().c_str()); | 357 core_path.value().c_str()); |
| 340 return false; | 358 return false; |
| 341 } | 359 } |
| 342 | 360 |
| 343 // Here we commit to sending this file. We must not return false | 361 // Here we commit to sending this file. We must not return false |
| 344 // after this point or we will generate a log report as well as a | 362 // after this point or we will generate a log report as well as a |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 406 if (!ConvertAndEnqueueCrash(pid, exec, &out_of_capacity)) { | 424 if (!ConvertAndEnqueueCrash(pid, exec, &out_of_capacity)) { |
| 407 if (!out_of_capacity) | 425 if (!out_of_capacity) |
| 408 EnqueueCollectionErrorLog(pid, exec); | 426 EnqueueCollectionErrorLog(pid, exec); |
| 409 return false; | 427 return false; |
| 410 } | 428 } |
| 411 } | 429 } |
| 412 } | 430 } |
| 413 | 431 |
| 414 return true; | 432 return true; |
| 415 } | 433 } |
| OLD | NEW |