Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Crashpad Authors. All rights reserved. | 1 // Copyright 2015 The Crashpad Authors. All rights reserved. |
| 2 // | 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
| 6 // | 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // | 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. | 13 // limitations under the License. |
| 14 | 14 |
| 15 #include "snapshot/minidump/process_snapshot_minidump.h" | 15 #include "snapshot/minidump/process_snapshot_minidump.h" |
| 16 | 16 |
| 17 #include <utility> | |
| 18 | |
| 19 #include "base/memory/scoped_ptr.h" | |
| 17 #include "util/file/file_io.h" | 20 #include "util/file/file_io.h" |
| 18 #include "snapshot/minidump/minidump_simple_string_dictionary_reader.h" | 21 #include "snapshot/minidump/minidump_simple_string_dictionary_reader.h" |
| 19 | 22 |
| 20 namespace crashpad { | 23 namespace crashpad { |
| 21 | 24 |
| 22 ProcessSnapshotMinidump::ProcessSnapshotMinidump() | 25 ProcessSnapshotMinidump::ProcessSnapshotMinidump() |
| 23 : ProcessSnapshot(), | 26 : ProcessSnapshot(), |
| 24 header_(), | 27 header_(), |
| 25 stream_directory_(), | 28 stream_directory_(), |
| 26 stream_map_(), | 29 stream_map_(), |
| 30 modules_(), | |
| 27 crashpad_info_(), | 31 crashpad_info_(), |
| 28 annotations_simple_map_(), | 32 annotations_simple_map_(), |
| 29 file_reader_(nullptr), | 33 file_reader_(nullptr), |
| 30 initialized_() { | 34 initialized_() { |
| 31 } | 35 } |
| 32 | 36 |
| 33 ProcessSnapshotMinidump::~ProcessSnapshotMinidump() { | 37 ProcessSnapshotMinidump::~ProcessSnapshotMinidump() { |
| 34 } | 38 } |
| 35 | 39 |
| 36 bool ProcessSnapshotMinidump::Initialize(FileReaderInterface* file_reader) { | 40 bool ProcessSnapshotMinidump::Initialize(FileReaderInterface* file_reader) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 74 LOG(ERROR) << "duplicate streams for type " << directory.StreamType; | 78 LOG(ERROR) << "duplicate streams for type " << directory.StreamType; |
| 75 return false; | 79 return false; |
| 76 } | 80 } |
| 77 | 81 |
| 78 stream_map_[stream_type] = &directory.Location; | 82 stream_map_[stream_type] = &directory.Location; |
| 79 } | 83 } |
| 80 | 84 |
| 81 INITIALIZATION_STATE_SET_VALID(initialized_); | 85 INITIALIZATION_STATE_SET_VALID(initialized_); |
| 82 | 86 |
| 83 InitializeCrashpadInfo(); | 87 InitializeCrashpadInfo(); |
| 88 InitializeModules(); | |
| 84 | 89 |
| 85 return true; | 90 return true; |
| 86 } | 91 } |
| 87 | 92 |
| 88 pid_t ProcessSnapshotMinidump::ProcessID() const { | 93 pid_t ProcessSnapshotMinidump::ProcessID() const { |
| 89 INITIALIZATION_STATE_DCHECK_VALID(initialized_); | 94 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 90 NOTREACHED(); | 95 NOTREACHED(); |
| 91 return 0; | 96 return 0; |
| 92 } | 97 } |
| 93 | 98 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 139 } | 144 } |
| 140 | 145 |
| 141 std::vector<const ThreadSnapshot*> ProcessSnapshotMinidump::Threads() const { | 146 std::vector<const ThreadSnapshot*> ProcessSnapshotMinidump::Threads() const { |
| 142 INITIALIZATION_STATE_DCHECK_VALID(initialized_); | 147 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 143 NOTREACHED(); | 148 NOTREACHED(); |
| 144 return std::vector<const ThreadSnapshot*>(); | 149 return std::vector<const ThreadSnapshot*>(); |
| 145 } | 150 } |
| 146 | 151 |
| 147 std::vector<const ModuleSnapshot*> ProcessSnapshotMinidump::Modules() const { | 152 std::vector<const ModuleSnapshot*> ProcessSnapshotMinidump::Modules() const { |
| 148 INITIALIZATION_STATE_DCHECK_VALID(initialized_); | 153 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 149 NOTREACHED(); | 154 std::vector<const ModuleSnapshot*> modules; |
| 150 return std::vector<const ModuleSnapshot*>(); | 155 for (internal::ModuleSnapshotMinidump* module : modules_) { |
| 156 modules.push_back(module); | |
| 157 } | |
| 158 return modules; | |
| 151 } | 159 } |
| 152 | 160 |
| 153 const ExceptionSnapshot* ProcessSnapshotMinidump::Exception() const { | 161 const ExceptionSnapshot* ProcessSnapshotMinidump::Exception() const { |
| 154 INITIALIZATION_STATE_DCHECK_VALID(initialized_); | 162 INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| 155 NOTREACHED(); | 163 NOTREACHED(); |
| 156 return nullptr; | 164 return nullptr; |
| 157 } | 165 } |
| 158 | 166 |
| 159 void ProcessSnapshotMinidump::InitializeCrashpadInfo() { | 167 void ProcessSnapshotMinidump::InitializeCrashpadInfo() { |
| 160 const auto& it = stream_map_.find(kMinidumpStreamTypeCrashpadInfo); | 168 const auto& stream_it = stream_map_.find(kMinidumpStreamTypeCrashpadInfo); |
| 161 if (it == stream_map_.end()) { | 169 if (stream_it == stream_map_.end()) { |
| 162 return; | 170 return; |
| 163 } | 171 } |
| 164 | 172 |
| 165 if (it->second->DataSize < sizeof(crashpad_info_)) { | 173 if (stream_it->second->DataSize < sizeof(crashpad_info_)) { |
| 166 LOG(ERROR) << "crashpad_info size mismatch"; | 174 LOG(ERROR) << "crashpad_info size mismatch"; |
| 167 return; | 175 return; |
| 168 } | 176 } |
| 169 | 177 |
| 170 if (!file_reader_->SeekSet(it->second->Rva)) { | 178 if (!file_reader_->SeekSet(stream_it->second->Rva)) { |
| 171 return; | 179 return; |
| 172 } | 180 } |
| 173 | 181 |
| 174 if (!file_reader_->ReadExactly(&crashpad_info_, sizeof(crashpad_info_))) { | 182 if (!file_reader_->ReadExactly(&crashpad_info_, sizeof(crashpad_info_))) { |
| 175 return; | 183 return; |
| 176 } | 184 } |
| 177 | 185 |
| 178 if (crashpad_info_.version != MinidumpCrashpadInfo::kVersion) { | 186 if (crashpad_info_.version != MinidumpCrashpadInfo::kVersion) { |
| 179 LOG(ERROR) << "crashpad_info version mismatch"; | 187 LOG(ERROR) << "crashpad_info version mismatch"; |
| 180 return; | 188 return; |
| 181 } | 189 } |
| 182 | 190 |
| 183 internal::ReadMinidumpSimpleStringDictionary( | 191 internal::ReadMinidumpSimpleStringDictionary( |
| 184 file_reader_, | 192 file_reader_, |
| 185 crashpad_info_.simple_annotations, | 193 crashpad_info_.simple_annotations, |
| 186 &annotations_simple_map_); | 194 &annotations_simple_map_); |
| 187 } | 195 } |
| 188 | 196 |
| 197 bool ProcessSnapshotMinidump::InitializeModules() { | |
| 198 const auto& stream_it = stream_map_.find(kMinidumpStreamTypeModuleList); | |
| 199 if (stream_it == stream_map_.end()) { | |
| 200 return true; | |
| 201 } | |
| 202 | |
| 203 std::map<uint32_t, MINIDUMP_LOCATION_DESCRIPTOR> module_crashpad_info_links; | |
| 204 InitializeModulesCrashpadInfo(&module_crashpad_info_links); | |
| 205 | |
| 206 if (stream_it->second->DataSize < sizeof(MINIDUMP_MODULE_LIST)) { | |
| 207 LOG(ERROR) << "module_list size mismatch"; | |
| 208 return false; | |
| 209 } | |
| 210 | |
| 211 if (!file_reader_->SeekSet(stream_it->second->Rva)) { | |
| 212 return false; | |
| 213 } | |
| 214 | |
| 215 uint32_t module_count; | |
| 216 if (!file_reader_->ReadExactly(&module_count, sizeof(module_count))) { | |
| 217 return false; | |
| 218 } | |
| 219 | |
| 220 if (sizeof(MINIDUMP_MODULE_LIST) + module_count * sizeof(MINIDUMP_MODULE) != | |
| 221 stream_it->second->DataSize) { | |
| 222 LOG(ERROR) << "module_list size mismatch"; | |
| 223 return false; | |
| 224 } | |
| 225 | |
| 226 for (uint32_t module_index = 0; module_index < module_count; ++module_index) { | |
| 227 internal::ModuleSnapshotMinidump* module = | |
|
Robert Sesek
2015/03/04 01:52:25
Similar to the earlier comment, it'll be easier to
| |
| 228 new internal::ModuleSnapshotMinidump(); | |
| 229 modules_.push_back(module); | |
| 230 | |
| 231 const RVA module_rva = stream_it->second->Rva + sizeof(module_count) + | |
| 232 module_index * sizeof(MINIDUMP_MODULE); | |
| 233 | |
| 234 const auto& module_crashpad_info_it = | |
| 235 module_crashpad_info_links.find(module_index); | |
| 236 const MINIDUMP_LOCATION_DESCRIPTOR* module_crashpad_info_location = | |
| 237 module_crashpad_info_it != module_crashpad_info_links.end() | |
| 238 ? &module_crashpad_info_it->second | |
| 239 : nullptr; | |
| 240 | |
| 241 if (!module->Initialize( | |
| 242 file_reader_, module_rva, module_crashpad_info_location)) { | |
| 243 delete module; | |
| 244 modules_.pop_back(); | |
| 245 return false; | |
| 246 } | |
| 247 } | |
| 248 | |
| 249 return true; | |
| 250 } | |
| 251 | |
| 252 void ProcessSnapshotMinidump::InitializeModulesCrashpadInfo( | |
| 253 std::map<uint32_t, MINIDUMP_LOCATION_DESCRIPTOR>* | |
| 254 module_crashpad_info_links) { | |
| 255 module_crashpad_info_links->clear(); | |
| 256 | |
| 257 if (crashpad_info_.version != MinidumpCrashpadInfo::kVersion) { | |
| 258 return; | |
| 259 } | |
| 260 | |
| 261 if (crashpad_info_.module_list.Rva == 0) { | |
| 262 return; | |
| 263 } | |
| 264 | |
| 265 if (crashpad_info_.module_list.DataSize < | |
| 266 sizeof(MinidumpModuleCrashpadInfoList)) { | |
|
Robert Sesek
2015/03/04 01:52:25
nit: indent +4
| |
| 267 LOG(ERROR) << "module_crashpad_info_list size mismatch"; | |
| 268 return; | |
| 269 } | |
| 270 | |
| 271 if (!file_reader_->SeekSet(crashpad_info_.module_list.Rva)) { | |
| 272 return; | |
| 273 } | |
| 274 | |
| 275 uint32_t crashpad_module_count; | |
| 276 if (!file_reader_->ReadExactly(&crashpad_module_count, | |
| 277 sizeof(crashpad_module_count))) { | |
| 278 return; | |
|
Robert Sesek
2015/03/04 01:52:25
Similar comment as to returning false under failur
| |
| 279 } | |
| 280 | |
| 281 if (crashpad_info_.module_list.DataSize != | |
| 282 sizeof(MinidumpModuleCrashpadInfoList) + | |
| 283 crashpad_module_count * sizeof(MinidumpModuleCrashpadInfoLink)) { | |
| 284 LOG(ERROR) << "module_crashpad_info_list size mismatch"; | |
| 285 return; | |
| 286 } | |
| 287 | |
| 288 scoped_ptr<MinidumpModuleCrashpadInfoLink[]> minidump_links( | |
| 289 new MinidumpModuleCrashpadInfoLink[crashpad_module_count]); | |
| 290 if (!file_reader_->ReadExactly( | |
| 291 &minidump_links[0], | |
| 292 crashpad_module_count * sizeof(MinidumpModuleCrashpadInfoLink))) { | |
| 293 return; | |
| 294 } | |
| 295 | |
| 296 for (uint32_t crashpad_module_index = 0; | |
| 297 crashpad_module_index < crashpad_module_count; | |
| 298 ++crashpad_module_index) { | |
| 299 const MinidumpModuleCrashpadInfoLink& minidump_link = | |
| 300 minidump_links[crashpad_module_index]; | |
| 301 if (module_crashpad_info_links->find( | |
| 302 minidump_link.minidump_module_list_index) != | |
| 303 module_crashpad_info_links->end()) { | |
| 304 LOG(WARNING) | |
| 305 << "duplicate module_crashpad_info_list minidump_module_list_index " | |
| 306 << minidump_link.minidump_module_list_index << ", discarding"; | |
| 307 } else { | |
| 308 module_crashpad_info_links->insert(std::make_pair( | |
| 309 minidump_link.minidump_module_list_index, minidump_link.location)); | |
| 310 } | |
| 311 } | |
| 312 } | |
| 313 | |
| 189 } // namespace crashpad | 314 } // namespace crashpad |
| OLD | NEW |