Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(351)

Side by Side Diff: crash_collector.cc

Issue 3436029: crash-reporter: Send OS version at time of crash and related improvements (Closed) Base URL: http://git.chromium.org/git/crash-reporter.git
Patch Set: respond to petkov review Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « crash_collector.h ('k') | crash_collector_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/crash_collector.h" 5 #include "crash-reporter/crash_collector.h"
6 6
7 #include <dirent.h> 7 #include <dirent.h>
8 #include <pwd.h> // For struct passwd. 8 #include <pwd.h> // For struct passwd.
9 #include <sys/types.h> // for mode_t. 9 #include <sys/types.h> // for mode_t.
10 10
11 #include <set>
12
11 #include "base/file_util.h" 13 #include "base/file_util.h"
12 #include "base/logging.h" 14 #include "base/logging.h"
13 #include "base/string_util.h" 15 #include "base/string_util.h"
14 #include "crash-reporter/system_logging.h" 16 #include "crash-reporter/system_logging.h"
15 17
16 static const char kDefaultUserName[] = "chronos"; 18 static const char kDefaultUserName[] = "chronos";
19 static const char kLsbRelease[] = "/etc/lsb-release";
17 static const char kSystemCrashPath[] = "/var/spool/crash"; 20 static const char kSystemCrashPath[] = "/var/spool/crash";
18 static const char kUserCrashPath[] = "/home/chronos/user/crash"; 21 static const char kUserCrashPath[] = "/home/chronos/user/crash";
19 22
20 // Directory mode of the user crash spool directory. 23 // Directory mode of the user crash spool directory.
21 static const mode_t kUserCrashPathMode = 0755; 24 static const mode_t kUserCrashPathMode = 0755;
22 25
23 // Directory mode of the system crash spool directory. 26 // Directory mode of the system crash spool directory.
24 static const mode_t kSystemCrashPathMode = 01755; 27 static const mode_t kSystemCrashPathMode = 01755;
25 28
26 static const uid_t kRootOwner = 0; 29 static const uid_t kRootOwner = 0;
(...skipping 21 matching lines...) Expand all
48 SystemLogging *logger) { 51 SystemLogging *logger) {
49 CHECK(count_crash_function != NULL); 52 CHECK(count_crash_function != NULL);
50 CHECK(is_feedback_allowed_function != NULL); 53 CHECK(is_feedback_allowed_function != NULL);
51 CHECK(logger != NULL); 54 CHECK(logger != NULL);
52 55
53 count_crash_function_ = count_crash_function; 56 count_crash_function_ = count_crash_function;
54 is_feedback_allowed_function_ = is_feedback_allowed_function; 57 is_feedback_allowed_function_ = is_feedback_allowed_function;
55 logger_ = logger; 58 logger_ = logger;
56 } 59 }
57 60
61 std::string CrashCollector::Sanitize(const std::string &name) {
62 std::string result = name;
63 for (size_t i = 0; i < name.size(); ++i) {
64 if (!isalnum(result[i]) && result[i] != '_')
65 result[i] = '_';
66 }
67 return result;
68 }
69
58 std::string CrashCollector::FormatDumpBasename(const std::string &exec_name, 70 std::string CrashCollector::FormatDumpBasename(const std::string &exec_name,
59 time_t timestamp, 71 time_t timestamp,
60 pid_t pid) { 72 pid_t pid) {
61 struct tm tm; 73 struct tm tm;
62 localtime_r(&timestamp, &tm); 74 localtime_r(&timestamp, &tm);
75 std::string sanitized_exec_name = Sanitize(exec_name);
63 return StringPrintf("%s.%04d%02d%02d.%02d%02d%02d.%d", 76 return StringPrintf("%s.%04d%02d%02d.%02d%02d%02d.%d",
64 exec_name.c_str(), 77 sanitized_exec_name.c_str(),
65 tm.tm_year + 1900, 78 tm.tm_year + 1900,
66 tm.tm_mon + 1, 79 tm.tm_mon + 1,
67 tm.tm_mday, 80 tm.tm_mday,
68 tm.tm_hour, 81 tm.tm_hour,
69 tm.tm_min, 82 tm.tm_min,
70 tm.tm_sec, 83 tm.tm_sec,
71 pid); 84 pid);
72 } 85 }
73 86
74 FilePath CrashCollector::GetCrashDirectoryInfo( 87 FilePath CrashCollector::GetCrashDirectoryInfo(
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 179
167 // Return true if the given crash directory has not already reached 180 // Return true if the given crash directory has not already reached
168 // maximum capacity. 181 // maximum capacity.
169 bool CrashCollector::CheckHasCapacity(const FilePath &crash_directory) { 182 bool CrashCollector::CheckHasCapacity(const FilePath &crash_directory) {
170 DIR* dir = opendir(crash_directory.value().c_str()); 183 DIR* dir = opendir(crash_directory.value().c_str());
171 if (!dir) { 184 if (!dir) {
172 return false; 185 return false;
173 } 186 }
174 struct dirent ent_buf; 187 struct dirent ent_buf;
175 struct dirent* ent; 188 struct dirent* ent;
176 int count_non_core = 0;
177 int count_core = 0;
178 bool full = false; 189 bool full = false;
190 std::set<std::string> basenames;
179 while (readdir_r(dir, &ent_buf, &ent) == 0 && ent != NULL) { 191 while (readdir_r(dir, &ent_buf, &ent) == 0 && ent != NULL) {
180 if ((strcmp(ent->d_name, ".") == 0) || 192 if ((strcmp(ent->d_name, ".") == 0) ||
181 (strcmp(ent->d_name, "..") == 0)) 193 (strcmp(ent->d_name, "..") == 0))
182 continue; 194 continue;
183 195
184 if (strcmp(ent->d_name + strlen(ent->d_name) - 5, ".core") == 0) { 196 std::string filename(ent->d_name);
185 ++count_core; 197 size_t last_dot = filename.rfind(".");
186 } else { 198 std::string basename;
187 ++count_non_core; 199 // If there is a valid looking extension, use the base part of the
188 } 200 // name. If the only dot is the first byte (aka a dot file), treat
201 // it as unique to avoid allowing a directory full of dot files
202 // from accumulating.
203 if (last_dot != std::string::npos && last_dot != 0)
204 basename = filename.substr(0, last_dot);
205 else
206 basename = filename;
207 basenames.insert(basename);
189 208
190 if (count_core >= kMaxCrashDirectorySize || 209 if (basenames.size() >= static_cast<size_t>(kMaxCrashDirectorySize)) {
191 count_non_core >= kMaxCrashDirectorySize) {
192 logger_->LogWarning( 210 logger_->LogWarning(
193 "Crash directory %s already full with %d pending reports", 211 "Crash directory %s already full with %d pending reports",
194 crash_directory.value().c_str(), 212 crash_directory.value().c_str(),
195 kMaxCrashDirectorySize); 213 kMaxCrashDirectorySize);
196 full = true; 214 full = true;
197 break; 215 break;
198 } 216 }
199 } 217 }
200 closedir(dir); 218 closedir(dir);
201 return !full; 219 return !full;
202 } 220 }
221
222 bool CrashCollector::ReadKeyValueFile(
223 const FilePath &path,
224 const char separator,
225 std::map<std::string, std::string> *dictionary) {
226 std::string contents;
227 if (!file_util::ReadFileToString(path, &contents)) {
228 return false;
229 }
230 typedef std::vector<std::string> StringVector;
231 StringVector lines;
232 SplitString(contents, '\n', &lines);
233 bool any_errors = false;
234 for (StringVector::iterator line = lines.begin(); line != lines.end();
235 ++line) {
236 // Allow empty strings.
237 if (line->empty())
238 continue;
239 StringVector sides;
240 SplitString(*line, separator, &sides);
241 if (sides.size() != 2) {
242 any_errors = true;
243 continue;
244 }
245 dictionary->insert(std::pair<std::string, std::string>(sides[0], sides[1]));
246 }
247 return !any_errors;
248 }
249
250 void CrashCollector::WriteCrashMetaData(const FilePath &meta_path,
251 const std::string &exec_name) {
252 std::map<std::string, std::string> contents;
253 if (!ReadKeyValueFile(FilePath(std::string(kLsbRelease)), '=', &contents)) {
254 logger_->LogError("Problem parsing %s", kLsbRelease);
255 // Even though there was some failure, take as much as we could read.
256 }
257 std::string version("unknown");
258 std::map<std::string, std::string>::iterator i;
259 if ((i = contents.find("CHROMEOS_RELEASE_VERSION")) != contents.end()) {
260 version = i->second;
261 }
262 std::string meta_data = StringPrintf("exec_name=%s\n"
263 "ver=%s\n"
264 "done=1\n",
265 exec_name.c_str(),
266 version.c_str());
267 if (!file_util::WriteFile(meta_path, meta_data.c_str(), meta_data.size())) {
268 logger_->LogError("Unable to write %s", meta_path.value().c_str());
269 }
270 }
OLDNEW
« no previous file with comments | « crash_collector.h ('k') | crash_collector_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698