mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-27 15:32:10 +08:00
minidump: Reorganize MinidumpModuleCrashpadInfo to improve linking
between classic and extension structures. Previosly, each MinidumpModuleCrashpadInfo structure contained a minidump_module_list_index field referencing a module in the MINIDUMP_MODULE_LIST stream by index. This layout was discovered to cause a problem for the new minidump reader in ModuleSnapshotMinidump. Instead, the module list index for linkage should be contained in the MinidumpModuleCrashpadInfoList alongside the LOCATION_DESCRIPTORs pointing to each MinidumpModuleCrashpadInfo. The organizational difference is small, but this enables a better design for ModuleSnapshotMinidump. When initializing a ModuleSnapshotMinidump with the new layout, it is possible for the caller to have access to the location descriptor for the MinidumpModuleCrashpadInfo corresponding to a MINIDUMP_MODULE_LIST. Previously, the caller would not have had this data without interpreting each MinidumpModuleCrashpadInfo, which ModuleSnapshotMinidump would have to do anyway. MinidumpModuleCrashpadInfoListWriter was the only user of MinidumpLocationDescriptorListWriter, which is obsoleted and removed in this change. Its functionality is moving directly into MinidumpModuleCrashpadInfoListWriter, but it is no longer generic enough to maintain as a distinct class. TEST=minidump_test \ MinidumpModuleCrashpadInfoWriter.*,MinidumpCrashpadInfoWriter.* R=rsesek@chromium.org Review URL: https://codereview.chromium.org/978463003
This commit is contained in:
parent
84eb68bae6
commit
4539fd1553
@ -41,8 +41,6 @@
|
||||
'minidump_extensions.h',
|
||||
'minidump_file_writer.cc',
|
||||
'minidump_file_writer.h',
|
||||
'minidump_location_descriptor_list_writer.cc',
|
||||
'minidump_location_descriptor_list_writer.h',
|
||||
'minidump_memory_writer.cc',
|
||||
'minidump_memory_writer.h',
|
||||
'minidump_misc_info_writer.cc',
|
||||
@ -89,7 +87,6 @@
|
||||
'minidump_crashpad_info_writer_test.cc',
|
||||
'minidump_exception_writer_test.cc',
|
||||
'minidump_file_writer_test.cc',
|
||||
'minidump_location_descriptor_list_writer_test.cc',
|
||||
'minidump_memory_writer_test.cc',
|
||||
'minidump_misc_info_writer_test.cc',
|
||||
'minidump_module_crashpad_info_writer_test.cc',
|
||||
@ -105,8 +102,6 @@
|
||||
'test/minidump_context_test_util.h',
|
||||
'test/minidump_file_writer_test_util.cc',
|
||||
'test/minidump_file_writer_test_util.h',
|
||||
'test/minidump_location_descriptor_list_test_util.cc',
|
||||
'test/minidump_location_descriptor_list_test_util.h',
|
||||
'test/minidump_memory_writer_test_util.cc',
|
||||
'test/minidump_memory_writer_test_util.h',
|
||||
'test/minidump_rva_list_test_util.cc',
|
||||
|
@ -140,8 +140,7 @@ TEST(MinidumpCrashpadInfoWriter, CrashpadModuleList) {
|
||||
auto module_list_writer =
|
||||
make_scoped_ptr(new MinidumpModuleCrashpadInfoListWriter());
|
||||
auto module_writer = make_scoped_ptr(new MinidumpModuleCrashpadInfoWriter());
|
||||
module_writer->SetMinidumpModuleListIndex(kMinidumpModuleListIndex);
|
||||
module_list_writer->AddModule(module_writer.Pass());
|
||||
module_list_writer->AddModule(module_writer.Pass(), kMinidumpModuleListIndex);
|
||||
crashpad_info_writer->SetModuleList(module_list_writer.Pass());
|
||||
|
||||
EXPECT_TRUE(crashpad_info_writer->IsUseful());
|
||||
@ -164,13 +163,14 @@ TEST(MinidumpCrashpadInfoWriter, CrashpadModuleList) {
|
||||
ASSERT_TRUE(module_list);
|
||||
ASSERT_EQ(1u, module_list->count);
|
||||
|
||||
EXPECT_EQ(kMinidumpModuleListIndex,
|
||||
module_list->modules[0].minidump_module_list_index);
|
||||
const MinidumpModuleCrashpadInfo* module =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfo>(
|
||||
string_file.string(), module_list->children[0]);
|
||||
string_file.string(), module_list->modules[0].location);
|
||||
ASSERT_TRUE(module);
|
||||
|
||||
EXPECT_EQ(MinidumpModuleCrashpadInfo::kVersion, module->version);
|
||||
EXPECT_EQ(kMinidumpModuleListIndex, module->minidump_module_list_index);
|
||||
EXPECT_EQ(0u, module->list_annotations.DataSize);
|
||||
EXPECT_EQ(0u, module->list_annotations.Rva);
|
||||
EXPECT_EQ(0u, module->simple_annotations.DataSize);
|
||||
@ -235,13 +235,13 @@ TEST(MinidumpCrashpadInfoWriter, InitializeFromSnapshot) {
|
||||
ASSERT_TRUE(module_list);
|
||||
ASSERT_EQ(1u, module_list->count);
|
||||
|
||||
EXPECT_EQ(0u, module_list->modules[0].minidump_module_list_index);
|
||||
const MinidumpModuleCrashpadInfo* module =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfo>(
|
||||
string_file.string(), module_list->children[0]);
|
||||
string_file.string(), module_list->modules[0].location);
|
||||
ASSERT_TRUE(module);
|
||||
|
||||
EXPECT_EQ(MinidumpModuleCrashpadInfo::kVersion, module->version);
|
||||
EXPECT_EQ(0u, module->minidump_module_list_index);
|
||||
|
||||
const MinidumpRVAList* list_annotations =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpRVAList>(
|
||||
|
@ -322,15 +322,6 @@ struct ALIGNAS(4) PACKED MinidumpRVAList {
|
||||
RVA children[0];
|
||||
};
|
||||
|
||||
//! \brief A list of MINIDUMP_LOCATION_DESCRIPTOR objects.
|
||||
struct ALIGNAS(4) PACKED MinidumpLocationDescriptorList {
|
||||
//! \brief The number of children present in the #children array.
|
||||
uint32_t count;
|
||||
|
||||
//! \brief Pointers to other structures in the minidump file.
|
||||
MINIDUMP_LOCATION_DESCRIPTOR children[0];
|
||||
};
|
||||
|
||||
//! \brief A key-value pair.
|
||||
struct ALIGNAS(4) PACKED MinidumpSimpleStringDictionaryEntry {
|
||||
//! \brief ::RVA of a MinidumpUTF8String containing the key of a key-value
|
||||
@ -383,14 +374,6 @@ struct ALIGNAS(4) PACKED MinidumpModuleCrashpadInfo {
|
||||
//! no need for any fields present in later versions.
|
||||
uint32_t version;
|
||||
|
||||
//! \brief A link to a MINIDUMP_MODULE structure in the module list stream.
|
||||
//!
|
||||
//! This field is an index into MINIDUMP_MODULE_LIST::Modules. This field’s
|
||||
//! value must be in the range of MINIDUMP_MODULE_LIST::NumberOfEntries.
|
||||
//!
|
||||
//! This field is present when #version is at least `1`.
|
||||
uint32_t minidump_module_list_index;
|
||||
|
||||
//! \brief A MinidumpRVAList pointing to MinidumpUTF8String objects. The
|
||||
//! module controls the data that appears here.
|
||||
//!
|
||||
@ -411,6 +394,24 @@ struct ALIGNAS(4) PACKED MinidumpModuleCrashpadInfo {
|
||||
MINIDUMP_LOCATION_DESCRIPTOR simple_annotations;
|
||||
};
|
||||
|
||||
//! \brief A link between a MINIDUMP_MODULE structure and additional
|
||||
//! Crashpad-specific information about a module carried within a minidump
|
||||
//! file.
|
||||
struct ALIGNAS(4) PACKED MinidumpModuleCrashpadInfoLink {
|
||||
//! \brief A link to a MINIDUMP_MODULE structure in the module list stream.
|
||||
//!
|
||||
//! This field is an index into MINIDUMP_MODULE_LIST::Modules. This field’s
|
||||
//! value must be in the range of MINIDUMP_MODULE_LIST::NumberOfEntries.
|
||||
uint32_t minidump_module_list_index;
|
||||
|
||||
//! \brief A link to a MinidumpModuleCrashpadInfo structure.
|
||||
//!
|
||||
//! MinidumpModuleCrashpadInfo structures are accessed indirectly through
|
||||
//! MINIDUMP_LOCATION_DESCRIPTOR pointers to allow for future growth of the
|
||||
//! MinidumpModuleCrashpadInfo structure.
|
||||
MINIDUMP_LOCATION_DESCRIPTOR location;
|
||||
};
|
||||
|
||||
//! \brief Additional Crashpad-specific information about modules carried within
|
||||
//! a minidump file.
|
||||
//!
|
||||
@ -423,12 +424,15 @@ struct ALIGNAS(4) PACKED MinidumpModuleCrashpadInfo {
|
||||
//! structure carried within the minidump file will necessarily have
|
||||
//! Crashpad-specific information provided by a MinidumpModuleCrashpadInfo
|
||||
//! structure.
|
||||
//!
|
||||
//! MinidumpModuleCrashpadInfoList::children references
|
||||
//! MinidumpModuleCrashpadInfo children indirectly through
|
||||
//! MINIDUMP_LOCATION_DESCRIPTOR pointers to allow for future growth of the
|
||||
//! MinidumpModuleCrashpadInfo structure.
|
||||
using MinidumpModuleCrashpadInfoList = MinidumpLocationDescriptorList;
|
||||
struct ALIGNAS(4) PACKED MinidumpModuleCrashpadInfoList {
|
||||
//! \brief The number of children present in the #modules array.
|
||||
uint32_t count;
|
||||
|
||||
//! \brief Crashpad-specific information about modules, along with links to
|
||||
//! MINIDUMP_MODULE structures that contain module information
|
||||
//! traditionally carried within minidump files.
|
||||
MinidumpModuleCrashpadInfoLink modules[0];
|
||||
};
|
||||
|
||||
//! \brief Additional Crashpad-specific information carried within a minidump
|
||||
//! file.
|
||||
|
@ -1,105 +0,0 @@
|
||||
// Copyright 2014 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 "minidump/minidump_location_descriptor_list_writer.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "util/file/file_writer.h"
|
||||
#include "util/numeric/safe_assignment.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace internal {
|
||||
|
||||
MinidumpLocationDescriptorListWriter::MinidumpLocationDescriptorListWriter()
|
||||
: MinidumpWritable(),
|
||||
location_descriptor_list_base_(new MinidumpLocationDescriptorList()),
|
||||
children_(),
|
||||
child_location_descriptors_() {
|
||||
}
|
||||
|
||||
MinidumpLocationDescriptorListWriter::~MinidumpLocationDescriptorListWriter() {
|
||||
}
|
||||
|
||||
void MinidumpLocationDescriptorListWriter::AddChild(
|
||||
scoped_ptr<MinidumpWritable> child) {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
|
||||
children_.push_back(child.release());
|
||||
}
|
||||
|
||||
bool MinidumpLocationDescriptorListWriter::Freeze() {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
DCHECK(child_location_descriptors_.empty());
|
||||
|
||||
if (!MinidumpWritable::Freeze()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t child_count = children_.size();
|
||||
if (!AssignIfInRange(&location_descriptor_list_base_->count,
|
||||
child_count)) {
|
||||
LOG(ERROR) << "child_count " << child_count << " out of range";
|
||||
return false;
|
||||
}
|
||||
|
||||
child_location_descriptors_.resize(child_count);
|
||||
for (size_t index = 0; index < child_count; ++index) {
|
||||
children_[index]->RegisterLocationDescriptor(
|
||||
&child_location_descriptors_[index]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t MinidumpLocationDescriptorListWriter::SizeOfObject() {
|
||||
DCHECK_GE(state(), kStateFrozen);
|
||||
|
||||
return sizeof(*location_descriptor_list_base_) +
|
||||
children_.size() * sizeof(MINIDUMP_LOCATION_DESCRIPTOR);
|
||||
}
|
||||
|
||||
std::vector<MinidumpWritable*>
|
||||
MinidumpLocationDescriptorListWriter::Children() {
|
||||
DCHECK_GE(state(), kStateFrozen);
|
||||
|
||||
std::vector<MinidumpWritable*> children;
|
||||
for (MinidumpWritable* child : children_) {
|
||||
children.push_back(child);
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
bool MinidumpLocationDescriptorListWriter::WriteObject(
|
||||
FileWriterInterface* file_writer) {
|
||||
DCHECK_EQ(state(), kStateWritable);
|
||||
DCHECK_EQ(children_.size(), child_location_descriptors_.size());
|
||||
|
||||
WritableIoVec iov;
|
||||
iov.iov_base = location_descriptor_list_base_.get();
|
||||
iov.iov_len = sizeof(*location_descriptor_list_base_);
|
||||
std::vector<WritableIoVec> iovecs(1, iov);
|
||||
|
||||
if (!child_location_descriptors_.empty()) {
|
||||
iov.iov_base = &child_location_descriptors_[0];
|
||||
iov.iov_len = child_location_descriptors_.size() *
|
||||
sizeof(MINIDUMP_LOCATION_DESCRIPTOR);
|
||||
iovecs.push_back(iov);
|
||||
}
|
||||
|
||||
return file_writer->WriteIoVec(&iovecs);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace crashpad
|
@ -1,83 +0,0 @@
|
||||
// Copyright 2014 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_MINIDUMP_LOCATION_DESCRIPTOR_LIST_WRITER_H_
|
||||
#define CRASHPAD_MINIDUMP_LOCATION_DESCRIPTOR_LIST_WRITER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "minidump/minidump_extensions.h"
|
||||
#include "minidump/minidump_writable.h"
|
||||
#include "util/stdlib/pointer_container.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace internal {
|
||||
|
||||
//! \brief The writer for a MinidumpLocationDescriptorList object in a minidump
|
||||
//! file, containing a list of MINIDUMP_LOCATION_DESCRIPTOR objects.
|
||||
class MinidumpLocationDescriptorListWriter : public MinidumpWritable {
|
||||
protected:
|
||||
MinidumpLocationDescriptorListWriter();
|
||||
~MinidumpLocationDescriptorListWriter() override;
|
||||
|
||||
//! \brief Adds a MINIDUMP_LOCATION_DESCRIPTOR referencing a MinidumpWritable
|
||||
//! to the MinidumpLocationDescriptorList.
|
||||
//!
|
||||
//! This object takes ownership of \a child and becomes its parent in the
|
||||
//! overall tree of MinidumpWritable objects.
|
||||
//!
|
||||
//! To provide type-correctness, subclasses are expected to provide a public
|
||||
//! method that accepts a `scoped_ptr`-wrapped argument of the proper
|
||||
//! MinidumpWritable subclass, and call this method with that argument.
|
||||
//!
|
||||
//! \note Valid in #kStateMutable.
|
||||
void AddChild(scoped_ptr<MinidumpWritable> child);
|
||||
|
||||
//! \brief Returns `true` if no child objects have been added by AddChild(),
|
||||
//! and `false` if child objects are present.
|
||||
bool IsEmpty() const { return children_.empty(); }
|
||||
|
||||
//! \brief Returns an object’s MINIDUMP_LOCATION_DESCRIPTOR objects
|
||||
//! referencing its children.
|
||||
//!
|
||||
//! \note The returned vector will be empty until the object advances to
|
||||
//! #kStateFrozen or beyond.
|
||||
const std::vector<MINIDUMP_LOCATION_DESCRIPTOR>& child_location_descriptors()
|
||||
const {
|
||||
return child_location_descriptors_;
|
||||
}
|
||||
|
||||
// MinidumpWritable:
|
||||
bool Freeze() override;
|
||||
size_t SizeOfObject() override;
|
||||
std::vector<MinidumpWritable*> Children() override;
|
||||
bool WriteObject(FileWriterInterface* file_writer) override;
|
||||
|
||||
private:
|
||||
scoped_ptr<MinidumpLocationDescriptorList> location_descriptor_list_base_;
|
||||
PointerVector<MinidumpWritable> children_;
|
||||
std::vector<MINIDUMP_LOCATION_DESCRIPTOR> child_location_descriptors_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MinidumpLocationDescriptorListWriter);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_MINIDUMP_LOCATION_DESCRIPTOR_LIST_WRITER_H_
|
@ -1,110 +0,0 @@
|
||||
// Copyright 2014 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 "minidump/minidump_location_descriptor_list_writer.h"
|
||||
|
||||
#include "base/format_macros.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "minidump/test/minidump_location_descriptor_list_test_util.h"
|
||||
#include "minidump/test/minidump_writable_test_util.h"
|
||||
#include "util/file/string_file.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
namespace {
|
||||
|
||||
class TestMinidumpLocationDescriptorListWriter final
|
||||
: public internal::MinidumpLocationDescriptorListWriter {
|
||||
public:
|
||||
TestMinidumpLocationDescriptorListWriter()
|
||||
: MinidumpLocationDescriptorListWriter() {
|
||||
}
|
||||
|
||||
~TestMinidumpLocationDescriptorListWriter() override {}
|
||||
|
||||
void AddChild(uint32_t value) {
|
||||
auto child = make_scoped_ptr(new TestUInt32MinidumpWritable(value));
|
||||
MinidumpLocationDescriptorListWriter::AddChild(child.Pass());
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(TestMinidumpLocationDescriptorListWriter);
|
||||
};
|
||||
|
||||
TEST(MinidumpLocationDescriptorListWriter, Empty) {
|
||||
TestMinidumpLocationDescriptorListWriter list_writer;
|
||||
|
||||
StringFile string_file;
|
||||
|
||||
ASSERT_TRUE(list_writer.WriteEverything(&string_file));
|
||||
EXPECT_EQ(sizeof(MinidumpLocationDescriptorList),
|
||||
string_file.string().size());
|
||||
|
||||
const MinidumpLocationDescriptorList* list =
|
||||
MinidumpLocationDescriptorListAtStart(string_file.string(), 0);
|
||||
ASSERT_TRUE(list);
|
||||
}
|
||||
|
||||
TEST(MinidumpLocationDescriptorListWriter, OneChild) {
|
||||
TestMinidumpLocationDescriptorListWriter list_writer;
|
||||
|
||||
const uint32_t kValue = 0;
|
||||
list_writer.AddChild(kValue);
|
||||
|
||||
StringFile string_file;
|
||||
|
||||
ASSERT_TRUE(list_writer.WriteEverything(&string_file));
|
||||
|
||||
const MinidumpLocationDescriptorList* list =
|
||||
MinidumpLocationDescriptorListAtStart(string_file.string(), 1);
|
||||
ASSERT_TRUE(list);
|
||||
|
||||
const uint32_t* child = MinidumpWritableAtLocationDescriptor<uint32_t>(
|
||||
string_file.string(), list->children[0]);
|
||||
ASSERT_TRUE(child);
|
||||
EXPECT_EQ(kValue, *child);
|
||||
}
|
||||
|
||||
TEST(MinidumpLocationDescriptorListWriter, ThreeChildren) {
|
||||
TestMinidumpLocationDescriptorListWriter list_writer;
|
||||
|
||||
const uint32_t kValues[] = { 0x80000000, 0x55555555, 0x66006600 };
|
||||
|
||||
list_writer.AddChild(kValues[0]);
|
||||
list_writer.AddChild(kValues[1]);
|
||||
list_writer.AddChild(kValues[2]);
|
||||
|
||||
StringFile string_file;
|
||||
|
||||
ASSERT_TRUE(list_writer.WriteEverything(&string_file));
|
||||
|
||||
const MinidumpLocationDescriptorList* list =
|
||||
MinidumpLocationDescriptorListAtStart(string_file.string(),
|
||||
arraysize(kValues));
|
||||
ASSERT_TRUE(list);
|
||||
|
||||
for (size_t index = 0; index < arraysize(kValues); ++index) {
|
||||
SCOPED_TRACE(base::StringPrintf("index %" PRIuS, index));
|
||||
|
||||
const uint32_t* child = MinidumpWritableAtLocationDescriptor<uint32_t>(
|
||||
string_file.string(), list->children[index]);
|
||||
ASSERT_TRUE(child);
|
||||
EXPECT_EQ(kValues[index], *child);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
@ -36,18 +36,11 @@ MinidumpModuleCrashpadInfoWriter::~MinidumpModuleCrashpadInfoWriter() {
|
||||
}
|
||||
|
||||
void MinidumpModuleCrashpadInfoWriter::InitializeFromSnapshot(
|
||||
const ModuleSnapshot* module_snapshot, size_t module_list_index) {
|
||||
const ModuleSnapshot* module_snapshot) {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
DCHECK(!list_annotations_);
|
||||
DCHECK(!simple_annotations_);
|
||||
|
||||
uint32_t module_list_index_u32;
|
||||
if (!AssignIfInRange(&module_list_index_u32, module_list_index)) {
|
||||
LOG(ERROR) << "module_list_index " << module_list_index << " out of range";
|
||||
return;
|
||||
}
|
||||
SetMinidumpModuleListIndex(module_list_index_u32);
|
||||
|
||||
auto list_annotations = make_scoped_ptr(new MinidumpUTF8StringListWriter());
|
||||
list_annotations->InitializeFromVector(module_snapshot->AnnotationsVector());
|
||||
if (list_annotations->IsUseful()) {
|
||||
@ -129,7 +122,10 @@ bool MinidumpModuleCrashpadInfoWriter::WriteObject(
|
||||
}
|
||||
|
||||
MinidumpModuleCrashpadInfoListWriter::MinidumpModuleCrashpadInfoListWriter()
|
||||
: MinidumpLocationDescriptorListWriter() {
|
||||
: MinidumpWritable(),
|
||||
module_crashpad_infos_(),
|
||||
module_crashpad_info_links_(),
|
||||
module_crashpad_info_list_base_() {
|
||||
}
|
||||
|
||||
MinidumpModuleCrashpadInfoListWriter::~MinidumpModuleCrashpadInfoListWriter() {
|
||||
@ -138,30 +134,106 @@ MinidumpModuleCrashpadInfoListWriter::~MinidumpModuleCrashpadInfoListWriter() {
|
||||
void MinidumpModuleCrashpadInfoListWriter::InitializeFromSnapshot(
|
||||
const std::vector<const ModuleSnapshot*>& module_snapshots) {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
DCHECK(IsEmpty());
|
||||
DCHECK(child_location_descriptors().empty());
|
||||
DCHECK(module_crashpad_infos_.empty());
|
||||
DCHECK(module_crashpad_info_links_.empty());
|
||||
|
||||
size_t count = module_snapshots.size();
|
||||
for (size_t index = 0; index < count; ++index) {
|
||||
const ModuleSnapshot* module_snapshot = module_snapshots[index];
|
||||
|
||||
auto module = make_scoped_ptr(new MinidumpModuleCrashpadInfoWriter());
|
||||
module->InitializeFromSnapshot(module_snapshot, index);
|
||||
module->InitializeFromSnapshot(module_snapshot);
|
||||
if (module->IsUseful()) {
|
||||
AddModule(module.Pass());
|
||||
AddModule(module.Pass(), index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MinidumpModuleCrashpadInfoListWriter::AddModule(
|
||||
scoped_ptr<MinidumpModuleCrashpadInfoWriter> module) {
|
||||
scoped_ptr<MinidumpModuleCrashpadInfoWriter> module_crashpad_info,
|
||||
size_t minidump_module_list_index) {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
DCHECK_EQ(module_crashpad_infos_.size(), module_crashpad_info_links_.size());
|
||||
|
||||
AddChild(module.Pass());
|
||||
MinidumpModuleCrashpadInfoLink module_crashpad_info_link = {};
|
||||
if (!AssignIfInRange(&module_crashpad_info_link.minidump_module_list_index,
|
||||
minidump_module_list_index)) {
|
||||
LOG(ERROR) << "minidump_module_list_index " << minidump_module_list_index
|
||||
<< " out of range";
|
||||
return;
|
||||
}
|
||||
|
||||
module_crashpad_info_links_.push_back(module_crashpad_info_link);
|
||||
module_crashpad_infos_.push_back(module_crashpad_info.release());
|
||||
}
|
||||
|
||||
bool MinidumpModuleCrashpadInfoListWriter::IsUseful() const {
|
||||
return !IsEmpty();
|
||||
DCHECK_EQ(module_crashpad_infos_.size(), module_crashpad_info_links_.size());
|
||||
return !module_crashpad_infos_.empty();
|
||||
}
|
||||
|
||||
bool MinidumpModuleCrashpadInfoListWriter::Freeze() {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
CHECK_EQ(module_crashpad_infos_.size(), module_crashpad_info_links_.size());
|
||||
|
||||
if (!MinidumpWritable::Freeze()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t module_count = module_crashpad_infos_.size();
|
||||
if (!AssignIfInRange(&module_crashpad_info_list_base_.count, module_count)) {
|
||||
LOG(ERROR) << "module_count " << module_count << " out of range";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t index = 0; index < module_count; ++index) {
|
||||
module_crashpad_infos_[index]->RegisterLocationDescriptor(
|
||||
&module_crashpad_info_links_[index].location);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t MinidumpModuleCrashpadInfoListWriter::SizeOfObject() {
|
||||
DCHECK_GE(state(), kStateFrozen);
|
||||
DCHECK_EQ(module_crashpad_infos_.size(), module_crashpad_info_links_.size());
|
||||
|
||||
return sizeof(module_crashpad_info_list_base_) +
|
||||
module_crashpad_info_links_.size() *
|
||||
sizeof(module_crashpad_info_links_[0]);
|
||||
}
|
||||
|
||||
std::vector<internal::MinidumpWritable*>
|
||||
MinidumpModuleCrashpadInfoListWriter::Children() {
|
||||
DCHECK_GE(state(), kStateFrozen);
|
||||
DCHECK_EQ(module_crashpad_infos_.size(), module_crashpad_info_links_.size());
|
||||
|
||||
std::vector<MinidumpWritable*> children;
|
||||
for (MinidumpModuleCrashpadInfoWriter* module : module_crashpad_infos_) {
|
||||
children.push_back(module);
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
bool MinidumpModuleCrashpadInfoListWriter::WriteObject(
|
||||
FileWriterInterface* file_writer) {
|
||||
DCHECK_EQ(state(), kStateWritable);
|
||||
DCHECK_EQ(module_crashpad_infos_.size(), module_crashpad_info_links_.size());
|
||||
|
||||
WritableIoVec iov;
|
||||
iov.iov_base = &module_crashpad_info_list_base_;
|
||||
iov.iov_len = sizeof(module_crashpad_info_list_base_);
|
||||
std::vector<WritableIoVec> iovecs(1, iov);
|
||||
|
||||
if (!module_crashpad_info_links_.empty()) {
|
||||
iov.iov_base = &module_crashpad_info_links_[0];
|
||||
iov.iov_len = module_crashpad_info_links_.size() *
|
||||
sizeof(module_crashpad_info_links_[0]);
|
||||
iovecs.push_back(iov);
|
||||
}
|
||||
|
||||
return file_writer->WriteIoVec(&iovecs);
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "base/basictypes.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "minidump/minidump_extensions.h"
|
||||
#include "minidump/minidump_location_descriptor_list_writer.h"
|
||||
#include "minidump/minidump_string_writer.h"
|
||||
#include "minidump/minidump_writable.h"
|
||||
#include "util/stdlib/pointer_container.h"
|
||||
@ -48,20 +47,11 @@ class MinidumpModuleCrashpadInfoWriter final
|
||||
//! MinidumpSimpleStringDictionaryWriter::IsUseful().
|
||||
//!
|
||||
//! \param[in] module_snapshot The module snapshot to use as source data.
|
||||
//! \param[in] module_list_index The index of the MINIDUMP_MODULE initialized
|
||||
//! from \a module_snapshot in the minidump file’s MINIDUMP_MODULE_LIST
|
||||
//! stream.
|
||||
//!
|
||||
//! \note Valid in #kStateMutable. No mutator methods may be called before
|
||||
//! this method, and it is not normally necessary to call any mutator
|
||||
//! methods after this method.
|
||||
void InitializeFromSnapshot(const ModuleSnapshot* module_snapshot,
|
||||
size_t module_list_index);
|
||||
|
||||
//! \brief Sets MinidumpModuleCrashpadInfo::minidump_module_list_index.
|
||||
void SetMinidumpModuleListIndex(uint32_t minidump_module_list_index) {
|
||||
module_.minidump_module_list_index = minidump_module_list_index;
|
||||
}
|
||||
void InitializeFromSnapshot(const ModuleSnapshot* module_snapshot);
|
||||
|
||||
//! \brief Arranges for MinidumpModuleCrashpadInfo::list_annotations to point
|
||||
//! to the internal::MinidumpUTF8StringListWriter object to be written by
|
||||
@ -112,7 +102,7 @@ class MinidumpModuleCrashpadInfoWriter final
|
||||
//! \brief The writer for a MinidumpModuleCrashpadInfoList object in a minidump
|
||||
//! file, containing a list of MinidumpModuleCrashpadInfo objects.
|
||||
class MinidumpModuleCrashpadInfoListWriter final
|
||||
: public internal::MinidumpLocationDescriptorListWriter {
|
||||
: public internal::MinidumpWritable {
|
||||
public:
|
||||
MinidumpModuleCrashpadInfoListWriter();
|
||||
~MinidumpModuleCrashpadInfoListWriter() override;
|
||||
@ -135,11 +125,17 @@ class MinidumpModuleCrashpadInfoListWriter final
|
||||
//! \brief Adds a MinidumpModuleCrashpadInfo to the
|
||||
//! MinidumpModuleCrashpadInfoList.
|
||||
//!
|
||||
//! This object takes ownership of \a module and becomes its parent in the
|
||||
//! overall tree of internal::MinidumpWritable objects.
|
||||
//! \param[in] module Extended Crashpad-specific information about the module.
|
||||
//! This object takes ownership of \a module and becomes its parent in the
|
||||
//! overall tree of internal::MinidumpWritable objects.
|
||||
//! \param[in] module_list_index The index of the MINIDUMP_MODULE in the
|
||||
//! minidump file’s MINIDUMP_MODULE_LIST stream that corresponds to \a
|
||||
//! module_crashpad_info.
|
||||
//!
|
||||
//! \note Valid in #kStateMutable.
|
||||
void AddModule(scoped_ptr<MinidumpModuleCrashpadInfoWriter> module);
|
||||
void AddModule(
|
||||
scoped_ptr<MinidumpModuleCrashpadInfoWriter> module_crashpad_info,
|
||||
size_t minidump_module_list_index);
|
||||
|
||||
//! \brief Determines whether the object is useful.
|
||||
//!
|
||||
@ -150,7 +146,18 @@ class MinidumpModuleCrashpadInfoListWriter final
|
||||
//! \return `true` if the object is useful, `false` otherwise.
|
||||
bool IsUseful() const;
|
||||
|
||||
protected:
|
||||
// MinidumpWritable:
|
||||
bool Freeze() override;
|
||||
size_t SizeOfObject() override;
|
||||
std::vector<MinidumpWritable*> Children() override;
|
||||
bool WriteObject(FileWriterInterface* file_writer) override;
|
||||
|
||||
private:
|
||||
PointerVector<MinidumpModuleCrashpadInfoWriter> module_crashpad_infos_;
|
||||
std::vector<MinidumpModuleCrashpadInfoLink> module_crashpad_info_links_;
|
||||
MinidumpModuleCrashpadInfoList module_crashpad_info_list_base_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MinidumpModuleCrashpadInfoListWriter);
|
||||
};
|
||||
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "minidump/minidump_extensions.h"
|
||||
#include "minidump/minidump_simple_string_dictionary_writer.h"
|
||||
#include "minidump/test/minidump_file_writer_test_util.h"
|
||||
#include "minidump/test/minidump_location_descriptor_list_test_util.h"
|
||||
#include "minidump/test/minidump_string_writer_test_util.h"
|
||||
#include "minidump/test/minidump_writable_test_util.h"
|
||||
#include "snapshot/test/test_module_snapshot.h"
|
||||
@ -31,49 +30,73 @@ namespace crashpad {
|
||||
namespace test {
|
||||
namespace {
|
||||
|
||||
const MinidumpModuleCrashpadInfoList* MinidumpModuleCrashpadInfoListAtStart(
|
||||
const std::string& file_contents,
|
||||
size_t count) {
|
||||
MINIDUMP_LOCATION_DESCRIPTOR location_descriptor;
|
||||
location_descriptor.DataSize = sizeof(MinidumpModuleCrashpadInfoList) +
|
||||
count * sizeof(MinidumpModuleCrashpadInfoLink);
|
||||
location_descriptor.Rva = 0;
|
||||
|
||||
const MinidumpModuleCrashpadInfoList* list =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfoList>(
|
||||
file_contents, location_descriptor);
|
||||
if (!list) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (list->count != count) {
|
||||
EXPECT_EQ(count, list->count);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
TEST(MinidumpModuleCrashpadInfoWriter, EmptyList) {
|
||||
StringFile string_file;
|
||||
|
||||
MinidumpModuleCrashpadInfoListWriter module_list_writer;
|
||||
EXPECT_FALSE(module_list_writer.IsUseful());
|
||||
auto module_list_writer =
|
||||
make_scoped_ptr(new MinidumpModuleCrashpadInfoListWriter());
|
||||
EXPECT_FALSE(module_list_writer->IsUseful());
|
||||
|
||||
EXPECT_TRUE(module_list_writer.WriteEverything(&string_file));
|
||||
EXPECT_TRUE(module_list_writer->WriteEverything(&string_file));
|
||||
ASSERT_EQ(sizeof(MinidumpModuleCrashpadInfoList),
|
||||
string_file.string().size());
|
||||
|
||||
const MinidumpModuleCrashpadInfoList* module_list =
|
||||
MinidumpLocationDescriptorListAtStart(string_file.string(), 0);
|
||||
MinidumpModuleCrashpadInfoListAtStart(string_file.string(), 0);
|
||||
ASSERT_TRUE(module_list);
|
||||
}
|
||||
|
||||
TEST(MinidumpModuleCrashpadInfoWriter, EmptyModule) {
|
||||
StringFile string_file;
|
||||
|
||||
MinidumpModuleCrashpadInfoListWriter module_list_writer;
|
||||
auto module_writer =
|
||||
make_scoped_ptr(new MinidumpModuleCrashpadInfoWriter());
|
||||
auto module_list_writer =
|
||||
make_scoped_ptr(new MinidumpModuleCrashpadInfoListWriter());
|
||||
auto module_writer = make_scoped_ptr(new MinidumpModuleCrashpadInfoWriter());
|
||||
EXPECT_FALSE(module_writer->IsUseful());
|
||||
module_list_writer.AddModule(module_writer.Pass());
|
||||
module_list_writer->AddModule(module_writer.Pass(), 0);
|
||||
|
||||
EXPECT_TRUE(module_list_writer.IsUseful());
|
||||
EXPECT_TRUE(module_list_writer->IsUseful());
|
||||
|
||||
EXPECT_TRUE(module_list_writer.WriteEverything(&string_file));
|
||||
EXPECT_TRUE(module_list_writer->WriteEverything(&string_file));
|
||||
ASSERT_EQ(sizeof(MinidumpModuleCrashpadInfoList) +
|
||||
sizeof(MINIDUMP_LOCATION_DESCRIPTOR) +
|
||||
sizeof(MinidumpModuleCrashpadInfoLink) +
|
||||
sizeof(MinidumpModuleCrashpadInfo),
|
||||
string_file.string().size());
|
||||
|
||||
const MinidumpModuleCrashpadInfoList* module_list =
|
||||
MinidumpLocationDescriptorListAtStart(string_file.string(), 1);
|
||||
MinidumpModuleCrashpadInfoListAtStart(string_file.string(), 1);
|
||||
ASSERT_TRUE(module_list);
|
||||
|
||||
EXPECT_EQ(0u, module_list->modules[0].minidump_module_list_index);
|
||||
const MinidumpModuleCrashpadInfo* module =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfo>(
|
||||
string_file.string(), module_list->children[0]);
|
||||
string_file.string(), module_list->modules[0].location);
|
||||
ASSERT_TRUE(module);
|
||||
|
||||
EXPECT_EQ(MinidumpModuleCrashpadInfo::kVersion, module->version);
|
||||
EXPECT_EQ(0u, module->minidump_module_list_index);
|
||||
EXPECT_EQ(0u, module->list_annotations.DataSize);
|
||||
EXPECT_EQ(0u, module->list_annotations.Rva);
|
||||
EXPECT_EQ(0u, module->simple_annotations.DataSize);
|
||||
@ -89,11 +112,10 @@ TEST(MinidumpModuleCrashpadInfoWriter, FullModule) {
|
||||
|
||||
StringFile string_file;
|
||||
|
||||
MinidumpModuleCrashpadInfoListWriter module_list_writer;
|
||||
auto module_list_writer =
|
||||
make_scoped_ptr(new MinidumpModuleCrashpadInfoListWriter());
|
||||
|
||||
auto module_writer =
|
||||
make_scoped_ptr(new MinidumpModuleCrashpadInfoWriter());
|
||||
module_writer->SetMinidumpModuleListIndex(kMinidumpModuleListIndex);
|
||||
auto module_writer = make_scoped_ptr(new MinidumpModuleCrashpadInfoWriter());
|
||||
auto string_list_writer = make_scoped_ptr(new MinidumpUTF8StringListWriter());
|
||||
string_list_writer->InitializeFromVector(vector);
|
||||
module_writer->SetListAnnotations(string_list_writer.Pass());
|
||||
@ -106,13 +128,13 @@ TEST(MinidumpModuleCrashpadInfoWriter, FullModule) {
|
||||
simple_string_dictionary_entry_writer.Pass());
|
||||
module_writer->SetSimpleAnnotations(simple_string_dictionary_writer.Pass());
|
||||
EXPECT_TRUE(module_writer->IsUseful());
|
||||
module_list_writer.AddModule(module_writer.Pass());
|
||||
module_list_writer->AddModule(module_writer.Pass(), kMinidumpModuleListIndex);
|
||||
|
||||
EXPECT_TRUE(module_list_writer.IsUseful());
|
||||
EXPECT_TRUE(module_list_writer->IsUseful());
|
||||
|
||||
EXPECT_TRUE(module_list_writer.WriteEverything(&string_file));
|
||||
EXPECT_TRUE(module_list_writer->WriteEverything(&string_file));
|
||||
ASSERT_EQ(sizeof(MinidumpModuleCrashpadInfoList) +
|
||||
sizeof(MINIDUMP_LOCATION_DESCRIPTOR) +
|
||||
sizeof(MinidumpModuleCrashpadInfoLink) +
|
||||
sizeof(MinidumpModuleCrashpadInfo) +
|
||||
sizeof(MinidumpRVAList) +
|
||||
sizeof(RVA) +
|
||||
@ -124,16 +146,17 @@ TEST(MinidumpModuleCrashpadInfoWriter, FullModule) {
|
||||
string_file.string().size());
|
||||
|
||||
const MinidumpModuleCrashpadInfoList* module_list =
|
||||
MinidumpLocationDescriptorListAtStart(string_file.string(), 1);
|
||||
MinidumpModuleCrashpadInfoListAtStart(string_file.string(), 1);
|
||||
ASSERT_TRUE(module_list);
|
||||
|
||||
EXPECT_EQ(kMinidumpModuleListIndex,
|
||||
module_list->modules[0].minidump_module_list_index);
|
||||
const MinidumpModuleCrashpadInfo* module =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfo>(
|
||||
string_file.string(), module_list->children[0]);
|
||||
string_file.string(), module_list->modules[0].location);
|
||||
ASSERT_TRUE(module);
|
||||
|
||||
EXPECT_EQ(MinidumpModuleCrashpadInfo::kVersion, module->version);
|
||||
EXPECT_EQ(kMinidumpModuleListIndex, module->minidump_module_list_index);
|
||||
EXPECT_NE(0u, module->list_annotations.DataSize);
|
||||
EXPECT_NE(0u, module->list_annotations.Rva);
|
||||
EXPECT_NE(0u, module->simple_annotations.DataSize);
|
||||
@ -145,8 +168,9 @@ TEST(MinidumpModuleCrashpadInfoWriter, FullModule) {
|
||||
ASSERT_TRUE(list_annotations);
|
||||
|
||||
ASSERT_EQ(1u, list_annotations->count);
|
||||
EXPECT_EQ(kEntry, MinidumpUTF8StringAtRVAAsString(
|
||||
string_file.string(), list_annotations->children[0]));
|
||||
EXPECT_EQ(kEntry,
|
||||
MinidumpUTF8StringAtRVAAsString(string_file.string(),
|
||||
list_annotations->children[0]));
|
||||
|
||||
const MinidumpSimpleStringDictionary* simple_annotations =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpSimpleStringDictionary>(
|
||||
@ -175,11 +199,11 @@ TEST(MinidumpModuleCrashpadInfoWriter, ThreeModules) {
|
||||
|
||||
StringFile string_file;
|
||||
|
||||
MinidumpModuleCrashpadInfoListWriter module_list_writer;
|
||||
auto module_list_writer =
|
||||
make_scoped_ptr(new MinidumpModuleCrashpadInfoListWriter());
|
||||
|
||||
auto module_writer_0 =
|
||||
make_scoped_ptr(new MinidumpModuleCrashpadInfoWriter());
|
||||
module_writer_0->SetMinidumpModuleListIndex(kMinidumpModuleListIndex0);
|
||||
auto simple_string_dictionary_writer_0 =
|
||||
make_scoped_ptr(new MinidumpSimpleStringDictionaryWriter());
|
||||
auto simple_string_dictionary_entry_writer_0 =
|
||||
@ -190,17 +214,17 @@ TEST(MinidumpModuleCrashpadInfoWriter, ThreeModules) {
|
||||
module_writer_0->SetSimpleAnnotations(
|
||||
simple_string_dictionary_writer_0.Pass());
|
||||
EXPECT_TRUE(module_writer_0->IsUseful());
|
||||
module_list_writer.AddModule(module_writer_0.Pass());
|
||||
module_list_writer->AddModule(module_writer_0.Pass(),
|
||||
kMinidumpModuleListIndex0);
|
||||
|
||||
auto module_writer_1 =
|
||||
make_scoped_ptr(new MinidumpModuleCrashpadInfoWriter());
|
||||
module_writer_1->SetMinidumpModuleListIndex(kMinidumpModuleListIndex1);
|
||||
EXPECT_FALSE(module_writer_1->IsUseful());
|
||||
module_list_writer.AddModule(module_writer_1.Pass());
|
||||
module_list_writer->AddModule(module_writer_1.Pass(),
|
||||
kMinidumpModuleListIndex1);
|
||||
|
||||
auto module_writer_2 =
|
||||
make_scoped_ptr(new MinidumpModuleCrashpadInfoWriter());
|
||||
module_writer_2->SetMinidumpModuleListIndex(kMinidumpModuleListIndex2);
|
||||
auto simple_string_dictionary_writer_2 =
|
||||
make_scoped_ptr(new MinidumpSimpleStringDictionaryWriter());
|
||||
auto simple_string_dictionary_entry_writer_2a =
|
||||
@ -216,23 +240,25 @@ TEST(MinidumpModuleCrashpadInfoWriter, ThreeModules) {
|
||||
module_writer_2->SetSimpleAnnotations(
|
||||
simple_string_dictionary_writer_2.Pass());
|
||||
EXPECT_TRUE(module_writer_2->IsUseful());
|
||||
module_list_writer.AddModule(module_writer_2.Pass());
|
||||
module_list_writer->AddModule(module_writer_2.Pass(),
|
||||
kMinidumpModuleListIndex2);
|
||||
|
||||
EXPECT_TRUE(module_list_writer.IsUseful());
|
||||
EXPECT_TRUE(module_list_writer->IsUseful());
|
||||
|
||||
EXPECT_TRUE(module_list_writer.WriteEverything(&string_file));
|
||||
EXPECT_TRUE(module_list_writer->WriteEverything(&string_file));
|
||||
|
||||
const MinidumpModuleCrashpadInfoList* module_list =
|
||||
MinidumpLocationDescriptorListAtStart(string_file.string(), 3);
|
||||
MinidumpModuleCrashpadInfoListAtStart(string_file.string(), 3);
|
||||
ASSERT_TRUE(module_list);
|
||||
|
||||
EXPECT_EQ(kMinidumpModuleListIndex0,
|
||||
module_list->modules[0].minidump_module_list_index);
|
||||
const MinidumpModuleCrashpadInfo* module_0 =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfo>(
|
||||
string_file.string(), module_list->children[0]);
|
||||
string_file.string(), module_list->modules[0].location);
|
||||
ASSERT_TRUE(module_0);
|
||||
|
||||
EXPECT_EQ(MinidumpModuleCrashpadInfo::kVersion, module_0->version);
|
||||
EXPECT_EQ(kMinidumpModuleListIndex0, module_0->minidump_module_list_index);
|
||||
|
||||
const MinidumpRVAList* list_annotations_0 =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpRVAList>(
|
||||
@ -252,13 +278,14 @@ TEST(MinidumpModuleCrashpadInfoWriter, ThreeModules) {
|
||||
MinidumpUTF8StringAtRVAAsString(
|
||||
string_file.string(), simple_annotations_0->entries[0].value));
|
||||
|
||||
EXPECT_EQ(kMinidumpModuleListIndex1,
|
||||
module_list->modules[1].minidump_module_list_index);
|
||||
const MinidumpModuleCrashpadInfo* module_1 =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfo>(
|
||||
string_file.string(), module_list->children[1]);
|
||||
string_file.string(), module_list->modules[1].location);
|
||||
ASSERT_TRUE(module_1);
|
||||
|
||||
EXPECT_EQ(MinidumpModuleCrashpadInfo::kVersion, module_1->version);
|
||||
EXPECT_EQ(kMinidumpModuleListIndex1, module_1->minidump_module_list_index);
|
||||
|
||||
const MinidumpRVAList* list_annotations_1 =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpRVAList>(
|
||||
@ -270,13 +297,14 @@ TEST(MinidumpModuleCrashpadInfoWriter, ThreeModules) {
|
||||
string_file.string(), module_1->simple_annotations);
|
||||
EXPECT_FALSE(simple_annotations_1);
|
||||
|
||||
EXPECT_EQ(kMinidumpModuleListIndex2,
|
||||
module_list->modules[2].minidump_module_list_index);
|
||||
const MinidumpModuleCrashpadInfo* module_2 =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfo>(
|
||||
string_file.string(), module_list->children[2]);
|
||||
string_file.string(), module_list->modules[2].location);
|
||||
ASSERT_TRUE(module_2);
|
||||
|
||||
EXPECT_EQ(MinidumpModuleCrashpadInfo::kVersion, module_2->version);
|
||||
EXPECT_EQ(kMinidumpModuleListIndex2, module_2->minidump_module_list_index);
|
||||
|
||||
const MinidumpRVAList* list_annotations_2 =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpRVAList>(
|
||||
@ -340,24 +368,25 @@ TEST(MinidumpModuleCrashpadInfoWriter, InitializeFromSnapshot) {
|
||||
module_snapshot_3.SetAnnotationsVector(annotations_vector_3);
|
||||
module_snapshots.push_back(&module_snapshot_3);
|
||||
|
||||
MinidumpModuleCrashpadInfoListWriter module_list_writer;
|
||||
module_list_writer.InitializeFromSnapshot(module_snapshots);
|
||||
EXPECT_TRUE(module_list_writer.IsUseful());
|
||||
auto module_list_writer =
|
||||
make_scoped_ptr(new MinidumpModuleCrashpadInfoListWriter());
|
||||
module_list_writer->InitializeFromSnapshot(module_snapshots);
|
||||
EXPECT_TRUE(module_list_writer->IsUseful());
|
||||
|
||||
StringFile string_file;
|
||||
ASSERT_TRUE(module_list_writer.WriteEverything(&string_file));
|
||||
ASSERT_TRUE(module_list_writer->WriteEverything(&string_file));
|
||||
|
||||
const MinidumpModuleCrashpadInfoList* module_list =
|
||||
MinidumpLocationDescriptorListAtStart(string_file.string(), 3);
|
||||
MinidumpModuleCrashpadInfoListAtStart(string_file.string(), 3);
|
||||
ASSERT_TRUE(module_list);
|
||||
|
||||
EXPECT_EQ(0u, module_list->modules[0].minidump_module_list_index);
|
||||
const MinidumpModuleCrashpadInfo* module_0 =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfo>(
|
||||
string_file.string(), module_list->children[0]);
|
||||
string_file.string(), module_list->modules[0].location);
|
||||
ASSERT_TRUE(module_0);
|
||||
|
||||
EXPECT_EQ(MinidumpModuleCrashpadInfo::kVersion, module_0->version);
|
||||
EXPECT_EQ(0u, module_0->minidump_module_list_index);
|
||||
|
||||
const MinidumpRVAList* list_annotations_0 =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpRVAList>(
|
||||
@ -383,13 +412,13 @@ TEST(MinidumpModuleCrashpadInfoWriter, InitializeFromSnapshot) {
|
||||
MinidumpUTF8StringAtRVAAsString(
|
||||
string_file.string(), simple_annotations_0->entries[1].value));
|
||||
|
||||
EXPECT_EQ(2u, module_list->modules[1].minidump_module_list_index);
|
||||
const MinidumpModuleCrashpadInfo* module_2 =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfo>(
|
||||
string_file.string(), module_list->children[1]);
|
||||
string_file.string(), module_list->modules[1].location);
|
||||
ASSERT_TRUE(module_2);
|
||||
|
||||
EXPECT_EQ(MinidumpModuleCrashpadInfo::kVersion, module_2->version);
|
||||
EXPECT_EQ(2u, module_2->minidump_module_list_index);
|
||||
|
||||
const MinidumpRVAList* list_annotations_2 =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpRVAList>(
|
||||
@ -409,13 +438,13 @@ TEST(MinidumpModuleCrashpadInfoWriter, InitializeFromSnapshot) {
|
||||
MinidumpUTF8StringAtRVAAsString(
|
||||
string_file.string(), simple_annotations_2->entries[0].value));
|
||||
|
||||
EXPECT_EQ(3u, module_list->modules[2].minidump_module_list_index);
|
||||
const MinidumpModuleCrashpadInfo* module_3 =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfo>(
|
||||
string_file.string(), module_list->children[2]);
|
||||
string_file.string(), module_list->modules[2].location);
|
||||
ASSERT_TRUE(module_3);
|
||||
|
||||
EXPECT_EQ(MinidumpModuleCrashpadInfo::kVersion, module_3->version);
|
||||
EXPECT_EQ(3u, module_3->minidump_module_list_index);
|
||||
|
||||
const MinidumpRVAList* list_annotations_3 =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpRVAList>(
|
||||
@ -424,11 +453,11 @@ TEST(MinidumpModuleCrashpadInfoWriter, InitializeFromSnapshot) {
|
||||
|
||||
ASSERT_EQ(annotations_vector_3.size(), list_annotations_3->count);
|
||||
EXPECT_EQ(kEntry3A,
|
||||
MinidumpUTF8StringAtRVAAsString(
|
||||
string_file.string(), list_annotations_3->children[0]));
|
||||
MinidumpUTF8StringAtRVAAsString(string_file.string(),
|
||||
list_annotations_3->children[0]));
|
||||
EXPECT_EQ(kEntry3B,
|
||||
MinidumpUTF8StringAtRVAAsString(
|
||||
string_file.string(), list_annotations_3->children[1]));
|
||||
MinidumpUTF8StringAtRVAAsString(string_file.string(),
|
||||
list_annotations_3->children[1]));
|
||||
|
||||
const MinidumpSimpleStringDictionary* simple_annotations_3 =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpSimpleStringDictionary>(
|
||||
|
@ -1,49 +0,0 @@
|
||||
// Copyright 2014 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 "minidump/test/minidump_location_descriptor_list_test_util.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
#include "minidump/minidump_extensions.h"
|
||||
#include "minidump/test/minidump_writable_test_util.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
|
||||
const MinidumpLocationDescriptorList* MinidumpLocationDescriptorListAtStart(
|
||||
const std::string& file_contents, size_t count) {
|
||||
MINIDUMP_LOCATION_DESCRIPTOR location_descriptor;
|
||||
location_descriptor.DataSize = sizeof(MinidumpLocationDescriptorList) +
|
||||
count * sizeof(MINIDUMP_LOCATION_DESCRIPTOR);
|
||||
location_descriptor.Rva = 0;
|
||||
|
||||
const MinidumpLocationDescriptorList* list =
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpLocationDescriptorList>(
|
||||
file_contents, location_descriptor);
|
||||
if (!list) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (list->count != count) {
|
||||
EXPECT_EQ(count, list->count);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
@ -1,45 +0,0 @@
|
||||
// Copyright 2014 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_MINIDUMP_TEST_MINIDUMP_LOCATION_DESCRIPTOR_LIST_TEST_UTIL_H_
|
||||
#define CRASHPAD_MINIDUMP_TEST_MINIDUMP_LOCATION_DESCRIPTOR_LIST_TEST_UTIL_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
struct MinidumpLocationDescriptorList;
|
||||
|
||||
namespace test {
|
||||
|
||||
//! \brief Returns the MinidumpLocationDescriptorList at the start of a minidump
|
||||
//! file.
|
||||
//!
|
||||
//! \param[in] file_contents The contents of the minidump file.
|
||||
//! \param[in] count The number of MINIDUMP_LOCATION_DESCRIPTOR objects expected
|
||||
//! in the MinidumpLocationDescriptorList. This function will only be
|
||||
//! successful if exactly this many objects are present, and if space for
|
||||
//! them exists in \a file_contents.
|
||||
//!
|
||||
//! \return On success, the MinidumpLocationDescriptorList at the beginning of
|
||||
//! the file. On failure, raises a gtest assertion and returns `nullptr`.
|
||||
const MinidumpLocationDescriptorList* MinidumpLocationDescriptorListAtStart(
|
||||
const std::string& file_contents, size_t count);
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_MINIDUMP_TEST_MINIDUMP_LOCATION_DESCRIPTOR_LIST_TEST_UTIL_H_
|
@ -26,8 +26,7 @@ namespace test {
|
||||
const MinidumpRVAList* MinidumpRVAListAtStart(const std::string& file_contents,
|
||||
size_t count) {
|
||||
MINIDUMP_LOCATION_DESCRIPTOR location_descriptor;
|
||||
location_descriptor.DataSize =
|
||||
sizeof(MinidumpLocationDescriptorList) + count * sizeof(RVA);
|
||||
location_descriptor.DataSize = sizeof(MinidumpRVAList) + count * sizeof(RVA);
|
||||
location_descriptor.Rva = 0;
|
||||
|
||||
const MinidumpRVAList* list =
|
||||
|
@ -181,9 +181,9 @@ struct MinidumpThreadListTraits {
|
||||
}
|
||||
};
|
||||
|
||||
struct MinidumpLocationDescriptorListTraits {
|
||||
using ListType = MinidumpLocationDescriptorList;
|
||||
enum : size_t { kElementSize = sizeof(MINIDUMP_LOCATION_DESCRIPTOR) };
|
||||
struct MinidumpModuleCrashpadInfoListTraits {
|
||||
using ListType = MinidumpModuleCrashpadInfoList;
|
||||
enum : size_t { kElementSize = sizeof(MinidumpModuleCrashpadInfoLink) };
|
||||
static size_t ElementCount(const ListType* list) {
|
||||
return list->count;
|
||||
}
|
||||
@ -245,11 +245,11 @@ const MINIDUMP_THREAD_LIST* MinidumpWritableAtLocationDescriptor<
|
||||
}
|
||||
|
||||
template <>
|
||||
const MinidumpLocationDescriptorList*
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpLocationDescriptorList>(
|
||||
const MinidumpModuleCrashpadInfoList*
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfoList>(
|
||||
const std::string& file_contents,
|
||||
const MINIDUMP_LOCATION_DESCRIPTOR& location) {
|
||||
return MinidumpListAtLocationDescriptor<MinidumpLocationDescriptorListTraits>(
|
||||
return MinidumpListAtLocationDescriptor<MinidumpModuleCrashpadInfoListTraits>(
|
||||
file_contents, location);
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_DIRECTORY);
|
||||
MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_MEMORY_LIST);
|
||||
MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_MODULE_LIST);
|
||||
MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_THREAD_LIST);
|
||||
MINIDUMP_ALLOW_OVERSIZED_DATA(MinidumpLocationDescriptorList);
|
||||
MINIDUMP_ALLOW_OVERSIZED_DATA(MinidumpModuleCrashpadInfoList);
|
||||
MINIDUMP_ALLOW_OVERSIZED_DATA(MinidumpRVAList);
|
||||
MINIDUMP_ALLOW_OVERSIZED_DATA(MinidumpSimpleStringDictionary);
|
||||
|
||||
@ -189,12 +189,6 @@ const MINIDUMP_THREAD_LIST* MinidumpWritableAtLocationDescriptor<
|
||||
MINIDUMP_THREAD_LIST>(const std::string& file_contents,
|
||||
const MINIDUMP_LOCATION_DESCRIPTOR& location);
|
||||
|
||||
template <>
|
||||
const MinidumpLocationDescriptorList*
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpLocationDescriptorList>(
|
||||
const std::string& file_contents,
|
||||
const MINIDUMP_LOCATION_DESCRIPTOR& location);
|
||||
|
||||
template <>
|
||||
const MinidumpModuleCodeViewRecordPDB20*
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpModuleCodeViewRecordPDB20>(
|
||||
@ -207,6 +201,12 @@ MinidumpWritableAtLocationDescriptor<MinidumpModuleCodeViewRecordPDB70>(
|
||||
const std::string& file_contents,
|
||||
const MINIDUMP_LOCATION_DESCRIPTOR& location);
|
||||
|
||||
template <>
|
||||
const MinidumpModuleCrashpadInfoList*
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfoList>(
|
||||
const std::string& file_contents,
|
||||
const MINIDUMP_LOCATION_DESCRIPTOR& location);
|
||||
|
||||
template <>
|
||||
const MinidumpSimpleStringDictionary*
|
||||
MinidumpWritableAtLocationDescriptor<MinidumpSimpleStringDictionary>(
|
||||
|
Loading…
x
Reference in New Issue
Block a user