Mostly-boilerplate to add MemoryMapSnapshot

Follows https://codereview.chromium.org/1375313005.

Adds MINIDUMP_MEMORY_INFO for non-win in dbghelp.h.

R=mark@chromium.org
BUG=crashpad:20, crashpad:46

Review URL: https://codereview.chromium.org/1377133006 .
This commit is contained in:
Scott Graham 2015-10-13 12:37:44 -07:00
parent 4212d3e4ad
commit 937d3d710c
14 changed files with 216 additions and 0 deletions

View File

@ -836,6 +836,42 @@ struct __attribute__((packed, aligned(4))) MINIDUMP_MISC_INFO_4
//! \brief The latest known version of the MINIDUMP_MISC_INFO structure.
typedef MINIDUMP_MISC_INFO_4 MINIDUMP_MISC_INFO_N;
//! \brief Describes a region of memory.
struct __attribute__((packed, aligned(4))) MINIDUMP_MEMORY_INFO {
//! \brief The base address of the region of pages.
uint64_t BaseAddress;
//! \brief The base address of a range of pages in this region. The page is
//! contained within this memory region.
uint64_t AllocationBase;
//! \brief The memory protection when the region was initially allocated. This
//! member can be one of the memory protection options (such as
//! `PAGE_EXECUTE`, `PAGE_NOACCESS`, etc.), along with `PAGE_GUARD` or
//! `PAGE_NOCACHE`, as needed.
uint32_t AllocationProtect;
uint32_t __alignment1;
//! \brief The size of the region beginning at the base address in which all
//! pages have identical attributes, in bytes.
uint64_t RegionSize;
//! \brief The state of the pages in the region. This can be one of
//! `MEM_COMMIT`, `MEM_FREE`, or `MEM_RESERVE`.
uint32_t State;
//! \brief The access protection of the pages in the region. This member is
//! one of the values listed for the #AllocationProtect member.
uint32_t Protect;
//! \brief The type of pages in the region. This can be one of `MEM_IMAGE`,
//! `MEM_MAPPED`, or `MEM_PRIVATE`.
uint32_t Type;
uint32_t __alignment2;
};
//! \brief Minidump file type values for MINIDUMP_HEADER::Flags. These bits
//! describe the types of data carried within a minidump file.
enum MINIDUMP_TYPE {

View File

@ -186,6 +186,12 @@ const ExceptionSnapshot* ProcessSnapshotMac::Exception() const {
return exception_.get();
}
std::vector<const MemoryMapRegionSnapshot*> ProcessSnapshotMac::MemoryMap()
const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return std::vector<const MemoryMapRegionSnapshot*>();
}
std::vector<const MemorySnapshot*> ProcessSnapshotMac::ExtraMemory() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return std::vector<const MemorySnapshot*>();

View File

@ -33,6 +33,7 @@
#include "snapshot/mac/process_reader.h"
#include "snapshot/mac/system_snapshot_mac.h"
#include "snapshot/mac/thread_snapshot_mac.h"
#include "snapshot/memory_map_region_snapshot.h"
#include "snapshot/module_snapshot.h"
#include "snapshot/process_snapshot.h"
#include "snapshot/system_snapshot.h"
@ -126,6 +127,7 @@ class ProcessSnapshotMac final : public ProcessSnapshot {
std::vector<const ThreadSnapshot*> Threads() const override;
std::vector<const ModuleSnapshot*> Modules() const override;
const ExceptionSnapshot* Exception() const override;
std::vector<const MemoryMapRegionSnapshot*> MemoryMap() const override;
std::vector<const MemorySnapshot*> ExtraMemory() const override;
private:

View File

@ -0,0 +1,35 @@
// 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.
#ifndef CRASHPAD_SNAPSHOT_MEMORY_MAP_REGION_SNAPSHOT_H_
#define CRASHPAD_SNAPSHOT_MEMORY_MAP_REGION_SNAPSHOT_H_
#include <windows.h>
#include <dbghelp.h>
namespace crashpad {
//! \brief An abstract interface to a snapshot representing a region of the
//! memory map present in the snapshot process.
class MemoryMapRegionSnapshot {
public:
virtual ~MemoryMapRegionSnapshot() {}
//! \brief Gets a MINIDUMP_MEMORY_INFO representing the region.
virtual const MINIDUMP_MEMORY_INFO& AsMinidumpMemoryInfo() const = 0;
};
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_MEMORY_MAP_REGION_SNAPSHOT_H_

View File

@ -177,6 +177,13 @@ const ExceptionSnapshot* ProcessSnapshotMinidump::Exception() const {
return nullptr;
}
std::vector<const MemoryMapRegionSnapshot*> ProcessSnapshotMinidump::MemoryMap()
const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // https://code.google.com/p/crashpad/issues/detail?id=10
return std::vector<const MemoryMapRegionSnapshot*>();
}
std::vector<const MemorySnapshot*> ProcessSnapshotMinidump::ExtraMemory()
const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);

