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 <pcrecpp.h> | 8 #include <pcrecpp.h> |
9 #include <pcrecpp.h> | 9 #include <pcrecpp.h> |
10 #include <pwd.h> // For struct passwd. | 10 #include <pwd.h> // For struct passwd. |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 } | 107 } |
108 | 108 |
109 bool UserCollector::GetSymlinkTarget(const FilePath &symlink, | 109 bool UserCollector::GetSymlinkTarget(const FilePath &symlink, |
110 FilePath *target) { | 110 FilePath *target) { |
111 int max_size = 32; | 111 int max_size = 32; |
112 scoped_array<char> buffer; | 112 scoped_array<char> buffer; |
113 while (true) { | 113 while (true) { |
114 buffer.reset(new char[max_size + 1]); | 114 buffer.reset(new char[max_size + 1]); |
115 ssize_t size = readlink(symlink.value().c_str(), buffer.get(), max_size); | 115 ssize_t size = readlink(symlink.value().c_str(), buffer.get(), max_size); |
116 if (size < 0) { | 116 if (size < 0) { |
| 117 int saved_errno = errno; |
| 118 logger_->LogError("Readlink failed on %s with %d", |
| 119 symlink.value().c_str(), saved_errno); |
117 return false; | 120 return false; |
118 } | 121 } |
119 buffer[size] = 0; | 122 buffer[size] = 0; |
120 if (size == max_size) { | 123 if (size == max_size) { |
121 // Avoid overflow when doubling. | 124 // Avoid overflow when doubling. |
122 if (max_size * 2 > max_size) { | 125 if (max_size * 2 > max_size) { |
123 max_size *= 2; | 126 max_size *= 2; |
124 continue; | 127 continue; |
125 } else { | 128 } else { |
126 return false; | 129 return false; |
127 } | 130 } |
128 } | 131 } |
129 break; | 132 break; |
130 } | 133 } |
131 | 134 |
132 *target = FilePath(buffer.get()); | 135 *target = FilePath(buffer.get()); |
133 return true; | 136 return true; |
134 } | 137 } |
135 | 138 |
136 bool UserCollector::GetExecutableBaseNameFromPid(uid_t pid, | 139 bool UserCollector::GetExecutableBaseNameFromPid(uid_t pid, |
137 std::string *base_name) { | 140 std::string *base_name) { |
138 FilePath target; | 141 FilePath target; |
139 if (!GetSymlinkTarget(GetProcessPath(pid).Append("exe"), &target)) | 142 FilePath process_path = GetProcessPath(pid); |
| 143 FilePath exe_path = process_path.Append("exe"); |
| 144 if (!GetSymlinkTarget(exe_path, &target)) { |
| 145 logger_->LogInfo("GetSymlinkTarget failed - Path %s DirectoryExists: %d", |
| 146 process_path.value().c_str(), |
| 147 file_util::DirectoryExists(process_path)); |
| 148 // Try to further diagnose exe readlink failure cause. |
| 149 struct stat buf; |
| 150 int stat_result = stat(exe_path.value().c_str(), &buf); |
| 151 int saved_errno = errno; |
| 152 if (stat_result < 0) { |
| 153 logger_->LogInfo("stat %s failed: %d %d", exe_path.value().c_str(), |
| 154 stat_result, saved_errno); |
| 155 } else { |
| 156 logger_->LogInfo("stat %s succeeded: st_mode=%d", |
| 157 exe_path.value().c_str(), buf.st_mode); |
| 158 } |
140 return false; | 159 return false; |
| 160 } |
141 *base_name = target.BaseName().value(); | 161 *base_name = target.BaseName().value(); |
142 return true; | 162 return true; |
143 } | 163 } |
144 | 164 |
145 bool UserCollector::GetIdFromStatus(const char *prefix, | 165 bool UserCollector::GetIdFromStatus(const char *prefix, |
146 IdKind kind, | 166 IdKind kind, |
147 const std::string &status_contents, | 167 const std::string &status_contents, |
148 int *id) { | 168 int *id) { |
149 // From fs/proc/array.c:task_state(), this file contains: | 169 // From fs/proc/array.c:task_state(), this file contains: |
150 // \nUid:\t<uid>\t<euid>\t<suid>\t<fsuid>\n | 170 // \nUid:\t<uid>\t<euid>\t<suid>\t<fsuid>\n |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 bool *out_of_capacity) { | 260 bool *out_of_capacity) { |
241 FilePath process_path = GetProcessPath(pid); | 261 FilePath process_path = GetProcessPath(pid); |
242 std::string status; | 262 std::string status; |
243 if (FLAGS_directory_failure) { | 263 if (FLAGS_directory_failure) { |
244 logger_->LogError("Purposefully failing to create spool directory"); | 264 logger_->LogError("Purposefully failing to create spool directory"); |
245 return false; | 265 return false; |
246 } | 266 } |
247 if (!file_util::ReadFileToString(process_path.Append("status"), | 267 if (!file_util::ReadFileToString(process_path.Append("status"), |
248 &status)) { | 268 &status)) { |
249 logger_->LogError("Could not read status file"); | 269 logger_->LogError("Could not read status file"); |
250 logger_->LogInfo("Path %s FileExists: %d", | 270 logger_->LogInfo("Path %s DirectoryExists: %d", |
251 process_path.value().c_str(), | 271 process_path.value().c_str(), |
252 file_util::DirectoryExists(process_path)); | 272 file_util::DirectoryExists(process_path)); |
253 return false; | 273 return false; |
254 } | 274 } |
255 int process_euid; | 275 int process_euid; |
256 if (!GetIdFromStatus(kUserId, kIdEffective, status, &process_euid)) { | 276 if (!GetIdFromStatus(kUserId, kIdEffective, status, &process_euid)) { |
257 logger_->LogError("Could not find euid in status file"); | 277 logger_->LogError("Could not find euid in status file"); |
258 return false; | 278 return false; |
259 } | 279 } |
260 if (!GetCreatedCrashDirectoryByEuid(process_euid, | 280 if (!GetCreatedCrashDirectoryByEuid(process_euid, |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 | 457 |
438 bool feedback = is_feedback_allowed_function_(); | 458 bool feedback = is_feedback_allowed_function_(); |
439 const char *handling_string = "handling"; | 459 const char *handling_string = "handling"; |
440 if (!feedback) { | 460 if (!feedback) { |
441 handling_string = "ignoring - no consent"; | 461 handling_string = "ignoring - no consent"; |
442 } | 462 } |
443 | 463 |
444 // Treat Chrome crashes as if the user opted-out. We stop counting Chrome | 464 // Treat Chrome crashes as if the user opted-out. We stop counting Chrome |
445 // crashes towards user crashes, so user crashes really mean non-Chrome | 465 // crashes towards user crashes, so user crashes really mean non-Chrome |
446 // user-space crashes. | 466 // user-space crashes. |
447 if (exec == "chrome") { | 467 if (exec == "chrome" || exec == "supplied_chrome") { |
448 feedback = false; | 468 feedback = false; |
449 handling_string = "ignoring - chrome crash"; | 469 handling_string = "ignoring - chrome crash"; |
450 } | 470 } |
451 | 471 |
452 logger_->LogWarning("Received crash notification for %s[%d] sig %d (%s)", | 472 logger_->LogWarning("Received crash notification for %s[%d] sig %d (%s)", |
453 exec.c_str(), pid, signal, handling_string); | 473 exec.c_str(), pid, signal, handling_string); |
454 | 474 |
455 if (feedback) { | 475 if (feedback) { |
456 count_crash_function_(); | 476 count_crash_function_(); |
457 | 477 |
458 if (generate_diagnostics_) { | 478 if (generate_diagnostics_) { |
459 bool out_of_capacity = false; | 479 bool out_of_capacity = false; |
460 logger_->set_accumulating(true); | |
461 bool convert_and_enqueue_result = | 480 bool convert_and_enqueue_result = |
462 ConvertAndEnqueueCrash(pid, exec, &out_of_capacity); | 481 ConvertAndEnqueueCrash(pid, exec, &out_of_capacity); |
463 logger_->set_accumulating(false); | |
464 if (!convert_and_enqueue_result) { | 482 if (!convert_and_enqueue_result) { |
465 if (!out_of_capacity) | 483 if (!out_of_capacity) |
466 EnqueueCollectionErrorLog(pid, exec); | 484 EnqueueCollectionErrorLog(pid, exec); |
467 return false; | 485 return false; |
468 } | 486 } |
469 } | 487 } |
470 } | 488 } |
471 | 489 |
472 return true; | 490 return true; |
473 } | 491 } |
OLD | NEW |