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 |