Chromium Code Reviews| Index: snapshot/minidump/process_snapshot_minidump.cc |
| diff --git a/snapshot/minidump/process_snapshot_minidump.cc b/snapshot/minidump/process_snapshot_minidump.cc |
| index a882c7cdb4818201b16f0fbdcffdd104c2560e8e..f172a56bd4dd4521e4f65e5a00bc38e841e5452c 100644 |
| --- a/snapshot/minidump/process_snapshot_minidump.cc |
| +++ b/snapshot/minidump/process_snapshot_minidump.cc |
| @@ -14,6 +14,9 @@ |
| #include "snapshot/minidump/process_snapshot_minidump.h" |
| +#include <utility> |
| + |
| +#include "base/memory/scoped_ptr.h" |
| #include "util/file/file_io.h" |
| #include "snapshot/minidump/minidump_simple_string_dictionary_reader.h" |
| @@ -24,6 +27,7 @@ ProcessSnapshotMinidump::ProcessSnapshotMinidump() |
| header_(), |
| stream_directory_(), |
| stream_map_(), |
| + modules_(), |
| crashpad_info_(), |
| annotations_simple_map_(), |
| file_reader_(nullptr), |
| @@ -81,6 +85,7 @@ bool ProcessSnapshotMinidump::Initialize(FileReaderInterface* file_reader) { |
| INITIALIZATION_STATE_SET_VALID(initialized_); |
| InitializeCrashpadInfo(); |
| + InitializeModules(); |
| return true; |
| } |
| @@ -146,8 +151,11 @@ std::vector<const ThreadSnapshot*> ProcessSnapshotMinidump::Threads() const { |
| std::vector<const ModuleSnapshot*> ProcessSnapshotMinidump::Modules() const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| - NOTREACHED(); |
| - return std::vector<const ModuleSnapshot*>(); |
| + std::vector<const ModuleSnapshot*> modules; |
| + for (internal::ModuleSnapshotMinidump* module : modules_) { |
| + modules.push_back(module); |
| + } |
| + return modules; |
| } |
| const ExceptionSnapshot* ProcessSnapshotMinidump::Exception() const { |
| @@ -157,17 +165,17 @@ const ExceptionSnapshot* ProcessSnapshotMinidump::Exception() const { |
| } |
| void ProcessSnapshotMinidump::InitializeCrashpadInfo() { |
| - const auto& it = stream_map_.find(kMinidumpStreamTypeCrashpadInfo); |
| - if (it == stream_map_.end()) { |
| + const auto& stream_it = stream_map_.find(kMinidumpStreamTypeCrashpadInfo); |
| + if (stream_it == stream_map_.end()) { |
| return; |
| } |
| - if (it->second->DataSize < sizeof(crashpad_info_)) { |
| + if (stream_it->second->DataSize < sizeof(crashpad_info_)) { |
| LOG(ERROR) << "crashpad_info size mismatch"; |
| return; |
| } |
| - if (!file_reader_->SeekSet(it->second->Rva)) { |
| + if (!file_reader_->SeekSet(stream_it->second->Rva)) { |
| return; |
| } |
| @@ -186,4 +194,121 @@ void ProcessSnapshotMinidump::InitializeCrashpadInfo() { |
| &annotations_simple_map_); |
| } |
| +bool ProcessSnapshotMinidump::InitializeModules() { |
| + const auto& stream_it = stream_map_.find(kMinidumpStreamTypeModuleList); |
| + if (stream_it == stream_map_.end()) { |
| + return true; |
| + } |
| + |
| + std::map<uint32_t, MINIDUMP_LOCATION_DESCRIPTOR> module_crashpad_info_links; |
| + InitializeModulesCrashpadInfo(&module_crashpad_info_links); |
| + |
| + if (stream_it->second->DataSize < sizeof(MINIDUMP_MODULE_LIST)) { |
| + LOG(ERROR) << "module_list size mismatch"; |
| + return false; |
| + } |
| + |
| + if (!file_reader_->SeekSet(stream_it->second->Rva)) { |
| + return false; |
| + } |
| + |
| + uint32_t module_count; |
| + if (!file_reader_->ReadExactly(&module_count, sizeof(module_count))) { |
| + return false; |
| + } |
| + |
| + if (sizeof(MINIDUMP_MODULE_LIST) + module_count * sizeof(MINIDUMP_MODULE) != |
| + stream_it->second->DataSize) { |
| + LOG(ERROR) << "module_list size mismatch"; |
| + return false; |
| + } |
| + |
| + for (uint32_t module_index = 0; module_index < module_count; ++module_index) { |
| + internal::ModuleSnapshotMinidump* module = |
|
Robert Sesek
2015/03/04 01:52:25
Similar to the earlier comment, it'll be easier to
|
| + new internal::ModuleSnapshotMinidump(); |
| + modules_.push_back(module); |
| + |
| + const RVA module_rva = stream_it->second->Rva + sizeof(module_count) + |
| + module_index * sizeof(MINIDUMP_MODULE); |
| + |
| + const auto& module_crashpad_info_it = |
| + module_crashpad_info_links.find(module_index); |
| + const MINIDUMP_LOCATION_DESCRIPTOR* module_crashpad_info_location = |
| + module_crashpad_info_it != module_crashpad_info_links.end() |
| + ? &module_crashpad_info_it->second |
| + : nullptr; |
| + |
| + if (!module->Initialize( |
| + file_reader_, module_rva, module_crashpad_info_location)) { |
| + delete module; |
| + modules_.pop_back(); |
| + return false; |
| + } |
| + } |
| + |
| + return true; |
| +} |
| + |
| +void ProcessSnapshotMinidump::InitializeModulesCrashpadInfo( |
| + std::map<uint32_t, MINIDUMP_LOCATION_DESCRIPTOR>* |
| + module_crashpad_info_links) { |
| + module_crashpad_info_links->clear(); |
| + |
| + if (crashpad_info_.version != MinidumpCrashpadInfo::kVersion) { |
| + return; |
| + } |
| + |
| + if (crashpad_info_.module_list.Rva == 0) { |
| + return; |
| + } |
| + |
| + if (crashpad_info_.module_list.DataSize < |
| + sizeof(MinidumpModuleCrashpadInfoList)) { |
|
Robert Sesek
2015/03/04 01:52:25
nit: indent +4
|
| + LOG(ERROR) << "module_crashpad_info_list size mismatch"; |
| + return; |
| + } |
| + |
| + if (!file_reader_->SeekSet(crashpad_info_.module_list.Rva)) { |
| + return; |
| + } |
| + |
| + uint32_t crashpad_module_count; |
| + if (!file_reader_->ReadExactly(&crashpad_module_count, |
| + sizeof(crashpad_module_count))) { |
| + return; |
|
Robert Sesek
2015/03/04 01:52:25
Similar comment as to returning false under failur
|
| + } |
| + |
| + if (crashpad_info_.module_list.DataSize != |
| + sizeof(MinidumpModuleCrashpadInfoList) + |
| + crashpad_module_count * sizeof(MinidumpModuleCrashpadInfoLink)) { |
| + LOG(ERROR) << "module_crashpad_info_list size mismatch"; |
| + return; |
| + } |
| + |
| + scoped_ptr<MinidumpModuleCrashpadInfoLink[]> minidump_links( |
| + new MinidumpModuleCrashpadInfoLink[crashpad_module_count]); |
| + if (!file_reader_->ReadExactly( |
| + &minidump_links[0], |
| + crashpad_module_count * sizeof(MinidumpModuleCrashpadInfoLink))) { |
| + return; |
| + } |
| + |
| + for (uint32_t crashpad_module_index = 0; |
| + crashpad_module_index < crashpad_module_count; |
| + ++crashpad_module_index) { |
| + const MinidumpModuleCrashpadInfoLink& minidump_link = |
| + minidump_links[crashpad_module_index]; |
| + if (module_crashpad_info_links->find( |
| + minidump_link.minidump_module_list_index) != |
| + module_crashpad_info_links->end()) { |
| + LOG(WARNING) |
| + << "duplicate module_crashpad_info_list minidump_module_list_index " |
| + << minidump_link.minidump_module_list_index << ", discarding"; |
| + } else { |
| + module_crashpad_info_links->insert(std::make_pair( |
| + minidump_link.minidump_module_list_index, minidump_link.location)); |
| + } |
| + } |
| +} |
| + |
| } // namespace crashpad |