mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-27 23:41:02 +08:00
Implement MemoryMap for ProcessSnapshotMinidump
Bug: crashpad:10 Change-Id: Icca05321b729fd869a371707940fab40e12e8e22 Reviewed-on: https://chromium-review.googlesource.com/c/1294254 Commit-Queue: Casey Dahlin <sadmac@google.com> Reviewed-by: Scott Graham <scottmg@chromium.org>
This commit is contained in:
parent
bf327d8ceb
commit
411f0ae41d
@ -16,11 +16,29 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "snapshot/memory_map_region_snapshot.h"
|
||||
#include "snapshot/minidump/minidump_simple_string_dictionary_reader.h"
|
||||
#include "util/file/file_io.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
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
|
||||
|
||||
ProcessSnapshotMinidump::ProcessSnapshotMinidump()
|
||||
: ProcessSnapshot(),
|
||||
header_(),
|
||||
@ -90,6 +108,7 @@ bool ProcessSnapshotMinidump::Initialize(FileReaderInterface* file_reader) {
|
||||
!InitializeMiscInfo() ||
|
||||
!InitializeModules() ||
|
||||
!InitializeSystemSnapshot() ||
|
||||
!InitializeMemoryInfo() ||
|
||||
!InitializeThreads()) {
|
||||
return false;
|
||||
}
|
||||
@ -194,8 +213,7 @@ const ExceptionSnapshot* ProcessSnapshotMinidump::Exception() const {
|
||||
std::vector<const MemoryMapRegionSnapshot*> ProcessSnapshotMinidump::MemoryMap()
|
||||
const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
NOTREACHED(); // https://crashpad.chromium.org/bug/10
|
||||
return std::vector<const MemoryMapRegionSnapshot*>();
|
||||
return mem_regions_exposed_;
|
||||
}
|
||||
|
||||
std::vector<HandleSnapshot> ProcessSnapshotMinidump::Handles() const {
|
||||
@ -396,6 +414,56 @@ bool ProcessSnapshotMinidump::InitializeModulesCrashpadInfo(
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool ProcessSnapshotMinidump::InitializeThreads() {
|
||||
const auto& stream_it = stream_map_.find(kMinidumpStreamTypeThreadList);
|
||||
if (stream_it == stream_map_.end()) {
|
||||
|
@ -43,6 +43,10 @@
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
namespace internal {
|
||||
class MemoryMapRegionSnapshotMinidump;
|
||||
} // namespace internal
|
||||
|
||||
//! \brief A ProcessSnapshot based on a minidump file.
|
||||
class ProcessSnapshotMinidump final : public ProcessSnapshot {
|
||||
public:
|
||||
@ -91,6 +95,10 @@ class ProcessSnapshotMinidump final : public ProcessSnapshot {
|
||||
// Initialize().
|
||||
bool InitializeThreads();
|
||||
|
||||
// Initializes data carried in a MINIDUMP_MEMORY_INFO_LIST stream on behalf of
|
||||
// Initialize().
|
||||
bool InitializeMemoryInfo();
|
||||
|
||||
// Initializes data carried in a MINIDUMP_SYSTEM_INFO stream on behalf of
|
||||
// Initialize().
|
||||
bool InitializeSystemSnapshot();
|
||||
@ -112,6 +120,9 @@ class ProcessSnapshotMinidump final : public ProcessSnapshot {
|
||||
std::vector<std::unique_ptr<internal::ModuleSnapshotMinidump>> modules_;
|
||||
std::vector<std::unique_ptr<internal::ThreadSnapshotMinidump>> threads_;
|
||||
std::vector<UnloadedModuleSnapshot> unloaded_modules_;
|
||||
std::vector<std::unique_ptr<internal::MemoryMapRegionSnapshotMinidump>>
|
||||
mem_regions_;
|
||||
std::vector<const MemoryMapRegionSnapshot*> mem_regions_exposed_;
|
||||
MinidumpCrashpadInfo crashpad_info_;
|
||||
internal::SystemSnapshotMinidump system_snapshot_;
|
||||
CPUArchitecture arch_;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "minidump/minidump_context.h"
|
||||
#include "snapshot/minidump/minidump_annotation_reader.h"
|
||||
#include "snapshot/memory_map_region_snapshot.h"
|
||||
#include "snapshot/module_snapshot.h"
|
||||
#include "util/file/string_file.h"
|
||||
#include "util/misc/pdb_structures.h"
|
||||
@ -968,6 +969,76 @@ TEST(ProcessSnapshotMinidump, ThreadContextX86_64) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ProcessSnapshotMinidump, MemoryMap) {
|
||||
StringFile string_file;
|
||||
|
||||
MINIDUMP_HEADER header = {};
|
||||
EXPECT_TRUE(string_file.Write(&header, sizeof(header)));
|
||||
|
||||
MINIDUMP_MEMORY_INFO minidump_memory_info_1 = {};
|
||||
MINIDUMP_MEMORY_INFO minidump_memory_info_2 = {};
|
||||
uint32_t minidump_memory_info_count = 2;
|
||||
|
||||
minidump_memory_info_1.BaseAddress = 1;
|
||||
minidump_memory_info_1.AllocationBase = 2;
|
||||
minidump_memory_info_1.AllocationProtect = 3;
|
||||
minidump_memory_info_1.RegionSize = 4;
|
||||
minidump_memory_info_1.State = 5;
|
||||
minidump_memory_info_1.Protect = 6;
|
||||
minidump_memory_info_1.Type = 6;
|
||||
|
||||
minidump_memory_info_2.BaseAddress = 7;
|
||||
minidump_memory_info_2.AllocationBase = 8;
|
||||
minidump_memory_info_2.AllocationProtect = 9;
|
||||
minidump_memory_info_2.RegionSize = 10;
|
||||
minidump_memory_info_2.State = 11;
|
||||
minidump_memory_info_2.Protect = 12;
|
||||
minidump_memory_info_2.Type = 13;
|
||||
|
||||
MINIDUMP_MEMORY_INFO_LIST minidump_memory_info_list = {};
|
||||
|
||||
minidump_memory_info_list.SizeOfHeader = sizeof(minidump_memory_info_list);
|
||||
minidump_memory_info_list.SizeOfEntry = sizeof(MINIDUMP_MEMORY_INFO);
|
||||
minidump_memory_info_list.NumberOfEntries = minidump_memory_info_count;
|
||||
|
||||
MINIDUMP_DIRECTORY minidump_memory_info_list_directory = {};
|
||||
minidump_memory_info_list_directory.StreamType =
|
||||
kMinidumpStreamTypeMemoryInfoList;
|
||||
minidump_memory_info_list_directory.Location.DataSize =
|
||||
sizeof(minidump_memory_info_list) +
|
||||
minidump_memory_info_count * sizeof(MINIDUMP_MEMORY_INFO);
|
||||
minidump_memory_info_list_directory.Location.Rva =
|
||||
static_cast<RVA>(string_file.SeekGet());
|
||||
|
||||
EXPECT_TRUE(string_file.Write(&minidump_memory_info_list,
|
||||
sizeof(minidump_memory_info_list)));
|
||||
EXPECT_TRUE(string_file.Write(&minidump_memory_info_1,
|
||||
sizeof(minidump_memory_info_1)));
|
||||
EXPECT_TRUE(string_file.Write(&minidump_memory_info_2,
|
||||
sizeof(minidump_memory_info_2)));
|
||||
|
||||
header.StreamDirectoryRva = static_cast<RVA>(string_file.SeekGet());
|
||||
EXPECT_TRUE(string_file.Write(&minidump_memory_info_list_directory,
|
||||
sizeof(minidump_memory_info_list_directory)));
|
||||
|
||||
header.Signature = MINIDUMP_SIGNATURE;
|
||||
header.Version = MINIDUMP_VERSION;
|
||||
header.NumberOfStreams = 1;
|
||||
EXPECT_TRUE(string_file.SeekSet(0));
|
||||
EXPECT_TRUE(string_file.Write(&header, sizeof(header)));
|
||||
|
||||
ProcessSnapshotMinidump process_snapshot;
|
||||
EXPECT_TRUE(process_snapshot.Initialize(&string_file));
|
||||
|
||||
std::vector<const MemoryMapRegionSnapshot*> map =
|
||||
process_snapshot.MemoryMap();
|
||||
ASSERT_EQ(map.size(), minidump_memory_info_count);
|
||||
EXPECT_EQ(memcmp(&map[0]->AsMinidumpMemoryInfo(), &minidump_memory_info_1,
|
||||
sizeof(minidump_memory_info_1)), 0);
|
||||
EXPECT_EQ(memcmp(&map[1]->AsMinidumpMemoryInfo(), &minidump_memory_info_2,
|
||||
sizeof(minidump_memory_info_2)), 0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
|
Loading…
x
Reference in New Issue
Block a user