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 | */ |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 16 | |
Ben Chan | 7e77690 | 2014-06-18 13:19:51 -0700 | [diff] [blame] | 17 | #ifndef CRASH_REPORTER_CRASH_COLLECTOR_H_ |
| 18 | #define CRASH_REPORTER_CRASH_COLLECTOR_H_ |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 19 | |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 20 | #include <sys/stat.h> |
| 21 | |
Ken Mixter | ee849c5 | 2010-09-30 15:30:10 -0700 | [diff] [blame] | 22 | #include <map> |
| 23 | #include <string> |
| 24 | |
Ben Chan | 7e77690 | 2014-06-18 13:19:51 -0700 | [diff] [blame] | 25 | #include <base/files/file_path.h> |
Ben Chan | 895fa5d | 2014-09-02 20:58:20 -0700 | [diff] [blame] | 26 | #include <base/macros.h> |
Ben Chan | 7e77690 | 2014-06-18 13:19:51 -0700 | [diff] [blame] | 27 | #include <gtest/gtest_prod.h> // for FRIEND_TEST |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 28 | |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 29 | // User crash collector. |
| 30 | class CrashCollector { |
| 31 | public: |
| 32 | typedef void (*CountCrashFunction)(); |
| 33 | typedef bool (*IsFeedbackAllowedFunction)(); |
| 34 | |
| 35 | CrashCollector(); |
| 36 | |
| 37 | virtual ~CrashCollector(); |
| 38 | |
| 39 | // Initialize the crash collector for detection of crashes, given a |
Ken Mixter | a324932 | 2011-03-03 08:47:38 -0800 | [diff] [blame] | 40 | // crash counting function, and metrics collection enabled oracle. |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 41 | void Initialize(CountCrashFunction count_crash, |
Ken Mixter | a324932 | 2011-03-03 08:47:38 -0800 | [diff] [blame] | 42 | IsFeedbackAllowedFunction is_metrics_allowed); |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 43 | |
| 44 | protected: |
| 45 | friend class CrashCollectorTest; |
Lei Zhang | 9b1f300 | 2014-04-24 02:10:57 -0700 | [diff] [blame] | 46 | FRIEND_TEST(ChromeCollectorTest, HandleCrash); |
Ken Mixter | ee849c5 | 2010-09-30 15:30:10 -0700 | [diff] [blame] | 47 | FRIEND_TEST(CrashCollectorTest, CheckHasCapacityCorrectBasename); |
| 48 | FRIEND_TEST(CrashCollectorTest, CheckHasCapacityStrangeNames); |
| 49 | FRIEND_TEST(CrashCollectorTest, CheckHasCapacityUsual); |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 50 | FRIEND_TEST(CrashCollectorTest, GetCrashDirectoryInfo); |
Ken Mixter | 207694d | 2010-10-28 15:42:37 -0700 | [diff] [blame] | 51 | FRIEND_TEST(CrashCollectorTest, GetCrashPath); |
Ken Mixter | c49dbd4 | 2010-12-14 17:44:11 -0800 | [diff] [blame] | 52 | FRIEND_TEST(CrashCollectorTest, GetLogContents); |
Ken Mixter | 9b34647 | 2010-11-07 13:45:45 -0800 | [diff] [blame] | 53 | FRIEND_TEST(CrashCollectorTest, ForkExecAndPipe); |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 54 | FRIEND_TEST(CrashCollectorTest, FormatDumpBasename); |
| 55 | FRIEND_TEST(CrashCollectorTest, Initialize); |
Ken Mixter | afcf808 | 2010-10-26 14:45:01 -0700 | [diff] [blame] | 56 | FRIEND_TEST(CrashCollectorTest, MetaData); |
Ken Mixter | ee849c5 | 2010-09-30 15:30:10 -0700 | [diff] [blame] | 57 | FRIEND_TEST(CrashCollectorTest, Sanitize); |
Ken Mixter | 9b34647 | 2010-11-07 13:45:45 -0800 | [diff] [blame] | 58 | FRIEND_TEST(CrashCollectorTest, WriteNewFile); |
Ken Mixter | 1b8fe01 | 2011-01-25 13:33:05 -0800 | [diff] [blame] | 59 | FRIEND_TEST(ForkExecAndPipeTest, Basic); |
| 60 | FRIEND_TEST(ForkExecAndPipeTest, NonZeroReturnValue); |
| 61 | FRIEND_TEST(ForkExecAndPipeTest, BadOutputFile); |
| 62 | FRIEND_TEST(ForkExecAndPipeTest, ExistingOutputFile); |
| 63 | FRIEND_TEST(ForkExecAndPipeTest, BadExecutable); |
| 64 | FRIEND_TEST(ForkExecAndPipeTest, StderrCaptured); |
| 65 | FRIEND_TEST(ForkExecAndPipeTest, NULLParam); |
| 66 | FRIEND_TEST(ForkExecAndPipeTest, NoParams); |
| 67 | FRIEND_TEST(ForkExecAndPipeTest, SegFaultHandling); |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 68 | |
Ken Mixter | 04ec10f | 2010-08-26 16:02:02 -0700 | [diff] [blame] | 69 | // Set maximum enqueued crashes in a crash directory. |
| 70 | static const int kMaxCrashDirectorySize; |
| 71 | |
Ken Mixter | 9b34647 | 2010-11-07 13:45:45 -0800 | [diff] [blame] | 72 | // Writes |data| of |size| to |filename|, which must be a new file. |
| 73 | // If the file already exists or writing fails, return a negative value. |
| 74 | // Otherwise returns the number of bytes written. |
Simon Que | 9f90aca | 2013-02-19 17:19:52 -0800 | [diff] [blame] | 75 | int WriteNewFile(const base::FilePath &filename, const char *data, int size); |
Ken Mixter | 9b34647 | 2010-11-07 13:45:45 -0800 | [diff] [blame] | 76 | |
Ken Mixter | ee849c5 | 2010-09-30 15:30:10 -0700 | [diff] [blame] | 77 | // Return a filename that has only [a-z0-1_] characters by mapping |
| 78 | // all others into '_'. |
| 79 | std::string Sanitize(const std::string &name); |
| 80 | |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 81 | // For testing, set the directory always returned by |
| 82 | // GetCreatedCrashDirectoryByEuid. |
Lei Zhang | 9b1f300 | 2014-04-24 02:10:57 -0700 | [diff] [blame] | 83 | void ForceCrashDirectory(const base::FilePath &forced_directory) { |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 84 | forced_crash_directory_ = forced_directory; |
| 85 | } |
| 86 | |
Steve Fung | ab2ac7d | 2015-08-14 17:58:05 -0700 | [diff] [blame] | 87 | base::FilePath GetCrashDirectoryInfo(mode_t *mode, |
| 88 | uid_t *directory_owner, |
| 89 | gid_t *directory_group); |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 90 | bool GetUserInfoFromName(const std::string &name, |
| 91 | uid_t *uid, |
| 92 | gid_t *gid); |
Lei Zhang | 9b1f300 | 2014-04-24 02:10:57 -0700 | [diff] [blame] | 93 | |
| 94 | // Determines the crash directory for given euid, and creates the |
Ken Mixter | 207694d | 2010-10-28 15:42:37 -0700 | [diff] [blame] | 95 | // directory if necessary with appropriate permissions. If |
Ben Chan | 262d798 | 2014-09-18 08:05:20 -0700 | [diff] [blame] | 96 | // |out_of_capacity| is not nullptr, it is set to indicate if the call |
Ken Mixter | 207694d | 2010-10-28 15:42:37 -0700 | [diff] [blame] | 97 | // failed due to not having capacity in the crash directory. Returns |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 98 | // true whether or not directory needed to be created, false on any |
Ken Mixter | 207694d | 2010-10-28 15:42:37 -0700 | [diff] [blame] | 99 | // failure. If the crash directory is at capacity, returns false. |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 100 | bool GetCreatedCrashDirectoryByEuid(uid_t euid, |
Simon Que | 9f90aca | 2013-02-19 17:19:52 -0800 | [diff] [blame] | 101 | base::FilePath *crash_file_path, |
Ken Mixter | 207694d | 2010-10-28 15:42:37 -0700 | [diff] [blame] | 102 | bool *out_of_capacity); |
Ken Mixter | 04ec10f | 2010-08-26 16:02:02 -0700 | [diff] [blame] | 103 | |
| 104 | // Format crash name based on components. |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 105 | std::string FormatDumpBasename(const std::string &exec_name, |
| 106 | time_t timestamp, |
| 107 | pid_t pid); |
| 108 | |
Ken Mixter | 207694d | 2010-10-28 15:42:37 -0700 | [diff] [blame] | 109 | // Create a file path to a file in |crash_directory| with the given |
| 110 | // |basename| and |extension|. |
Simon Que | 9f90aca | 2013-02-19 17:19:52 -0800 | [diff] [blame] | 111 | base::FilePath GetCrashPath(const base::FilePath &crash_directory, |
| 112 | const std::string &basename, |
| 113 | const std::string &extension); |
Ken Mixter | 207694d | 2010-10-28 15:42:37 -0700 | [diff] [blame] | 114 | |
Albert Chaulk | 426fcc0 | 2013-05-02 15:38:31 -0700 | [diff] [blame] | 115 | base::FilePath GetProcessPath(pid_t pid); |
| 116 | bool GetSymlinkTarget(const base::FilePath &symlink, |
| 117 | base::FilePath *target); |
| 118 | bool GetExecutableBaseNameFromPid(pid_t pid, |
| 119 | std::string *base_name); |
| 120 | |
Ken Mixter | 04ec10f | 2010-08-26 16:02:02 -0700 | [diff] [blame] | 121 | // Check given crash directory still has remaining capacity for another |
| 122 | // crash. |
Simon Que | 9f90aca | 2013-02-19 17:19:52 -0800 | [diff] [blame] | 123 | bool CheckHasCapacity(const base::FilePath &crash_directory); |
Ken Mixter | 04ec10f | 2010-08-26 16:02:02 -0700 | [diff] [blame] | 124 | |
Ken Mixter | c49dbd4 | 2010-12-14 17:44:11 -0800 | [diff] [blame] | 125 | // Write a log applicable to |exec_name| to |output_file| based on the |
| 126 | // log configuration file at |config_path|. |
Simon Que | 9f90aca | 2013-02-19 17:19:52 -0800 | [diff] [blame] | 127 | bool GetLogContents(const base::FilePath &config_path, |
Ken Mixter | c49dbd4 | 2010-12-14 17:44:11 -0800 | [diff] [blame] | 128 | const std::string &exec_name, |
Simon Que | 9f90aca | 2013-02-19 17:19:52 -0800 | [diff] [blame] | 129 | const base::FilePath &output_file); |
Ken Mixter | c49dbd4 | 2010-12-14 17:44:11 -0800 | [diff] [blame] | 130 | |
Ken Mixter | afcf808 | 2010-10-26 14:45:01 -0700 | [diff] [blame] | 131 | // Add non-standard meta data to the crash metadata file. Call |
| 132 | // before calling WriteCrashMetaData. Key must not contain "=" or |
| 133 | // "\n" characters. Value must not contain "\n" characters. |
| 134 | void AddCrashMetaData(const std::string &key, const std::string &value); |
| 135 | |
Albert Chaulk | 33dfd47 | 2013-06-19 15:34:13 -0700 | [diff] [blame] | 136 | // Add a file to be uploaded to the crash reporter server. The file must |
| 137 | // persist until the crash report is sent; ideally it should live in the same |
| 138 | // place as the .meta file, so it can be cleaned up automatically. |
| 139 | void AddCrashMetaUploadFile(const std::string &key, const std::string &path); |
| 140 | |
| 141 | // Add non-standard meta data to the crash metadata file. |
| 142 | // Data added though this call will be uploaded to the crash reporter server, |
| 143 | // appearing as a form field. |
| 144 | void AddCrashMetaUploadData(const std::string &key, const std::string &value); |
| 145 | |
Ken Mixter | ee849c5 | 2010-09-30 15:30:10 -0700 | [diff] [blame] | 146 | // Write a file of metadata about crash. |
Simon Que | 9f90aca | 2013-02-19 17:19:52 -0800 | [diff] [blame] | 147 | void WriteCrashMetaData(const base::FilePath &meta_path, |
Ken Mixter | c909b69 | 2010-10-18 12:26:05 -0700 | [diff] [blame] | 148 | const std::string &exec_name, |
| 149 | const std::string &payload_path); |
Ken Mixter | ee849c5 | 2010-09-30 15:30:10 -0700 | [diff] [blame] | 150 | |
Thieu Le | 1652fb2 | 2011-03-03 12:14:43 -0800 | [diff] [blame] | 151 | // Returns true if the a crash test is currently running. |
| 152 | bool IsCrashTestInProgress(); |
Michael Krebs | 4fe30db | 2011-08-05 13:54:52 -0700 | [diff] [blame] | 153 | // Returns true if we should consider ourselves to be running on a |
| 154 | // developer image. |
| 155 | bool IsDeveloperImage(); |
Thieu Le | 1652fb2 | 2011-03-03 12:14:43 -0800 | [diff] [blame] | 156 | |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 157 | CountCrashFunction count_crash_function_; |
| 158 | IsFeedbackAllowedFunction is_feedback_allowed_function_; |
Ken Mixter | afcf808 | 2010-10-26 14:45:01 -0700 | [diff] [blame] | 159 | std::string extra_metadata_; |
Lei Zhang | 9b1f300 | 2014-04-24 02:10:57 -0700 | [diff] [blame] | 160 | base::FilePath forced_crash_directory_; |
Simon Que | 9f90aca | 2013-02-19 17:19:52 -0800 | [diff] [blame] | 161 | base::FilePath log_config_path_; |
Ben Chan | 895fa5d | 2014-09-02 20:58:20 -0700 | [diff] [blame] | 162 | |
| 163 | private: |
| 164 | DISALLOW_COPY_AND_ASSIGN(CrashCollector); |
Ken Mixter | 0340316 | 2010-08-18 15:23:16 -0700 | [diff] [blame] | 165 | }; |
| 166 | |
Ben Chan | 7e77690 | 2014-06-18 13:19:51 -0700 | [diff] [blame] | 167 | #endif // CRASH_REPORTER_CRASH_COLLECTOR_H_ |