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 */ 16 17 #ifndef CRASH_REPORTER_CRASH_COLLECTOR_H_ 18 #define CRASH_REPORTER_CRASH_COLLECTOR_H_ 19 20 #include <sys/stat.h> 21 22 #include <map> 23 #include <string> 24 25 #include <base/files/file_path.h> 26 #include <base/macros.h> 27 #include <gtest/gtest_prod.h> // for FRIEND_TEST 28 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 40 // crash counting function, and metrics collection enabled oracle. 41 void Initialize(CountCrashFunction count_crash, 42 IsFeedbackAllowedFunction is_metrics_allowed); 43 44 protected: 45 friend class CrashCollectorTest; 46 FRIEND_TEST(ChromeCollectorTest, HandleCrash); 47 FRIEND_TEST(CrashCollectorTest, CheckHasCapacityCorrectBasename); 48 FRIEND_TEST(CrashCollectorTest, CheckHasCapacityStrangeNames); 49 FRIEND_TEST(CrashCollectorTest, CheckHasCapacityUsual); 50 FRIEND_TEST(CrashCollectorTest, GetCrashDirectoryInfo); 51 FRIEND_TEST(CrashCollectorTest, GetCrashPath); 52 FRIEND_TEST(CrashCollectorTest, GetLogContents); 53 FRIEND_TEST(CrashCollectorTest, ForkExecAndPipe); 54 FRIEND_TEST(CrashCollectorTest, FormatDumpBasename); 55 FRIEND_TEST(CrashCollectorTest, Initialize); 56 FRIEND_TEST(CrashCollectorTest, MetaData); 57 FRIEND_TEST(CrashCollectorTest, Sanitize); 58 FRIEND_TEST(CrashCollectorTest, WriteNewFile); 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); 68 69 // Set maximum enqueued crashes in a crash directory. 70 static const int kMaxCrashDirectorySize; 71 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. 75 int WriteNewFile(const base::FilePath &filename, const char *data, int size); 76 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 81 // For testing, set the directory always returned by 82 // GetCreatedCrashDirectoryByEuid. ForceCrashDirectory(const base::FilePath & forced_directory)83 void ForceCrashDirectory(const base::FilePath &forced_directory) { 84 forced_crash_directory_ = forced_directory; 85 } 86 87 base::FilePath GetCrashDirectoryInfo(mode_t *mode, 88 uid_t *directory_owner, 89 gid_t *directory_group); 90 bool GetUserInfoFromName(const std::string &name, 91 uid_t *uid, 92 gid_t *gid); 93 94 // Determines the crash directory for given euid, and creates the 95 // directory if necessary with appropriate permissions. If 96 // |out_of_capacity| is not nullptr, it is set to indicate if the call 97 // failed due to not having capacity in the crash directory. Returns 98 // true whether or not directory needed to be created, false on any 99 // failure. If the crash directory is at capacity, returns false. 100 bool GetCreatedCrashDirectoryByEuid(uid_t euid, 101 base::FilePath *crash_file_path, 102 bool *out_of_capacity); 103 104 // Format crash name based on components. 105 std::string FormatDumpBasename(const std::string &exec_name, 106 time_t timestamp, 107 pid_t pid); 108 109 // Create a file path to a file in |crash_directory| with the given 110 // |basename| and |extension|. 111 base::FilePath GetCrashPath(const base::FilePath &crash_directory, 112 const std::string &basename, 113 const std::string &extension); 114 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 121 // Check given crash directory still has remaining capacity for another 122 // crash. 123 bool CheckHasCapacity(const base::FilePath &crash_directory); 124 125 // Write a log applicable to |exec_name| to |output_file| based on the 126 // log configuration file at |config_path|. 127 bool GetLogContents(const base::FilePath &config_path, 128 const std::string &exec_name, 129 const base::FilePath &output_file); 130 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 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 146 // Write a file of metadata about crash. 147 void WriteCrashMetaData(const base::FilePath &meta_path, 148 const std::string &exec_name, 149 const std::string &payload_path); 150 151 // Returns true if the a crash test is currently running. 152 bool IsCrashTestInProgress(); 153 // Returns true if we should consider ourselves to be running on a 154 // developer image. 155 bool IsDeveloperImage(); 156 157 CountCrashFunction count_crash_function_; 158 IsFeedbackAllowedFunction is_feedback_allowed_function_; 159 std::string extra_metadata_; 160 base::FilePath forced_crash_directory_; 161 base::FilePath log_config_path_; 162 163 private: 164 DISALLOW_COPY_AND_ASSIGN(CrashCollector); 165 }; 166 167 #endif // CRASH_REPORTER_CRASH_COLLECTOR_H_ 168