Handle Chrome crashes
Chrome will be modified to pass crashes to crash_reporter via a specially
formatted file, a TLV-style designed to be easily parsed, instead of
multipart/form-data. Extra attributes are added into the .meta file.
BUG=chromium:187808
TEST=new unit tests created
Change-Id: I0d65d118e0e348329d14bb4004c8f7bad5a44a97
Reviewed-on: https://gerrit.chromium.org/gerrit/49972
Reviewed-by: Chris Masone <cmasone@chromium.org>
Commit-Queue: Albert Chaulk <achaulk@chromium.org>
Tested-by: Albert Chaulk <achaulk@chromium.org>
diff --git a/crash_reporter/crash_collector.cc b/crash_reporter/crash_collector.cc
index 990ef03..85c0933 100644
--- a/crash_reporter/crash_collector.cc
+++ b/crash_reporter/crash_collector.cc
@@ -226,6 +226,66 @@
return true;
}
+FilePath CrashCollector::GetProcessPath(pid_t pid) {
+ return FilePath(StringPrintf("/proc/%d", pid));
+}
+
+bool CrashCollector::GetSymlinkTarget(const FilePath &symlink,
+ FilePath *target) {
+ int max_size = 32;
+ scoped_array<char> buffer;
+ while (true) {
+ buffer.reset(new char[max_size + 1]);
+ ssize_t size = readlink(symlink.value().c_str(), buffer.get(), max_size);
+ if (size < 0) {
+ int saved_errno = errno;
+ LOG(ERROR) << "Readlink failed on " << symlink.value() << " with "
+ << saved_errno;
+ return false;
+ }
+ buffer[size] = 0;
+ if (size == max_size) {
+ // Avoid overflow when doubling.
+ if (max_size * 2 > max_size) {
+ max_size *= 2;
+ continue;
+ } else {
+ return false;
+ }
+ }
+ break;
+ }
+
+ *target = FilePath(buffer.get());
+ return true;
+}
+
+bool CrashCollector::GetExecutableBaseNameFromPid(pid_t pid,
+ std::string *base_name) {
+ FilePath target;
+ FilePath process_path = GetProcessPath(pid);
+ FilePath exe_path = process_path.Append("exe");
+ if (!GetSymlinkTarget(exe_path, &target)) {
+ LOG(INFO) << "GetSymlinkTarget failed - Path " << process_path.value()
+ << " DirectoryExists: "
+ << file_util::DirectoryExists(process_path);
+ // Try to further diagnose exe readlink failure cause.
+ struct stat buf;
+ int stat_result = stat(exe_path.value().c_str(), &buf);
+ int saved_errno = errno;
+ if (stat_result < 0) {
+ LOG(INFO) << "stat " << exe_path.value() << " failed: " << stat_result
+ << " " << saved_errno;
+ } else {
+ LOG(INFO) << "stat " << exe_path.value() << " succeeded: st_mode="
+ << buf.st_mode;
+ }
+ return false;
+ }
+ *base_name = target.BaseName().value();
+ return true;
+}
+
// Return true if the given crash directory has not already reached
// maximum capacity.
bool CrashCollector::CheckHasCapacity(const FilePath &crash_directory) {