View File

@ -69,6 +69,7 @@ class ProcessSnapshotMinidump final : public ProcessSnapshot {
std::vector<const ThreadSnapshot*> Threads() const override;
std::vector<const ModuleSnapshot*> Modules() const override;
const ExceptionSnapshot* Exception() const override;
std::vector<const MemoryMapRegionSnapshot*> MemoryMap() const override;
std::vector<const MemorySnapshot*> ExtraMemory() const override;
private:

View File

@ -27,6 +27,7 @@
namespace crashpad {
class ExceptionSnapshot;
class MemoryMapRegionSnapshot;
class MemorySnapshot;
class ModuleSnapshot;
class SystemSnapshot;
@ -162,6 +163,14 @@ class ProcessSnapshot {
//! an exception, returns `nullptr`.
virtual const ExceptionSnapshot* Exception() const = 0;
//! \brief Returns MemoryMapRegionSnapshot objects reflecting the regions
//! of the memory map in the snapshot process at the time of the snapshot.
//!
//! \return A vector of MemoryMapRegionSnapshot objects. The caller does not
//! take ownership of these objects, they are scoped to the lifetime of
//! the ProcessSnapshot object that they were obtained from.
virtual std::vector<const MemoryMapRegionSnapshot*> MemoryMap() const = 0;
//! \brief Returns a vector of additional memory blocks that should be
//! included in a minidump.
//!

View File

@ -91,6 +91,8 @@
'win/cpu_context_win.h',
'win/exception_snapshot_win.cc',
'win/exception_snapshot_win.h',
'win/memory_map_region_snapshot_win.cc',
'win/memory_map_region_snapshot_win.h',
'win/memory_snapshot_win.cc',
'win/memory_snapshot_win.h',
'win/module_snapshot_win.cc',

View File

@ -33,6 +33,7 @@ TestProcessSnapshot::TestProcessSnapshot()
threads_(),
modules_(),
exception_(),
memory_map_(),
extra_memory_() {
}
@ -98,6 +99,14 @@ const ExceptionSnapshot* TestProcessSnapshot::Exception() const {
return exception_.get();
}
std::vector<const MemoryMapRegionSnapshot*> TestProcessSnapshot::MemoryMap()
const {
std::vector<const MemoryMapRegionSnapshot*> memory_map;
for (const auto& item : memory_map_)
memory_map.push_back(item);
return memory_map;
}
std::vector<const MemorySnapshot*> TestProcessSnapshot::ExtraMemory() const {
std::vector<const MemorySnapshot*> extra_memory;
for (const auto& em : extra_memory_)

View File

@ -26,6 +26,7 @@
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "snapshot/exception_snapshot.h"
#include "snapshot/memory_map_region_snapshot.h"
#include "snapshot/memory_snapshot.h"
#include "snapshot/module_snapshot.h"
#include "snapshot/process_snapshot.h"
@ -96,6 +97,15 @@ class TestProcessSnapshot final : public ProcessSnapshot {
exception_ = exception.Pass();
}
//! \brief Adds a memory map region snapshot to be returned by MemoryMap().
//!
//! \param[in] region The memory map region snapshot that will be included in
//! MemoryMap(). The TestProcessSnapshot object takes ownership of \a
//! region.
void AddMemoryMapRegion(scoped_ptr<MemoryMapRegionSnapshot> region) {
memory_map_.push_back(region.release());
}
//! \brief Add a memory snapshot to be returned by ExtraMemory().
//!
//! \param[in] extra_memory The memory snapshot that will be included in
@ -120,6 +130,7 @@ class TestProcessSnapshot final : public ProcessSnapshot {
std::vector<const ThreadSnapshot*> Threads() const override;
std::vector<const ModuleSnapshot*> Modules() const override;
const ExceptionSnapshot* Exception() const override;
std::vector<const MemoryMapRegionSnapshot*> MemoryMap() const override;
std::vector<const MemorySnapshot*> ExtraMemory() const override;
private:
@ -136,6 +147,7 @@ class TestProcessSnapshot final : public ProcessSnapshot {
PointerVector<ThreadSnapshot> threads_;
PointerVector<ModuleSnapshot> modules_;
scoped_ptr<ExceptionSnapshot> exception_;
PointerVector<MemoryMapRegionSnapshot> memory_map_;
PointerVector<MemorySnapshot> extra_memory_;
DISALLOW_COPY_AND_ASSIGN(TestProcessSnapshot);

View File

@ -0,0 +1,41 @@
// 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/win/memory_map_region_snapshot_win.h"
namespace crashpad {
namespace internal {
MemoryMapRegionSnapshotWin::MemoryMapRegionSnapshotWin(
const MEMORY_BASIC_INFORMATION64& mbi)
: memory_info_() {
memory_info_.BaseAddress = mbi.BaseAddress;
memory_info_.AllocationBase = mbi.AllocationBase;
memory_info_.AllocationProtect = mbi.AllocationProtect;
memory_info_.RegionSize = mbi.RegionSize;
memory_info_.State = mbi.State;
memory_info_.Protect = mbi.Protect;
memory_info_.Type = mbi.Type;
}
MemoryMapRegionSnapshotWin::~MemoryMapRegionSnapshotWin() {
}
const MINIDUMP_MEMORY_INFO& MemoryMapRegionSnapshotWin::AsMinidumpMemoryInfo()
const {
return memory_info_;
}
} // namespace internal
} // namespace crashpad

View File

@ -0,0 +1,37 @@
// 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.
#ifndef CRASHPAD_SNAPSHOT_WIN_MEMORY_MAP_REGION_SNAPSHOT_WIN_H_
#define CRASHPAD_SNAPSHOT_WIN_MEMORY_MAP_REGION_SNAPSHOT_WIN_H_
#include "snapshot/memory_map_region_snapshot.h"
namespace crashpad {
namespace internal {
class MemoryMapRegionSnapshotWin : public MemoryMapRegionSnapshot {
public:
explicit MemoryMapRegionSnapshotWin(const MEMORY_BASIC_INFORMATION64& mbi);
~MemoryMapRegionSnapshotWin() override;
virtual const MINIDUMP_MEMORY_INFO& AsMinidumpMemoryInfo() const override;
private:
MINIDUMP_MEMORY_INFO memory_info_;
};
} // namespace internal
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_WIN_MEMORY_MAP_REGION_SNAPSHOT_WIN_H_

View File

@ -18,6 +18,7 @@
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "snapshot/win/memory_snapshot_win.h"
#include "snapshot/win/module_snapshot_win.h"
#include "util/win/registration_protocol_win.h"
#include "util/win/time.h"
@ -30,6 +31,7 @@ ProcessSnapshotWin::ProcessSnapshotWin()
threads_(),
modules_(),
exception_(),
memory_map_(),
process_reader_(),
report_id_(),
client_id_(),
@ -60,6 +62,11 @@ bool ProcessSnapshotWin::Initialize(HANDLE process,
InitializeThreads();
InitializeModules();
for (const MEMORY_BASIC_INFORMATION64& mbi :
process_reader_.GetProcessInfo().MemoryInfo()) {
memory_map_.push_back(new internal::MemoryMapRegionSnapshotWin(mbi));
}
INITIALIZATION_STATE_SET_VALID(initialized_);
return true;
}
@ -187,6 +194,14 @@ const ExceptionSnapshot* ProcessSnapshotWin::Exception() const {
return exception_.get();
}
std::vector<const MemoryMapRegionSnapshot*> ProcessSnapshotWin::MemoryMap()
const {
std::vector<const MemoryMapRegionSnapshot*> memory_map;
for (const auto& item : memory_map_)
memory_map.push_back(item);
return memory_map;
}
std::vector<const MemorySnapshot*> ProcessSnapshotWin::ExtraMemory() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
std::vector<const MemorySnapshot*> extra_memory;

View File

@ -27,12 +27,14 @@
#include "client/crashpad_info.h"
#include "snapshot/crashpad_info_client_options.h"
#include "snapshot/exception_snapshot.h"
#include "snapshot/memory_map_region_snapshot.h"
#include "snapshot/memory_snapshot.h"
#include "snapshot/module_snapshot.h"
#include "snapshot/process_snapshot.h"
#include "snapshot/system_snapshot.h"
#include "snapshot/thread_snapshot.h"
#include "snapshot/win/exception_snapshot_win.h"
#include "snapshot/win/memory_map_region_snapshot_win.h"
#include "snapshot/win/memory_snapshot_win.h"
#include "snapshot/win/module_snapshot_win.h"
#include "snapshot/win/system_snapshot_win.h"
@ -126,6 +128,7 @@ class ProcessSnapshotWin final : public ProcessSnapshot {
std::vector<const ThreadSnapshot*> Threads() const override;
std::vector<const ModuleSnapshot*> Modules() const override;
const ExceptionSnapshot* Exception() const override;
std::vector<const MemoryMapRegionSnapshot*> MemoryMap() const override;
std::vector<const MemorySnapshot*> ExtraMemory() const override;
private:
@ -162,6 +165,7 @@ class ProcessSnapshotWin final : public ProcessSnapshot {
PointerVector<internal::ThreadSnapshotWin> threads_;
PointerVector<internal::ModuleSnapshotWin> modules_;
scoped_ptr<internal::ExceptionSnapshotWin> exception_;
PointerVector<internal::MemoryMapRegionSnapshotWin> memory_map_;
ProcessReaderWin process_reader_;
UUID report_id_;
UUID client_id_;