mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-19 09:53:47 +00:00
Have MinidumpMemoryListWriter deal directly in SnapshotMinidumpMemoryWriters
This is as a precursor to https://chromium-review.googlesource.com/374539 which merges MemorySnapshots and so needs to be able to update them from the minidump code. MinidumpMemoryWriter existed to be able to mock for tests; that behaviour is wrapped up in TestMemorySnapshot now. BUG=crashpad:61, chromium:638370 Change-Id: I825ec57493b12fc1848018585c14544faa7e66d4 Reviewed-on: https://chromium-review.googlesource.com/374019 Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
357c7c7b7b
commit
c6f88d164e
@ -24,32 +24,27 @@
|
|||||||
#include "util/numeric/safe_assignment.h"
|
#include "util/numeric/safe_assignment.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
namespace {
|
|
||||||
|
|
||||||
class SnapshotMinidumpMemoryWriter final : public MinidumpMemoryWriter,
|
SnapshotMinidumpMemoryWriter::SnapshotMinidumpMemoryWriter(
|
||||||
public MemorySnapshot::Delegate {
|
const MemorySnapshot* memory_snapshot)
|
||||||
public:
|
: internal::MinidumpWritable(),
|
||||||
explicit SnapshotMinidumpMemoryWriter(const MemorySnapshot* memory_snapshot)
|
|
||||||
: MinidumpMemoryWriter(),
|
|
||||||
MemorySnapshot::Delegate(),
|
MemorySnapshot::Delegate(),
|
||||||
|
memory_descriptor_(),
|
||||||
|
registered_memory_descriptors_(),
|
||||||
memory_snapshot_(memory_snapshot),
|
memory_snapshot_(memory_snapshot),
|
||||||
file_writer_(nullptr) {
|
file_writer_(nullptr) {}
|
||||||
}
|
|
||||||
|
|
||||||
~SnapshotMinidumpMemoryWriter() override {}
|
SnapshotMinidumpMemoryWriter::~SnapshotMinidumpMemoryWriter() {}
|
||||||
|
|
||||||
// MemorySnapshot::Delegate:
|
bool SnapshotMinidumpMemoryWriter::MemorySnapshotDelegateRead(void* data,
|
||||||
|
size_t size) {
|
||||||
bool MemorySnapshotDelegateRead(void* data, size_t size) override {
|
|
||||||
DCHECK_EQ(state(), kStateWritable);
|
DCHECK_EQ(state(), kStateWritable);
|
||||||
DCHECK_EQ(size, MemoryRangeSize());
|
DCHECK_EQ(size, UnderlyingSnapshot().Size());
|
||||||
return file_writer_->Write(data, size);
|
return file_writer_->Write(data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
bool SnapshotMinidumpMemoryWriter::WriteObject(
|
||||||
// MinidumpMemoryWriter:
|
FileWriterInterface* file_writer) {
|
||||||
|
|
||||||
bool WriteObject(FileWriterInterface* file_writer) override {
|
|
||||||
DCHECK_EQ(state(), kStateWritable);
|
DCHECK_EQ(state(), kStateWritable);
|
||||||
DCHECK(!file_writer_);
|
DCHECK(!file_writer_);
|
||||||
|
|
||||||
@ -60,41 +55,14 @@ class SnapshotMinidumpMemoryWriter final : public MinidumpMemoryWriter,
|
|||||||
return memory_snapshot_->Read(this);
|
return memory_snapshot_->Read(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t MemoryRangeBaseAddress() const override {
|
|
||||||
DCHECK_EQ(state(), kStateFrozen);
|
|
||||||
return memory_snapshot_->Address();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t MemoryRangeSize() const override {
|
|
||||||
DCHECK_GE(state(), kStateFrozen);
|
|
||||||
return memory_snapshot_->Size();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const MemorySnapshot* memory_snapshot_;
|
|
||||||
FileWriterInterface* file_writer_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(SnapshotMinidumpMemoryWriter);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
MinidumpMemoryWriter::~MinidumpMemoryWriter() {
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<MinidumpMemoryWriter> MinidumpMemoryWriter::CreateFromSnapshot(
|
|
||||||
const MemorySnapshot* memory_snapshot) {
|
|
||||||
return base::WrapUnique(new SnapshotMinidumpMemoryWriter(memory_snapshot));
|
|
||||||
}
|
|
||||||
|
|
||||||
const MINIDUMP_MEMORY_DESCRIPTOR*
|
const MINIDUMP_MEMORY_DESCRIPTOR*
|
||||||
MinidumpMemoryWriter::MinidumpMemoryDescriptor() const {
|
SnapshotMinidumpMemoryWriter::MinidumpMemoryDescriptor() const {
|
||||||
DCHECK_EQ(state(), kStateWritable);
|
DCHECK_EQ(state(), kStateWritable);
|
||||||
|
|
||||||
return &memory_descriptor_;
|
return &memory_descriptor_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MinidumpMemoryWriter::RegisterMemoryDescriptor(
|
void SnapshotMinidumpMemoryWriter::RegisterMemoryDescriptor(
|
||||||
MINIDUMP_MEMORY_DESCRIPTOR* memory_descriptor) {
|
MINIDUMP_MEMORY_DESCRIPTOR* memory_descriptor) {
|
||||||
DCHECK_LE(state(), kStateFrozen);
|
DCHECK_LE(state(), kStateFrozen);
|
||||||
|
|
||||||
@ -102,13 +70,7 @@ void MinidumpMemoryWriter::RegisterMemoryDescriptor(
|
|||||||
RegisterLocationDescriptor(&memory_descriptor->Memory);
|
RegisterLocationDescriptor(&memory_descriptor->Memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
MinidumpMemoryWriter::MinidumpMemoryWriter()
|
bool SnapshotMinidumpMemoryWriter::Freeze() {
|
||||||
: MinidumpWritable(),
|
|
||||||
memory_descriptor_(),
|
|
||||||
registered_memory_descriptors_() {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MinidumpMemoryWriter::Freeze() {
|
|
||||||
DCHECK_EQ(state(), kStateMutable);
|
DCHECK_EQ(state(), kStateMutable);
|
||||||
|
|
||||||
if (!MinidumpWritable::Freeze()) {
|
if (!MinidumpWritable::Freeze()) {
|
||||||
@ -120,26 +82,26 @@ bool MinidumpMemoryWriter::Freeze() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t MinidumpMemoryWriter::Alignment() {
|
size_t SnapshotMinidumpMemoryWriter::Alignment() {
|
||||||
DCHECK_GE(state(), kStateFrozen);
|
DCHECK_GE(state(), kStateFrozen);
|
||||||
|
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t MinidumpMemoryWriter::SizeOfObject() {
|
size_t SnapshotMinidumpMemoryWriter::SizeOfObject() {
|
||||||
DCHECK_GE(state(), kStateFrozen);
|
DCHECK_GE(state(), kStateFrozen);
|
||||||
|
|
||||||
return MemoryRangeSize();
|
return UnderlyingSnapshot().Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MinidumpMemoryWriter::WillWriteAtOffsetImpl(FileOffset offset) {
|
bool SnapshotMinidumpMemoryWriter::WillWriteAtOffsetImpl(FileOffset offset) {
|
||||||
DCHECK_EQ(state(), kStateFrozen);
|
DCHECK_EQ(state(), kStateFrozen);
|
||||||
|
|
||||||
// There will always be at least one registered descriptor, the one for this
|
// There will always be at least one registered descriptor, the one for this
|
||||||
// object’s own memory_descriptor_ field.
|
// object’s own memory_descriptor_ field.
|
||||||
DCHECK_GE(registered_memory_descriptors_.size(), 1u);
|
DCHECK_GE(registered_memory_descriptors_.size(), 1u);
|
||||||
|
|
||||||
uint64_t base_address = MemoryRangeBaseAddress();
|
uint64_t base_address = UnderlyingSnapshot().Address();
|
||||||
decltype(registered_memory_descriptors_[0]->StartOfMemoryRange) local_address;
|
decltype(registered_memory_descriptors_[0]->StartOfMemoryRange) local_address;
|
||||||
if (!AssignIfInRange(&local_address, base_address)) {
|
if (!AssignIfInRange(&local_address, base_address)) {
|
||||||
LOG(ERROR) << "base_address " << base_address << " out of range";
|
LOG(ERROR) << "base_address " << base_address << " out of range";
|
||||||
@ -154,7 +116,7 @@ bool MinidumpMemoryWriter::WillWriteAtOffsetImpl(FileOffset offset) {
|
|||||||
return MinidumpWritable::WillWriteAtOffsetImpl(offset);
|
return MinidumpWritable::WillWriteAtOffsetImpl(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal::MinidumpWritable::Phase MinidumpMemoryWriter::WritePhase() {
|
internal::MinidumpWritable::Phase SnapshotMinidumpMemoryWriter::WritePhase() {
|
||||||
// Memory dumps are large and are unlikely to be consumed in their entirety.
|
// Memory dumps are large and are unlikely to be consumed in their entirety.
|
||||||
// Data accesses are expected to be sparse and sporadic, and are expected to
|
// Data accesses are expected to be sparse and sporadic, and are expected to
|
||||||
// occur after all of the other structural and informational data from the
|
// occur after all of the other structural and informational data from the
|
||||||
@ -178,14 +140,14 @@ void MinidumpMemoryListWriter::AddFromSnapshot(
|
|||||||
DCHECK_EQ(state(), kStateMutable);
|
DCHECK_EQ(state(), kStateMutable);
|
||||||
|
|
||||||
for (const MemorySnapshot* memory_snapshot : memory_snapshots) {
|
for (const MemorySnapshot* memory_snapshot : memory_snapshots) {
|
||||||
std::unique_ptr<MinidumpMemoryWriter> memory =
|
std::unique_ptr<SnapshotMinidumpMemoryWriter> memory(
|
||||||
MinidumpMemoryWriter::CreateFromSnapshot(memory_snapshot);
|
new SnapshotMinidumpMemoryWriter(memory_snapshot));
|
||||||
AddMemory(std::move(memory));
|
AddMemory(std::move(memory));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MinidumpMemoryListWriter::AddMemory(
|
void MinidumpMemoryListWriter::AddMemory(
|
||||||
std::unique_ptr<MinidumpMemoryWriter> memory_writer) {
|
std::unique_ptr<SnapshotMinidumpMemoryWriter> memory_writer) {
|
||||||
DCHECK_EQ(state(), kStateMutable);
|
DCHECK_EQ(state(), kStateMutable);
|
||||||
|
|
||||||
AddExtraMemory(memory_writer.get());
|
AddExtraMemory(memory_writer.get());
|
||||||
@ -193,7 +155,7 @@ void MinidumpMemoryListWriter::AddMemory(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MinidumpMemoryListWriter::AddExtraMemory(
|
void MinidumpMemoryListWriter::AddExtraMemory(
|
||||||
MinidumpMemoryWriter* memory_writer) {
|
SnapshotMinidumpMemoryWriter* memory_writer) {
|
||||||
DCHECK_EQ(state(), kStateMutable);
|
DCHECK_EQ(state(), kStateMutable);
|
||||||
|
|
||||||
memory_writers_.push_back(memory_writer);
|
memory_writers_.push_back(memory_writer);
|
||||||
@ -232,7 +194,7 @@ std::vector<internal::MinidumpWritable*> MinidumpMemoryListWriter::Children() {
|
|||||||
DCHECK_LE(children_.size(), memory_writers_.size());
|
DCHECK_LE(children_.size(), memory_writers_.size());
|
||||||
|
|
||||||
std::vector<MinidumpWritable*> children;
|
std::vector<MinidumpWritable*> children;
|
||||||
for (MinidumpMemoryWriter* child : children_) {
|
for (SnapshotMinidumpMemoryWriter* child : children_) {
|
||||||
children.push_back(child);
|
children.push_back(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +209,7 @@ bool MinidumpMemoryListWriter::WriteObject(FileWriterInterface* file_writer) {
|
|||||||
iov.iov_len = sizeof(memory_list_base_);
|
iov.iov_len = sizeof(memory_list_base_);
|
||||||
std::vector<WritableIoVec> iovecs(1, iov);
|
std::vector<WritableIoVec> iovecs(1, iov);
|
||||||
|
|
||||||
for (const MinidumpMemoryWriter* memory_writer : memory_writers_) {
|
for (const SnapshotMinidumpMemoryWriter* memory_writer : memory_writers_) {
|
||||||
iov.iov_base = memory_writer->MinidumpMemoryDescriptor();
|
iov.iov_base = memory_writer->MinidumpMemoryDescriptor();
|
||||||
iov.iov_len = sizeof(MINIDUMP_MEMORY_DESCRIPTOR);
|
iov.iov_len = sizeof(MINIDUMP_MEMORY_DESCRIPTOR);
|
||||||
iovecs.push_back(iov);
|
iovecs.push_back(iov);
|
||||||
|
@ -26,34 +26,19 @@
|
|||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
#include "minidump/minidump_stream_writer.h"
|
#include "minidump/minidump_stream_writer.h"
|
||||||
#include "minidump/minidump_writable.h"
|
#include "minidump/minidump_writable.h"
|
||||||
|
#include "snapshot/memory_snapshot.h"
|
||||||
#include "util/file/file_io.h"
|
#include "util/file/file_io.h"
|
||||||
#include "util/stdlib/pointer_container.h"
|
#include "util/stdlib/pointer_container.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
|
|
||||||
class MemorySnapshot;
|
|
||||||
|
|
||||||
//! \brief The base class for writers of memory ranges pointed to by
|
//! \brief The base class for writers of memory ranges pointed to by
|
||||||
//! MINIDUMP_MEMORY_DESCRIPTOR objects in a minidump file.
|
//! MINIDUMP_MEMORY_DESCRIPTOR objects in a minidump file.
|
||||||
//!
|
class SnapshotMinidumpMemoryWriter : public internal::MinidumpWritable,
|
||||||
//! This is an abstract base class because users are expected to provide their
|
public MemorySnapshot::Delegate {
|
||||||
//! own implementations that, when possible, obtain the memory contents
|
|
||||||
//! on-demand in their WriteObject() methods. Memory ranges may be large, and
|
|
||||||
//! the alternative construction would require the contents of multiple ranges
|
|
||||||
//! to be held in memory simultaneously while a minidump file is being written.
|
|
||||||
class MinidumpMemoryWriter : public internal::MinidumpWritable {
|
|
||||||
public:
|
public:
|
||||||
~MinidumpMemoryWriter() override;
|
explicit SnapshotMinidumpMemoryWriter(const MemorySnapshot* memory_snapshot);
|
||||||
|
~SnapshotMinidumpMemoryWriter() override;
|
||||||
//! \brief Creates a concrete initialized MinidumpMemoryWriter based on \a
|
|
||||||
//! memory_snapshot.
|
|
||||||
//!
|
|
||||||
//! \param[in] memory_snapshot The memory snapshot to use as source data.
|
|
||||||
//!
|
|
||||||
//! \return An object of a MinidumpMemoryWriter subclass initialized using the
|
|
||||||
//! source data in \a memory_snapshot.
|
|
||||||
static std::unique_ptr<MinidumpMemoryWriter> CreateFromSnapshot(
|
|
||||||
const MemorySnapshot* memory_snapshot);
|
|
||||||
|
|
||||||
//! \brief Returns a MINIDUMP_MEMORY_DESCRIPTOR referencing the data that this
|
//! \brief Returns a MINIDUMP_MEMORY_DESCRIPTOR referencing the data that this
|
||||||
//! object writes.
|
//! object writes.
|
||||||
@ -76,24 +61,14 @@ class MinidumpMemoryWriter : public internal::MinidumpWritable {
|
|||||||
//! \note Valid in #kStateFrozen or any preceding state.
|
//! \note Valid in #kStateFrozen or any preceding state.
|
||||||
void RegisterMemoryDescriptor(MINIDUMP_MEMORY_DESCRIPTOR* memory_descriptor);
|
void RegisterMemoryDescriptor(MINIDUMP_MEMORY_DESCRIPTOR* memory_descriptor);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
MinidumpMemoryWriter();
|
// MemorySnapshot::Delegate:
|
||||||
|
bool MemorySnapshotDelegateRead(void* data, size_t size) override;
|
||||||
//! \brief Returns the base address of the memory region in the address space
|
|
||||||
//! of the process that the snapshot describes.
|
|
||||||
//!
|
|
||||||
//! \note This method will only be called in #kStateFrozen.
|
|
||||||
virtual uint64_t MemoryRangeBaseAddress() const = 0;
|
|
||||||
|
|
||||||
//! \brief Returns the size of the memory region in bytes.
|
|
||||||
//!
|
|
||||||
//! \note This method will only be called in #kStateFrozen or a subsequent
|
|
||||||
//! state.
|
|
||||||
virtual size_t MemoryRangeSize() const = 0;
|
|
||||||
|
|
||||||
// MinidumpWritable:
|
// MinidumpWritable:
|
||||||
bool Freeze() override;
|
bool Freeze() override;
|
||||||
size_t SizeOfObject() final;
|
size_t SizeOfObject() final;
|
||||||
|
bool WriteObject(FileWriterInterface* file_writer) override;
|
||||||
|
|
||||||
//! \brief Returns the object’s desired byte-boundary alignment.
|
//! \brief Returns the object’s desired byte-boundary alignment.
|
||||||
//!
|
//!
|
||||||
@ -119,13 +94,18 @@ class MinidumpMemoryWriter : public internal::MinidumpWritable {
|
|||||||
//! \note Valid in any state.
|
//! \note Valid in any state.
|
||||||
Phase WritePhase() final;
|
Phase WritePhase() final;
|
||||||
|
|
||||||
private:
|
//! \brief Gets the underlying memory snapshot that the memory writer will
|
||||||
|
//! write to the minidump.
|
||||||
|
const MemorySnapshot& UnderlyingSnapshot() const { return *memory_snapshot_; }
|
||||||
|
|
||||||
MINIDUMP_MEMORY_DESCRIPTOR memory_descriptor_;
|
MINIDUMP_MEMORY_DESCRIPTOR memory_descriptor_;
|
||||||
|
|
||||||
// weak
|
// weak
|
||||||
std::vector<MINIDUMP_MEMORY_DESCRIPTOR*> registered_memory_descriptors_;
|
std::vector<MINIDUMP_MEMORY_DESCRIPTOR*> registered_memory_descriptors_;
|
||||||
|
const MemorySnapshot* memory_snapshot_;
|
||||||
|
FileWriterInterface* file_writer_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(MinidumpMemoryWriter);
|
DISALLOW_COPY_AND_ASSIGN(SnapshotMinidumpMemoryWriter);
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief The writer for a MINIDUMP_MEMORY_LIST stream in a minidump file,
|
//! \brief The writer for a MINIDUMP_MEMORY_LIST stream in a minidump file,
|
||||||
@ -135,8 +115,8 @@ class MinidumpMemoryListWriter final : public internal::MinidumpStreamWriter {
|
|||||||
MinidumpMemoryListWriter();
|
MinidumpMemoryListWriter();
|
||||||
~MinidumpMemoryListWriter() override;
|
~MinidumpMemoryListWriter() override;
|
||||||
|
|
||||||
//! \brief Adds a concrete initialized MinidumpMemoryWriter for each memory
|
//! \brief Adds a concrete initialized SnapshotMinidumpMemoryWriter for each
|
||||||
//! snapshot in \a memory_snapshots to the MINIDUMP_MEMORY_LIST.
|
//! memory snapshot in \a memory_snapshots to the MINIDUMP_MEMORY_LIST.
|
||||||
//!
|
//!
|
||||||
//! Memory snapshots are added in the fashion of AddMemory().
|
//! Memory snapshots are added in the fashion of AddMemory().
|
||||||
//!
|
//!
|
||||||
@ -146,15 +126,15 @@ class MinidumpMemoryListWriter final : public internal::MinidumpStreamWriter {
|
|||||||
void AddFromSnapshot(
|
void AddFromSnapshot(
|
||||||
const std::vector<const MemorySnapshot*>& memory_snapshots);
|
const std::vector<const MemorySnapshot*>& memory_snapshots);
|
||||||
|
|
||||||
//! \brief Adds a MinidumpMemoryWriter to the MINIDUMP_MEMORY_LIST.
|
//! \brief Adds a SnapshotMinidumpMemoryWriter to the MINIDUMP_MEMORY_LIST.
|
||||||
//!
|
//!
|
||||||
//! This object takes ownership of \a memory_writer and becomes its parent in
|
//! This object takes ownership of \a memory_writer and becomes its parent in
|
||||||
//! the overall tree of internal::MinidumpWritable objects.
|
//! the overall tree of internal::MinidumpWritable objects.
|
||||||
//!
|
//!
|
||||||
//! \note Valid in #kStateMutable.
|
//! \note Valid in #kStateMutable.
|
||||||
void AddMemory(std::unique_ptr<MinidumpMemoryWriter> memory_writer);
|
void AddMemory(std::unique_ptr<SnapshotMinidumpMemoryWriter> memory_writer);
|
||||||
|
|
||||||
//! \brief Adds a MinidumpMemoryWriter that’s a child of another
|
//! \brief Adds a SnapshotMinidumpMemoryWriter that’s a child of another
|
||||||
//! internal::MinidumpWritable object to the MINIDUMP_MEMORY_LIST.
|
//! internal::MinidumpWritable object to the MINIDUMP_MEMORY_LIST.
|
||||||
//!
|
//!
|
||||||
//! \a memory_writer does not become a child of this object, but the
|
//! \a memory_writer does not become a child of this object, but the
|
||||||
@ -163,12 +143,12 @@ class MinidumpMemoryListWriter final : public internal::MinidumpStreamWriter {
|
|||||||
//! internal::MinidumpWritable tree.
|
//! internal::MinidumpWritable tree.
|
||||||
//!
|
//!
|
||||||
//! This method exists to be called by objects that have their own
|
//! This method exists to be called by objects that have their own
|
||||||
//! MinidumpMemoryWriter children but wish for them to also appear in the
|
//! SnapshotMinidumpMemoryWriter children but wish for them to also appear in
|
||||||
//! minidump file’s MINIDUMP_MEMORY_LIST. MinidumpThreadWriter, which has a
|
//! the minidump file’s MINIDUMP_MEMORY_LIST. MinidumpThreadWriter, which has
|
||||||
//! MinidumpMemoryWriter for thread stack memory, is an example.
|
//! a SnapshotMinidumpMemoryWriter for thread stack memory, is an example.
|
||||||
//!
|
//!
|
||||||
//! \note Valid in #kStateMutable.
|
//! \note Valid in #kStateMutable.
|
||||||
void AddExtraMemory(MinidumpMemoryWriter* memory_writer);
|
void AddExtraMemory(SnapshotMinidumpMemoryWriter* memory_writer);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// MinidumpWritable:
|
// MinidumpWritable:
|
||||||
@ -181,8 +161,8 @@ class MinidumpMemoryListWriter final : public internal::MinidumpStreamWriter {
|
|||||||
MinidumpStreamType StreamType() const override;
|
MinidumpStreamType StreamType() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<MinidumpMemoryWriter*> memory_writers_; // weak
|
std::vector<SnapshotMinidumpMemoryWriter*> memory_writers_; // weak
|
||||||
PointerVector<MinidumpMemoryWriter> children_;
|
PointerVector<SnapshotMinidumpMemoryWriter> children_;
|
||||||
MINIDUMP_MEMORY_LIST memory_list_base_;
|
MINIDUMP_MEMORY_LIST memory_list_base_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(MinidumpMemoryListWriter);
|
DISALLOW_COPY_AND_ASSIGN(MinidumpMemoryListWriter);
|
||||||
|
@ -51,8 +51,8 @@ void MinidumpThreadWriter::InitializeFromSnapshot(
|
|||||||
|
|
||||||
const MemorySnapshot* stack_snapshot = thread_snapshot->Stack();
|
const MemorySnapshot* stack_snapshot = thread_snapshot->Stack();
|
||||||
if (stack_snapshot && stack_snapshot->Size() > 0) {
|
if (stack_snapshot && stack_snapshot->Size() > 0) {
|
||||||
std::unique_ptr<MinidumpMemoryWriter> stack =
|
std::unique_ptr<SnapshotMinidumpMemoryWriter> stack(
|
||||||
MinidumpMemoryWriter::CreateFromSnapshot(stack_snapshot);
|
new SnapshotMinidumpMemoryWriter(stack_snapshot));
|
||||||
SetStack(std::move(stack));
|
SetStack(std::move(stack));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ const MINIDUMP_THREAD* MinidumpThreadWriter::MinidumpThread() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MinidumpThreadWriter::SetStack(
|
void MinidumpThreadWriter::SetStack(
|
||||||
std::unique_ptr<MinidumpMemoryWriter> stack) {
|
std::unique_ptr<SnapshotMinidumpMemoryWriter> stack) {
|
||||||
DCHECK_EQ(state(), kStateMutable);
|
DCHECK_EQ(state(), kStateMutable);
|
||||||
|
|
||||||
stack_ = std::move(stack);
|
stack_ = std::move(stack);
|
||||||
@ -172,7 +172,7 @@ void MinidumpThreadListWriter::AddThread(
|
|||||||
DCHECK_EQ(state(), kStateMutable);
|
DCHECK_EQ(state(), kStateMutable);
|
||||||
|
|
||||||
if (memory_list_writer_) {
|
if (memory_list_writer_) {
|
||||||
MinidumpMemoryWriter* stack = thread->Stack();
|
SnapshotMinidumpMemoryWriter* stack = thread->Stack();
|
||||||
if (stack) {
|
if (stack) {
|
||||||
memory_list_writer_->AddExtraMemory(stack);
|
memory_list_writer_->AddExtraMemory(stack);
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ namespace crashpad {
|
|||||||
|
|
||||||
class MinidumpContextWriter;
|
class MinidumpContextWriter;
|
||||||
class MinidumpMemoryListWriter;
|
class MinidumpMemoryListWriter;
|
||||||
class MinidumpMemoryWriter;
|
class SnapshotMinidumpMemoryWriter;
|
||||||
class ThreadSnapshot;
|
class ThreadSnapshot;
|
||||||
|
|
||||||
//! \brief The writer for a MINIDUMP_THREAD object in a minidump file.
|
//! \brief The writer for a MINIDUMP_THREAD object in a minidump file.
|
||||||
@ -67,8 +67,8 @@ class MinidumpThreadWriter final : public internal::MinidumpWritable {
|
|||||||
//! \note Valid in #kStateWritable.
|
//! \note Valid in #kStateWritable.
|
||||||
const MINIDUMP_THREAD* MinidumpThread() const;
|
const MINIDUMP_THREAD* MinidumpThread() const;
|
||||||
|
|
||||||
//! \brief Returns a MinidumpMemoryWriter that will write the memory region
|
//! \brief Returns a SnapshotMinidumpMemoryWriter that will write the memory
|
||||||
//! corresponding to this object’s stack.
|
//! region corresponding to this object’s stack.
|
||||||
//!
|
//!
|
||||||
//! If the thread does not have a stack, or its stack could not be determined,
|
//! If the thread does not have a stack, or its stack could not be determined,
|
||||||
//! this will return `nullptr`.
|
//! this will return `nullptr`.
|
||||||
@ -80,7 +80,7 @@ class MinidumpThreadWriter final : public internal::MinidumpWritable {
|
|||||||
//! MinidumpMemoryListWriter::AddExtraMemory().
|
//! MinidumpMemoryListWriter::AddExtraMemory().
|
||||||
//!
|
//!
|
||||||
//! \note Valid in any state.
|
//! \note Valid in any state.
|
||||||
MinidumpMemoryWriter* Stack() const { return stack_.get(); }
|
SnapshotMinidumpMemoryWriter* Stack() const { return stack_.get(); }
|
||||||
|
|
||||||
//! \brief Arranges for MINIDUMP_THREAD::Stack to point to the MINIDUMP_MEMORY
|
//! \brief Arranges for MINIDUMP_THREAD::Stack to point to the MINIDUMP_MEMORY
|
||||||
//! object to be written by \a stack.
|
//! object to be written by \a stack.
|
||||||
@ -89,7 +89,7 @@ class MinidumpThreadWriter final : public internal::MinidumpWritable {
|
|||||||
//! overall tree of internal::MinidumpWritable objects.
|
//! overall tree of internal::MinidumpWritable objects.
|
||||||
//!
|
//!
|
||||||
//! \note Valid in #kStateMutable.
|
//! \note Valid in #kStateMutable.
|
||||||
void SetStack(std::unique_ptr<MinidumpMemoryWriter> stack);
|
void SetStack(std::unique_ptr<SnapshotMinidumpMemoryWriter> stack);
|
||||||
|
|
||||||
//! \brief Arranges for MINIDUMP_THREAD::ThreadContext to point to the CPU
|
//! \brief Arranges for MINIDUMP_THREAD::ThreadContext to point to the CPU
|
||||||
//! context to be written by \a context.
|
//! context to be written by \a context.
|
||||||
@ -130,7 +130,7 @@ class MinidumpThreadWriter final : public internal::MinidumpWritable {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
MINIDUMP_THREAD thread_;
|
MINIDUMP_THREAD thread_;
|
||||||
std::unique_ptr<MinidumpMemoryWriter> stack_;
|
std::unique_ptr<SnapshotMinidumpMemoryWriter> stack_;
|
||||||
std::unique_ptr<MinidumpContextWriter> context_;
|
std::unique_ptr<MinidumpContextWriter> context_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(MinidumpThreadWriter);
|
DISALLOW_COPY_AND_ASSIGN(MinidumpThreadWriter);
|
||||||
@ -161,9 +161,9 @@ class MinidumpThreadListWriter final : public internal::MinidumpStreamWriter {
|
|||||||
//! region should be added to as extra memory.
|
//! region should be added to as extra memory.
|
||||||
//!
|
//!
|
||||||
//! Each MINIDUMP_THREAD object can contain a reference to a
|
//! Each MINIDUMP_THREAD object can contain a reference to a
|
||||||
//! MinidumpMemoryWriter object that contains a snapshot of its stack memory.
|
//! SnapshotMinidumpMemoryWriter object that contains a snapshot of its stac
|
||||||
//! In the overall tree of internal::MinidumpWritable objects, these
|
//! memory. In the overall tree of internal::MinidumpWritable objects, these
|
||||||
//! MinidumpMemoryWriter objects are considered children of their
|
//! SnapshotMinidumpMemoryWriter objects are considered children of their
|
||||||
//! MINIDUMP_THREAD, and are referenced by a MINIDUMP_MEMORY_DESCRIPTOR
|
//! MINIDUMP_THREAD, and are referenced by a MINIDUMP_MEMORY_DESCRIPTOR
|
||||||
//! contained in the MINIDUMP_THREAD. It is also possible for the same memory
|
//! contained in the MINIDUMP_THREAD. It is also possible for the same memory
|
||||||
//! regions to have MINIDUMP_MEMORY_DESCRIPTOR objects present in a
|
//! regions to have MINIDUMP_MEMORY_DESCRIPTOR objects present in a
|
||||||
|
@ -22,48 +22,15 @@ namespace test {
|
|||||||
TestMinidumpMemoryWriter::TestMinidumpMemoryWriter(uint64_t base_address,
|
TestMinidumpMemoryWriter::TestMinidumpMemoryWriter(uint64_t base_address,
|
||||||
size_t size,
|
size_t size,
|
||||||
uint8_t value)
|
uint8_t value)
|
||||||
: MinidumpMemoryWriter(),
|
: SnapshotMinidumpMemoryWriter(&test_snapshot_) {
|
||||||
base_address_(base_address),
|
test_snapshot_.SetAddress(base_address);
|
||||||
expected_offset_(-1),
|
test_snapshot_.SetSize(size);
|
||||||
size_(size),
|
test_snapshot_.SetValue(value);
|
||||||
value_(value) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TestMinidumpMemoryWriter::~TestMinidumpMemoryWriter() {
|
TestMinidumpMemoryWriter::~TestMinidumpMemoryWriter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t TestMinidumpMemoryWriter::MemoryRangeBaseAddress() const {
|
|
||||||
EXPECT_EQ(state(), kStateFrozen);
|
|
||||||
return base_address_;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t TestMinidumpMemoryWriter::MemoryRangeSize() const {
|
|
||||||
EXPECT_GE(state(), kStateFrozen);
|
|
||||||
return size_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TestMinidumpMemoryWriter::WillWriteAtOffsetImpl(FileOffset offset) {
|
|
||||||
EXPECT_EQ(state(), kStateFrozen);
|
|
||||||
expected_offset_ = offset;
|
|
||||||
bool rv = MinidumpMemoryWriter::WillWriteAtOffsetImpl(offset);
|
|
||||||
EXPECT_TRUE(rv);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TestMinidumpMemoryWriter::WriteObject(FileWriterInterface* file_writer) {
|
|
||||||
EXPECT_EQ(state(), kStateWritable);
|
|
||||||
EXPECT_EQ(expected_offset_, file_writer->Seek(0, SEEK_CUR));
|
|
||||||
|
|
||||||
bool rv = true;
|
|
||||||
if (size_ > 0) {
|
|
||||||
std::string data(size_, value_);
|
|
||||||
rv = file_writer->Write(&data[0], size_);
|
|
||||||
EXPECT_TRUE(rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExpectMinidumpMemoryDescriptor(
|
void ExpectMinidumpMemoryDescriptor(
|
||||||
const MINIDUMP_MEMORY_DESCRIPTOR* expected,
|
const MINIDUMP_MEMORY_DESCRIPTOR* expected,
|
||||||
const MINIDUMP_MEMORY_DESCRIPTOR* observed) {
|
const MINIDUMP_MEMORY_DESCRIPTOR* observed) {
|
||||||
|
@ -25,34 +25,23 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
|
#include "snapshot/test/test_memory_snapshot.h"
|
||||||
#include "util/file/file_writer.h"
|
#include "util/file/file_writer.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
namespace test {
|
namespace test {
|
||||||
|
|
||||||
//! \brief A MinidumpMemoryWriter implementation used for testing.
|
//! \brief A SnapshotMinidumpMemoryWriter implementation used for testing.
|
||||||
//!
|
//!
|
||||||
//! TestMinidumpMemoryWriter objects are created with a fixed base address and
|
//! TestMinidumpMemoryWriter objects are created with a fixed base address and
|
||||||
//! size, and will write the same byte (\a value) repeatedly, \a size times.
|
//! size, and will write the same byte (\a value) repeatedly, \a size times.
|
||||||
class TestMinidumpMemoryWriter final : public MinidumpMemoryWriter {
|
class TestMinidumpMemoryWriter final : public SnapshotMinidumpMemoryWriter {
|
||||||
public:
|
public:
|
||||||
TestMinidumpMemoryWriter(uint64_t base_address, size_t size, uint8_t value);
|
TestMinidumpMemoryWriter(uint64_t base_address, size_t size, uint8_t value);
|
||||||
~TestMinidumpMemoryWriter();
|
~TestMinidumpMemoryWriter();
|
||||||
|
|
||||||
protected:
|
|
||||||
// MinidumpMemoryWriter:
|
|
||||||
uint64_t MemoryRangeBaseAddress() const override;
|
|
||||||
size_t MemoryRangeSize() const override;
|
|
||||||
|
|
||||||
// MinidumpWritable:
|
|
||||||
bool WillWriteAtOffsetImpl(FileOffset offset) override;
|
|
||||||
bool WriteObject(FileWriterInterface* file_writer) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t base_address_;
|
TestMemorySnapshot test_snapshot_;
|
||||||
FileOffset expected_offset_;
|
|
||||||
size_t size_;
|
|
||||||
uint8_t value_;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(TestMinidumpMemoryWriter);
|
DISALLOW_COPY_AND_ASSIGN(TestMinidumpMemoryWriter);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user