OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 #include "chromecast/crash/dump_info.h" |
| 5 |
| 6 #include <stdlib.h> |
| 7 |
| 8 #include <sstream> |
| 9 |
| 10 #include "base/logging.h" |
| 11 #include "base/strings/string_split.h" |
| 12 |
| 13 namespace chromecast { |
| 14 |
| 15 namespace { |
| 16 |
| 17 const char kDumpTimeFormat[] = "%Y-%m-%d %H:%M:%S"; |
| 18 const unsigned kDumpTimeMaxLen = 255; |
| 19 |
| 20 const int kNumRequiredParams = 5; |
| 21 } // namespace |
| 22 |
| 23 MinidumpParams::MinidumpParams(const std::string& p_process_name, |
| 24 const uint64_t p_process_uptime, |
| 25 const std::string& p_suffix, |
| 26 const std::string& p_previous_app_name, |
| 27 const std::string& p_current_app_name, |
| 28 const std::string& p_last_app_name, |
| 29 const std::string& p_cast_release_version, |
| 30 const std::string& p_cast_build_number) |
| 31 : process_name(p_process_name), |
| 32 process_uptime(p_process_uptime), |
| 33 suffix(p_suffix), |
| 34 previous_app_name(p_previous_app_name), |
| 35 current_app_name(p_current_app_name), |
| 36 last_app_name(p_last_app_name), |
| 37 cast_release_version(p_cast_release_version), |
| 38 cast_build_number(p_cast_build_number) { |
| 39 } |
| 40 |
| 41 MinidumpParams::MinidumpParams() : process_uptime(0) { |
| 42 } |
| 43 |
| 44 MinidumpParams::MinidumpParams(const MinidumpParams& params) = default; |
| 45 |
| 46 MinidumpParams::~MinidumpParams() { |
| 47 } |
| 48 |
| 49 DumpInfo::DumpInfo(const std::string& entry) : valid_(false) { |
| 50 // TODO(slan): This ctor is doing non-trivial work. Change this. |
| 51 if ((valid_ = ParseEntry(entry)) == true) { |
| 52 entry_ = GetEntryAsString(); |
| 53 } |
| 54 } |
| 55 |
| 56 DumpInfo::DumpInfo(const std::string& crashed_process_dump, |
| 57 const std::string& logfile, |
| 58 const time_t& dump_time, |
| 59 const MinidumpParams& params) |
| 60 : crashed_process_dump_(crashed_process_dump), |
| 61 logfile_(logfile), |
| 62 dump_time_(dump_time), |
| 63 params_(params), |
| 64 valid_(false) { |
| 65 // The format is |
| 66 // <name>|<dump time>|<dump>|<uptime>|<logfile>|<suffix>|<prev_app_name>| |
| 67 // <curent_app name>|<last_app_name> |
| 68 // <dump time> is in the format of kDumpTimeFormat |
| 69 |
| 70 // Validate the time passed in. |
| 71 struct tm* tm = gmtime(&dump_time); |
| 72 char buf[kDumpTimeMaxLen]; |
| 73 int n = strftime(buf, kDumpTimeMaxLen, kDumpTimeFormat, tm); |
| 74 if (n <= 0) { |
| 75 LOG(INFO) << "strftime failed"; |
| 76 return; |
| 77 } |
| 78 entry_ = GetEntryAsString(); |
| 79 valid_ = true; |
| 80 } |
| 81 |
| 82 DumpInfo::~DumpInfo() { |
| 83 } |
| 84 |
| 85 std::string DumpInfo::GetEntryAsString() { |
| 86 struct tm* tm = gmtime(&dump_time_); |
| 87 char buf[kDumpTimeMaxLen]; |
| 88 int n = strftime(buf, kDumpTimeMaxLen, kDumpTimeFormat, tm); |
| 89 DCHECK_GT(n, 0); |
| 90 |
| 91 std::stringstream entrystream; |
| 92 entrystream << params_.process_name << "|" << buf << "|" |
| 93 << crashed_process_dump_ << "|" << params_.process_uptime << "|" |
| 94 << logfile_ << "|" << params_.suffix << "|" |
| 95 << params_.previous_app_name << "|" << params_.current_app_name |
| 96 << "|" << params_.last_app_name << "|" |
| 97 << params_.cast_release_version << "|" |
| 98 << params_.cast_build_number << std::endl; |
| 99 return entrystream.str(); |
| 100 } |
| 101 |
| 102 bool DumpInfo::ParseEntry(const std::string& entry) { |
| 103 // The format is |
| 104 // <name>|<dump time>|<dump>|<uptime>|<logfile>{|<suffix>{|<prev_app_name>{ |
| 105 // |<current_app name>{|last_launched_app_name}}}} |
| 106 // <dump time> is in the format |kDumpTimeFormat| |
| 107 std::vector<std::string> fields; |
| 108 base::SplitString(entry, '|', &fields); |
| 109 if (fields.size() < kNumRequiredParams) { |
| 110 LOG(INFO) << "Invalid entry: Too few fields."; |
| 111 return false; |
| 112 } |
| 113 |
| 114 // Extract the process name, which must be non-empty. |
| 115 if (fields[0].empty()) { |
| 116 LOG(INFO) << "Invalid entry: Process name is empty."; |
| 117 return false; |
| 118 } |
| 119 params_.process_name = fields[0]; |
| 120 |
| 121 // Extract the time. |
| 122 if (!SetDumpTimeFromString(fields[1])) |
| 123 return false; |
| 124 |
| 125 // Extract all other fields. |
| 126 for (size_t i = 2; i < fields.size(); ++i) { |
| 127 const std::string& temp = fields[i]; |
| 128 switch (i) { |
| 129 case 2: // Required field: crashed process dump |
| 130 crashed_process_dump_ = temp; |
| 131 break; |
| 132 case 3: // Required field: process uptime |
| 133 params_.process_uptime = atoll(temp.c_str()); |
| 134 break; |
| 135 case 4: // Required field: log file path |
| 136 logfile_ = temp; |
| 137 break; |
| 138 case 5: // Optional field: suffix |
| 139 params_.suffix = temp; |
| 140 break; |
| 141 case 6: // Optional field: prev_app_name |
| 142 params_.previous_app_name = temp; |
| 143 break; |
| 144 case 7: // Optional field: current_app_name |
| 145 params_.current_app_name = temp; |
| 146 break; |
| 147 case 8: // Optional field: last_launched_app_name |
| 148 params_.last_app_name = temp; |
| 149 break; |
| 150 case 9: // extract an optional cast release version |
| 151 params_.cast_release_version = temp; |
| 152 break; |
| 153 case 10: // extract an optional cast build number |
| 154 params_.cast_build_number = temp; |
| 155 break; |
| 156 default: |
| 157 LOG(INFO) << "Entry has too many fields invalid"; |
| 158 return false; |
| 159 } |
| 160 } |
| 161 valid_ = true; |
| 162 return true; |
| 163 } |
| 164 |
| 165 bool DumpInfo::SetDumpTimeFromString(const std::string& timestr) { |
| 166 struct tm tm; |
| 167 char* text = strptime(timestr.c_str(), kDumpTimeFormat, &tm); |
| 168 dump_time_ = mktime(&tm); |
| 169 if (!text || dump_time_ < 0) { |
| 170 LOG(INFO) << "Failed to convert dump time invalid"; |
| 171 return false; |
| 172 } |
| 173 return true; |
| 174 } |
| 175 |
| 176 } // namespace chromecast |
OLD | NEW |