2015-02-26 14:43:10 -05:00
|
|
|
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
#include "snapshot/minidump/process_snapshot_minidump.h"
|
|
|
|
|
2015-03-04 12:29:01 -05:00
|
|
|
#include <utility>
|
|
|
|
|
2018-10-22 11:14:09 -07:00
|
|
|
#include "snapshot/memory_map_region_snapshot.h"
|
2015-02-26 14:43:10 -05:00
|
|
|
#include "snapshot/minidump/minidump_simple_string_dictionary_reader.h"
|
2016-04-25 12:13:07 -07:00
|
|
|
#include "util/file/file_io.h"
|
2015-02-26 14:43:10 -05:00
|
|
|
|
|
|
|
namespace crashpad {
|
|
|
|
|
2018-10-22 11:14:09 -07:00
|
|
|
namespace internal {
|
|
|
|
|
|
|
|
class MemoryMapRegionSnapshotMinidump : public MemoryMapRegionSnapshot {
|
|
|
|
public:
|
|
|
|
MemoryMapRegionSnapshotMinidump(MINIDUMP_MEMORY_INFO info) : info_(info) {}
|
|
|
|
~MemoryMapRegionSnapshotMinidump() override = default;
|
|
|
|
|
|
|
|
const MINIDUMP_MEMORY_INFO& AsMinidumpMemoryInfo() const override {
|
|
|
|
return info_;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
MINIDUMP_MEMORY_INFO info_;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
|
2015-02-26 14:43:10 -05:00
|
|
|
ProcessSnapshotMinidump::ProcessSnapshotMinidump()
|
|
|
|
: ProcessSnapshot(),
|
|
|
|
header_(),
|
|
|
|
stream_directory_(),
|
|
|
|
stream_map_(),
|
2015-03-04 12:29:01 -05:00
|
|
|
modules_(),
|
2016-02-11 17:19:30 -08:00
|
|
|
unloaded_modules_(),
|
2015-02-26 14:43:10 -05:00
|
|
|
crashpad_info_(),
|
2018-10-15 15:20:48 -07:00
|
|
|
system_snapshot_(),
|
2018-10-16 12:23:21 -07:00
|
|
|
arch_(CPUArchitecture::kCPUArchitectureUnknown),
|
2015-02-26 14:43:10 -05:00
|
|
|
annotations_simple_map_(),
|
|
|
|
file_reader_(nullptr),
|
2018-07-24 09:21:51 -07:00
|
|
|
process_id_(static_cast<pid_t>(-1)),
|
2015-02-26 14:43:10 -05:00
|
|
|
initialized_() {
|
|
|
|
}
|
|
|
|
|
|
|
|
ProcessSnapshotMinidump::~ProcessSnapshotMinidump() {
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProcessSnapshotMinidump::Initialize(FileReaderInterface* file_reader) {
|
|
|
|
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
|
|
|
|
|
|
|
|
file_reader_ = file_reader;
|
|
|
|
|
|
|
|
if (!file_reader_->SeekSet(0)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!file_reader_->ReadExactly(&header_, sizeof(header_))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (header_.Signature != MINIDUMP_SIGNATURE) {
|
|
|
|
LOG(ERROR) << "minidump signature mismatch";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (header_.Version != MINIDUMP_VERSION) {
|
|
|
|
LOG(ERROR) << "minidump version mismatch";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!file_reader->SeekSet(header_.StreamDirectoryRva)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream_directory_.resize(header_.NumberOfStreams);
|
2015-08-20 11:50:19 -04:00
|
|
|
if (!stream_directory_.empty() &&
|
|
|
|
!file_reader_->ReadExactly(
|
2015-02-26 14:43:10 -05:00
|
|
|
&stream_directory_[0],
|
|
|
|
header_.NumberOfStreams * sizeof(stream_directory_[0]))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const MINIDUMP_DIRECTORY& directory : stream_directory_) {
|
|
|
|
const MinidumpStreamType stream_type =
|
|
|
|
static_cast<MinidumpStreamType>(directory.StreamType);
|
|
|
|
if (stream_map_.find(stream_type) != stream_map_.end()) {
|
|
|
|
LOG(ERROR) << "duplicate streams for type " << directory.StreamType;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream_map_[stream_type] = &directory.Location;
|
|
|
|
}
|
|
|
|
|
2018-07-24 09:21:51 -07:00
|
|
|
if (!InitializeCrashpadInfo() ||
|
|
|
|
!InitializeMiscInfo() ||
|
2018-10-12 13:12:01 -07:00
|
|
|
!InitializeModules() ||
|
2018-10-16 12:23:21 -07:00
|
|
|
!InitializeSystemSnapshot() ||
|
2018-10-22 11:14:09 -07:00
|
|
|
!InitializeMemoryInfo() ||
|
2018-10-16 12:23:21 -07:00
|
|
|
!InitializeThreads()) {
|
2015-03-04 12:29:01 -05:00
|
|
|
return false;
|
|
|
|
}
|
2015-02-26 14:43:10 -05:00
|
|
|
|
2018-07-24 09:21:51 -07:00
|
|
|
INITIALIZATION_STATE_SET_VALID(initialized_);
|
|
|
|
return true;
|
2015-02-26 14:43:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pid_t ProcessSnapshotMinidump::ProcessID() const {
|
|
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
2018-07-24 09:21:51 -07:00
|
|
|
return process_id_;
|
2015-02-26 14:43:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pid_t ProcessSnapshotMinidump::ParentProcessID() const {
|
|
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
2015-10-29 18:31:20 -04:00
|
|
|
NOTREACHED(); // https://crashpad.chromium.org/bug/10
|
2015-02-26 14:43:10 -05:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProcessSnapshotMinidump::SnapshotTime(timeval* snapshot_time) const {
|
|
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
2015-10-29 18:31:20 -04:00
|
|
|
NOTREACHED(); // https://crashpad.chromium.org/bug/10
|
2015-02-26 14:43:10 -05:00
|
|
|
snapshot_time->tv_sec = 0;
|
|
|
|
snapshot_time->tv_usec = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProcessSnapshotMinidump::ProcessStartTime(timeval* start_time) const {
|
|
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
2015-10-29 18:31:20 -04:00
|
|
|
NOTREACHED(); // https://crashpad.chromium.org/bug/10
|
2015-02-26 14:43:10 -05:00
|
|
|
start_time->tv_sec = 0;
|
|
|
|
start_time->tv_usec = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProcessSnapshotMinidump::ProcessCPUTimes(timeval* user_time,
|
|
|
|
timeval* system_time) const {
|
|
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
2015-10-29 18:31:20 -04:00
|
|
|
NOTREACHED(); // https://crashpad.chromium.org/bug/10
|
2015-02-26 14:43:10 -05:00
|
|
|
user_time->tv_sec = 0;
|
|
|
|
user_time->tv_usec = 0;
|
|
|
|
system_time->tv_sec = 0;
|
|
|
|
system_time->tv_usec = 0;
|
|
|
|
}
|
|
|
|
|
2015-03-13 13:00:56 -04:00
|
|
|
void ProcessSnapshotMinidump::ReportID(UUID* report_id) const {
|
|
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
|
|
*report_id = crashpad_info_.report_id;
|
|
|
|
}
|
|
|
|
|
2015-03-11 17:10:50 -04:00
|
|
|
void ProcessSnapshotMinidump::ClientID(UUID* client_id) const {
|
|
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
|
|
*client_id = crashpad_info_.client_id;
|
|
|
|
}
|
|
|
|
|
2015-02-26 14:43:10 -05:00
|
|
|
const std::map<std::string, std::string>&
|
|
|
|
ProcessSnapshotMinidump::AnnotationsSimpleMap() const {
|
|
|
|
// TODO(mark): This method should not be const, although the interface
|
|
|
|
// currently imposes this requirement. Making it non-const would allow
|
|
|
|
// annotations_simple_map_ to be lazily constructed: InitializeCrashpadInfo()
|
|
|
|
// could be called here, and from other locations that require it, rather than
|
|
|
|
// calling it from Initialize().
|
2015-10-29 18:31:20 -04:00
|
|
|
// https://crashpad.chromium.org/bug/9
|
2015-02-26 14:43:10 -05:00
|
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
|
|
return annotations_simple_map_;
|
|
|
|
}
|
|
|
|
|
|
|
|
const SystemSnapshot* ProcessSnapshotMinidump::System() const {
|
|
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
2018-10-15 15:20:48 -07:00
|
|
|
return &system_snapshot_;
|
2015-02-26 14:43:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<const ThreadSnapshot*> ProcessSnapshotMinidump::Threads() const {
|
|
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
2018-10-12 13:12:01 -07:00
|
|
|
std::vector<const ThreadSnapshot*> threads;
|
|
|
|
for (const auto& thread : threads_) {
|
|
|
|
threads.push_back(thread.get());
|
|
|
|
}
|
|
|
|
return threads;
|
2015-02-26 14:43:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<const ModuleSnapshot*> ProcessSnapshotMinidump::Modules() const {
|
|
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
2015-03-04 12:29:01 -05:00
|
|
|
std::vector<const ModuleSnapshot*> modules;
|
2017-10-19 00:26:38 -04:00
|
|
|
for (const auto& module : modules_) {
|
|
|
|
modules.push_back(module.get());
|
2015-03-04 12:29:01 -05:00
|
|
|
}
|
|
|
|
return modules;
|
2015-02-26 14:43:10 -05:00
|
|
|
}
|
|
|
|
|
2016-02-11 17:19:30 -08:00
|
|
|
std::vector<UnloadedModuleSnapshot> ProcessSnapshotMinidump::UnloadedModules()
|
|
|
|
const {
|
|
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
|
|
NOTREACHED(); // https://crashpad.chromium.org/bug/10
|
|
|
|
return unloaded_modules_;
|
|
|
|
}
|
|
|
|
|
2015-02-26 14:43:10 -05:00
|
|
|
const ExceptionSnapshot* ProcessSnapshotMinidump::Exception() const {
|
|
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
2015-10-29 18:31:20 -04:00
|
|
|
NOTREACHED(); // https://crashpad.chromium.org/bug/10
|
2015-02-26 14:43:10 -05:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2015-10-13 12:37:44 -07:00
|
|
|
std::vector<const MemoryMapRegionSnapshot*> ProcessSnapshotMinidump::MemoryMap()
|
|
|
|
const {
|
|
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
2018-10-22 11:14:09 -07:00
|
|
|
return mem_regions_exposed_;
|
2015-10-13 12:37:44 -07:00
|
|
|
}
|
|
|
|
|
2015-10-16 15:58:40 -07:00
|
|
|
std::vector<HandleSnapshot> ProcessSnapshotMinidump::Handles() const {
|
|
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
2015-10-29 18:31:20 -04:00
|
|
|
NOTREACHED(); // https://crashpad.chromium.org/bug/10
|
2015-10-16 15:58:40 -07:00
|
|
|
return std::vector<HandleSnapshot>();
|
|
|
|
}
|
|
|
|
|
2015-09-25 10:31:02 -07:00
|
|
|
std::vector<const MemorySnapshot*> ProcessSnapshotMinidump::ExtraMemory()
|
|
|
|
const {
|
|
|
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
2015-10-29 18:31:20 -04:00
|
|
|
NOTREACHED(); // https://crashpad.chromium.org/bug/10
|
2015-09-25 10:31:02 -07:00
|
|
|
return std::vector<const MemorySnapshot*>();
|
|
|
|
}
|
|
|
|
|
2015-03-04 12:29:01 -05:00
|
|
|
bool ProcessSnapshotMinidump::InitializeCrashpadInfo() {
|
|
|
|
const auto& stream_it = stream_map_.find(kMinidumpStreamTypeCrashpadInfo);
|
|
|
|
if (stream_it == stream_map_.end()) {
|
|
|
|
return true;
|
2015-02-26 14:43:10 -05:00
|
|
|
}
|
|
|
|
|
2015-03-04 12:29:01 -05:00
|
|
|
if (stream_it->second->DataSize < sizeof(crashpad_info_)) {
|
2015-02-26 14:43:10 -05:00
|
|
|
LOG(ERROR) << "crashpad_info size mismatch";
|
2015-03-04 12:29:01 -05:00
|
|
|
return false;
|
2015-02-26 14:43:10 -05:00
|
|
|
}
|
|
|
|
|
2015-03-04 12:29:01 -05:00
|
|
|
if (!file_reader_->SeekSet(stream_it->second->Rva)) {
|
|
|
|
return false;
|
2015-02-26 14:43:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!file_reader_->ReadExactly(&crashpad_info_, sizeof(crashpad_info_))) {
|
2015-03-04 12:29:01 -05:00
|
|
|
return false;
|
2015-02-26 14:43:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (crashpad_info_.version != MinidumpCrashpadInfo::kVersion) {
|
|
|
|
LOG(ERROR) << "crashpad_info version mismatch";
|
2015-03-04 12:29:01 -05:00
|
|
|
return false;
|
2015-02-26 14:43:10 -05:00
|
|
|
}
|
|
|
|
|
2015-03-04 12:29:01 -05:00
|
|
|
return internal::ReadMinidumpSimpleStringDictionary(
|
2015-02-26 14:43:10 -05:00
|
|
|
file_reader_,
|
|
|
|
crashpad_info_.simple_annotations,
|
|
|
|
&annotations_simple_map_);
|
|
|
|
}
|
|
|
|
|
2018-07-24 09:21:51 -07:00
|
|
|
bool ProcessSnapshotMinidump::InitializeMiscInfo() {
|
|
|
|
const auto& stream_it = stream_map_.find(kMinidumpStreamTypeMiscInfo);
|
|
|
|
if (stream_it == stream_map_.end()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!file_reader_->SeekSet(stream_it->second->Rva)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const size_t size = stream_it->second->DataSize;
|
|
|
|
if (size != sizeof(MINIDUMP_MISC_INFO_5) &&
|
|
|
|
size != sizeof(MINIDUMP_MISC_INFO_4) &&
|
|
|
|
size != sizeof(MINIDUMP_MISC_INFO_3) &&
|
|
|
|
size != sizeof(MINIDUMP_MISC_INFO_2) &&
|
|
|
|
size != sizeof(MINIDUMP_MISC_INFO)) {
|
|
|
|
LOG(ERROR) << "misc_info size mismatch";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
MINIDUMP_MISC_INFO_5 info;
|
|
|
|
if (!file_reader_->ReadExactly(&info, size)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (stream_it->second->DataSize) {
|
|
|
|
case sizeof(MINIDUMP_MISC_INFO_5):
|
|
|
|
case sizeof(MINIDUMP_MISC_INFO_4):
|
|
|
|
case sizeof(MINIDUMP_MISC_INFO_3):
|
|
|
|
case sizeof(MINIDUMP_MISC_INFO_2):
|
|
|
|
case sizeof(MINIDUMP_MISC_INFO):
|
|
|
|
// TODO(jperaza): Save the remaining misc info.
|
|
|
|
// https://crashpad.chromium.org/bug/10
|
|
|
|
process_id_ = info.ProcessId;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-03-04 12:29:01 -05:00
|
|
|
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;
|
|
|
|
if (!InitializeModulesCrashpadInfo(&module_crashpad_info_links)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
|
|
|
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;
|
|
|
|
|
2017-10-12 12:42:28 -04:00
|
|
|
auto module = std::make_unique<internal::ModuleSnapshotMinidump>();
|
2015-03-04 12:29:01 -05:00
|
|
|
if (!module->Initialize(
|
|
|
|
file_reader_, module_rva, module_crashpad_info_location)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-10-19 00:26:38 -04:00
|
|
|
modules_.push_back(std::move(module));
|
2015-03-04 12:29:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool 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 false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (crashpad_info_.module_list.Rva == 0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (crashpad_info_.module_list.DataSize <
|
|
|
|
sizeof(MinidumpModuleCrashpadInfoList)) {
|
|
|
|
LOG(ERROR) << "module_crashpad_info_list size mismatch";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!file_reader_->SeekSet(crashpad_info_.module_list.Rva)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t crashpad_module_count;
|
|
|
|
if (!file_reader_->ReadExactly(&crashpad_module_count,
|
|
|
|
sizeof(crashpad_module_count))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (crashpad_info_.module_list.DataSize !=
|
|
|
|
sizeof(MinidumpModuleCrashpadInfoList) +
|
|
|
|
crashpad_module_count * sizeof(MinidumpModuleCrashpadInfoLink)) {
|
|
|
|
LOG(ERROR) << "module_crashpad_info_list size mismatch";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-04-25 12:13:07 -07:00
|
|
|
std::unique_ptr<MinidumpModuleCrashpadInfoLink[]> minidump_links(
|
2015-03-04 12:29:01 -05:00
|
|
|
new MinidumpModuleCrashpadInfoLink[crashpad_module_count]);
|
|
|
|
if (!file_reader_->ReadExactly(
|
|
|
|
&minidump_links[0],
|
|
|
|
crashpad_module_count * sizeof(MinidumpModuleCrashpadInfoLink))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
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];
|
2015-03-31 14:29:32 -04:00
|
|
|
if (!module_crashpad_info_links
|
|
|
|
->insert(std::make_pair(minidump_link.minidump_module_list_index,
|
|
|
|
minidump_link.location)).second) {
|
2015-03-04 12:29:01 -05:00
|
|
|
LOG(WARNING)
|
|
|
|
<< "duplicate module_crashpad_info_list minidump_module_list_index "
|
|
|
|
<< minidump_link.minidump_module_list_index;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-10-22 11:14:09 -07:00
|
|
|
bool ProcessSnapshotMinidump::InitializeMemoryInfo() {
|
|
|
|
const auto& stream_it = stream_map_.find(kMinidumpStreamTypeMemoryInfoList);
|
|
|
|
if (stream_it == stream_map_.end()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stream_it->second->DataSize < sizeof(MINIDUMP_MEMORY_INFO_LIST)) {
|
|
|
|
LOG(ERROR) << "memory_info_list size mismatch";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!file_reader_->SeekSet(stream_it->second->Rva)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
MINIDUMP_MEMORY_INFO_LIST list;
|
|
|
|
|
|
|
|
if (!file_reader_->ReadExactly(&list, sizeof(list))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (list.SizeOfHeader != sizeof(list)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (list.SizeOfEntry != sizeof(MINIDUMP_MEMORY_INFO)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sizeof(MINIDUMP_MEMORY_INFO_LIST) +
|
|
|
|
list.NumberOfEntries * list.SizeOfEntry != stream_it->second->DataSize) {
|
|
|
|
LOG(ERROR) << "memory_info_list size mismatch";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < list.NumberOfEntries; i++) {
|
|
|
|
MINIDUMP_MEMORY_INFO info;
|
|
|
|
|
|
|
|
if (!file_reader_->ReadExactly(&info, sizeof(info))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
mem_regions_.emplace_back(
|
|
|
|
std::make_unique<internal::MemoryMapRegionSnapshotMinidump>(info));
|
|
|
|
mem_regions_exposed_.emplace_back(mem_regions_.back().get());
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-10-12 13:12:01 -07:00
|
|
|
bool ProcessSnapshotMinidump::InitializeThreads() {
|
|
|
|
const auto& stream_it = stream_map_.find(kMinidumpStreamTypeThreadList);
|
|
|
|
if (stream_it == stream_map_.end()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stream_it->second->DataSize < sizeof(MINIDUMP_THREAD_LIST)) {
|
|
|
|
LOG(ERROR) << "thread_list size mismatch";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!file_reader_->SeekSet(stream_it->second->Rva)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t thread_count;
|
|
|
|
if (!file_reader_->ReadExactly(&thread_count, sizeof(thread_count))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sizeof(MINIDUMP_THREAD_LIST) + thread_count * sizeof(MINIDUMP_THREAD) !=
|
|
|
|
stream_it->second->DataSize) {
|
|
|
|
LOG(ERROR) << "thread_list size mismatch";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint32_t thread_index = 0; thread_index < thread_count; ++thread_index) {
|
|
|
|
const RVA thread_rva = stream_it->second->Rva + sizeof(thread_count) +
|
|
|
|
thread_index * sizeof(MINIDUMP_THREAD);
|
|
|
|
|
|
|
|
auto thread = std::make_unique<internal::ThreadSnapshotMinidump>();
|
2018-10-16 12:23:21 -07:00
|
|
|
if (!thread->Initialize(file_reader_, thread_rva, arch_)) {
|
2018-10-12 13:12:01 -07:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
threads_.push_back(std::move(thread));
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-10-15 15:20:48 -07:00
|
|
|
bool ProcessSnapshotMinidump::InitializeSystemSnapshot() {
|
|
|
|
const auto& stream_it = stream_map_.find(kMinidumpStreamTypeSystemInfo);
|
|
|
|
if (stream_it == stream_map_.end()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stream_it->second->DataSize < sizeof(MINIDUMP_SYSTEM_INFO)) {
|
|
|
|
LOG(ERROR) << "system info size mismatch";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-10-16 12:23:21 -07:00
|
|
|
if (!system_snapshot_.Initialize(file_reader_, stream_it->second->Rva)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
arch_ = system_snapshot_.GetCPUArchitecture();
|
|
|
|
return true;
|
2018-10-15 15:20:48 -07:00
|
|
|
}
|
|
|
|
|
2015-02-26 14:43:10 -05:00
|
|
|
} // namespace crashpad
|