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 <fcntl.h> // For creat. | 7 #include <fcntl.h> // For creat. |
8 #include <grp.h> // For struct group. | 8 #include <grp.h> // For struct group. |
9 #include <pwd.h> // For struct passwd. | 9 #include <pwd.h> // For struct passwd. |
10 #include <sys/types.h> // For getpwuid_r, getgrnam_r, WEXITSTATUS. | 10 #include <sys/types.h> // For getpwuid_r, getgrnam_r, WEXITSTATUS. |
11 #include <sys/wait.h> // For waitpid. | 11 #include <sys/wait.h> // For waitpid. |
12 #include <unistd.h> // For execv and fork. | 12 #include <unistd.h> // For execv and fork. |
13 | 13 |
14 #include <string> | 14 #include <string> |
15 #include <vector> | 15 #include <vector> |
16 | 16 |
17 #include "base/eintr_wrapper.h" | 17 #include "base/eintr_wrapper.h" |
18 #include "base/file_util.h" | 18 #include "base/file_util.h" |
19 #include "base/logging.h" | 19 #include "base/logging.h" |
20 #include "base/string_util.h" | 20 #include "base/string_util.h" |
21 #include "crash-reporter/system_logging.h" | 21 #include "crash-reporter/system_logging.h" |
22 #include "gflags/gflags.h" | 22 #include "gflags/gflags.h" |
23 | 23 |
| 24 #pragma GCC diagnostic ignored "-Wstrict-aliasing" |
24 DEFINE_bool(core2md_failure_test, false, "Core2md failure test"); | 25 DEFINE_bool(core2md_failure_test, false, "Core2md failure test"); |
25 DEFINE_bool(directory_failure_test, false, "Spool directory failure test"); | 26 DEFINE_bool(directory_failure_test, false, "Spool directory failure test"); |
| 27 DEFINE_string(filter_in, "", |
| 28 "Ignore all crashes but this for testing"); |
| 29 #pragma GCC diagnostic error "-Wstrict-aliasing" |
26 | 30 |
27 static const char kCollectionErrorSignature[] = | 31 static const char kCollectionErrorSignature[] = |
28 "crash_reporter-user-collection"; | 32 "crash_reporter-user-collection"; |
29 // This procfs file is used to cause kernel core file writing to | 33 // This procfs file is used to cause kernel core file writing to |
30 // instead pipe the core file into a user space process. See | 34 // instead pipe the core file into a user space process. See |
31 // core(5) man page. | 35 // core(5) man page. |
32 static const char kCorePatternFile[] = "/proc/sys/kernel/core_pattern"; | 36 static const char kCorePatternFile[] = "/proc/sys/kernel/core_pattern"; |
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 |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 bool UserCollector::HandleCrash(int signal, int pid, const char *force_exec) { | 420 bool UserCollector::HandleCrash(int signal, int pid, const char *force_exec) { |
417 CHECK(initialized_); | 421 CHECK(initialized_); |
418 std::string exec; | 422 std::string exec; |
419 if (force_exec) { | 423 if (force_exec) { |
420 exec.assign(force_exec); | 424 exec.assign(force_exec); |
421 } else if (!GetExecutableBaseNameFromPid(pid, &exec)) { | 425 } else if (!GetExecutableBaseNameFromPid(pid, &exec)) { |
422 // If for some reason we don't have the base name, avoid completely | 426 // If for some reason we don't have the base name, avoid completely |
423 // failing by indicating an unknown name. | 427 // failing by indicating an unknown name. |
424 exec = "unknown"; | 428 exec = "unknown"; |
425 } | 429 } |
| 430 |
| 431 // Allow us to test the crash reporting mechanism successfully even if |
| 432 // other parts of the system crash. |
| 433 if (!FLAGS_filter_in.empty() && |
| 434 (FLAGS_filter_in == "none" || |
| 435 FLAGS_filter_in != exec)) { |
| 436 // We use a different format message to make it more obvious in tests |
| 437 // which crashes are test generated and which are real. |
| 438 logger_->LogWarning("Ignoring crash from %s[%d] while filter_in=%s", |
| 439 exec.c_str(), pid, FLAGS_filter_in.c_str()); |
| 440 return true; |
| 441 } |
| 442 |
426 bool feedback = is_feedback_allowed_function_(); | 443 bool feedback = is_feedback_allowed_function_(); |
427 logger_->LogWarning("Received crash notification for %s[%d] sig %d (%s)", | 444 logger_->LogWarning("Received crash notification for %s[%d] sig %d (%s)", |
428 exec.c_str(), pid, signal, | 445 exec.c_str(), pid, signal, |
429 feedback ? "handling" : "ignoring - no consent"); | 446 feedback ? "handling" : "ignoring - no consent"); |
430 | 447 |
431 if (feedback) { | 448 if (feedback) { |
432 count_crash_function_(); | 449 count_crash_function_(); |
433 | 450 |
434 if (generate_diagnostics_) { | 451 if (generate_diagnostics_) { |
435 bool out_of_capacity = false; | 452 bool out_of_capacity = false; |
436 if (!ConvertAndEnqueueCrash(pid, exec, &out_of_capacity)) { | 453 if (!ConvertAndEnqueueCrash(pid, exec, &out_of_capacity)) { |
437 if (!out_of_capacity) | 454 if (!out_of_capacity) |
438 EnqueueCollectionErrorLog(pid, exec); | 455 EnqueueCollectionErrorLog(pid, exec); |
439 return false; | 456 return false; |
440 } | 457 } |
441 } | 458 } |
442 } | 459 } |
443 | 460 |
444 return true; | 461 return true; |
445 } | 462 } |
OLD | NEW |