minidump: Add InitializeFromSnapshot() for

MinidumpModuleCrashpadInfoListWriter and everything downstream.

TEST=minidump_test
R=rsesek@chromium.org

Review URL: https://codereview.chromium.org/683143003
This commit is contained in:
Mark Mentovai 2014-10-28 17:00:46 -04:00
parent 0a4ea0b52d
commit 765e428321
10 changed files with 503 additions and 1 deletions

View File

@ -19,6 +19,7 @@
'type': 'static_library',
'dependencies': [
'../compat/compat.gyp:compat',
'../snapshot/snapshot.gyp:snapshot',
'../third_party/mini_chromium/mini_chromium/base/base.gyp:base',
'../util/util.gyp:util',
],
@ -69,6 +70,7 @@
'type': 'executable',
'dependencies': [
'minidump',
'../snapshot/snapshot.gyp:snapshot_test_lib',
'../third_party/gtest/gtest.gyp:gtest',
'../third_party/gtest/gtest.gyp:gtest_main',
'../third_party/mini_chromium/mini_chromium/base/base.gyp:base',

View File

@ -18,6 +18,7 @@
#include "base/logging.h"
#include "minidump/minidump_simple_string_dictionary_writer.h"
#include "snapshot/module_snapshot.h"
#include "util/file/file_writer.h"
#include "util/numeric/safe_assignment.h"
@ -31,6 +32,27 @@ MinidumpModuleCrashpadInfoWriter::MinidumpModuleCrashpadInfoWriter()
MinidumpModuleCrashpadInfoWriter::~MinidumpModuleCrashpadInfoWriter() {
}
void MinidumpModuleCrashpadInfoWriter::InitializeFromSnapshot(
const ModuleSnapshot* module_snapshot, size_t module_list_index) {
DCHECK_EQ(state(), kStateMutable);
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 simple_annotations =
make_scoped_ptr(new MinidumpSimpleStringDictionaryWriter());
simple_annotations->InitializeFromMap(
module_snapshot->AnnotationsSimpleMap());
if (simple_annotations->IsUseful()) {
SetSimpleAnnotations(simple_annotations.Pass());
}
}
void MinidumpModuleCrashpadInfoWriter::SetSimpleAnnotations(
scoped_ptr<MinidumpSimpleStringDictionaryWriter> simple_annotations) {
DCHECK_EQ(state(), kStateMutable);
@ -38,6 +60,10 @@ void MinidumpModuleCrashpadInfoWriter::SetSimpleAnnotations(
simple_annotations_ = simple_annotations.Pass();
}
bool MinidumpModuleCrashpadInfoWriter::IsUseful() const {
return simple_annotations_;
}
bool MinidumpModuleCrashpadInfoWriter::Freeze() {
DCHECK_EQ(state(), kStateMutable);
@ -88,6 +114,24 @@ MinidumpModuleCrashpadInfoListWriter::MinidumpModuleCrashpadInfoListWriter()
MinidumpModuleCrashpadInfoListWriter::~MinidumpModuleCrashpadInfoListWriter() {
}
void MinidumpModuleCrashpadInfoListWriter::InitializeFromSnapshot(
const std::vector<const ModuleSnapshot*>& module_snapshots) {
DCHECK_EQ(state(), kStateMutable);
DCHECK(modules_.empty());
DCHECK(module_location_descriptors_.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);
if (module->IsUseful()) {
AddModule(module.Pass());
}
}
}
void MinidumpModuleCrashpadInfoListWriter::AddModule(
scoped_ptr<MinidumpModuleCrashpadInfoWriter> module) {
DCHECK_EQ(state(), kStateMutable);

View File

@ -16,6 +16,7 @@
#define CRASHPAD_MINIDUMP_MINIDUMP_MODULE_CRASHPAD_INFO_WRITER_H_
#include <stdint.h>
#include <sys/types.h>
#include <vector>
@ -28,6 +29,7 @@
namespace crashpad {
class MinidumpSimpleStringDictionaryWriter;
class ModuleSnapshot;
//! \brief The writer for a MinidumpModuleCrashpadInfo object in a minidump
//! file.
@ -37,6 +39,24 @@ class MinidumpModuleCrashpadInfoWriter final
MinidumpModuleCrashpadInfoWriter();
~MinidumpModuleCrashpadInfoWriter() override;
//! \brief Initializes the MinidumpModuleCrashpadInfo based on \a
//! module_snapshot.
//!
//! Only data in \a module_snapshot that is considered useful will be
//! included. For simple annotations, usefulness is determined by
//! 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 files 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;
@ -53,6 +73,15 @@ class MinidumpModuleCrashpadInfoWriter final
void SetSimpleAnnotations(
scoped_ptr<MinidumpSimpleStringDictionaryWriter> simple_annotations);
//! \brief Determines whether the object is useful.
//!
//! A useful object is one that carries data that makes a meaningful
//! contribution to a minidump file. An object carrying simple annotations
//! would be considered useful.
//!
//! \return `true` if the object is useful, `false` otherwise.
bool IsUseful() const;
protected:
// MinidumpWritable:
bool Freeze() override;
@ -75,6 +104,21 @@ class MinidumpModuleCrashpadInfoListWriter final
MinidumpModuleCrashpadInfoListWriter();
~MinidumpModuleCrashpadInfoListWriter() override;
//! \brief Adds an initialized MinidumpModuleCrashpadInfo for modules in \a
//! module_snapshots to the MinidumpModuleCrashpadInfoList.
//!
//! Only modules in \a module_snapshots that would produce a useful
//! MinidumpModuleCrashpadInfo structure are included. Usefulness is
//! determined by MinidumpModuleCrashpadInfoWriter::IsUseful().
//!
//! \param[in] module_snapshots The module snapshots to use as source data.
//!
//! \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 std::vector<const ModuleSnapshot*>& module_snapshots);
//! \brief Adds a MinidumpModuleCrashpadInfo to the
//! MinidumpModuleCrashpadInfoList.
//!

View File

@ -22,6 +22,7 @@
#include "minidump/test/minidump_file_writer_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"
#include "util/file/string_file_writer.h"
namespace crashpad {
@ -61,6 +62,7 @@ TEST(MinidumpModuleCrashpadInfoWriter, EmptyModule) {
MinidumpModuleCrashpadInfoListWriter module_list_writer;
auto module_writer =
make_scoped_ptr(new MinidumpModuleCrashpadInfoWriter());
EXPECT_FALSE(module_writer->IsUseful());
module_list_writer.AddModule(module_writer.Pass());
EXPECT_TRUE(module_list_writer.WriteEverything(&file_writer));
@ -106,6 +108,7 @@ TEST(MinidumpModuleCrashpadInfoWriter, FullModule) {
simple_string_dictionary_writer->AddEntry(
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());
EXPECT_TRUE(module_list_writer.WriteEverything(&file_writer));
@ -175,11 +178,13 @@ TEST(MinidumpModuleCrashpadInfoWriter, ThreeModules) {
simple_string_dictionary_entry_writer_0.Pass());
module_writer_0->SetSimpleAnnotations(
simple_string_dictionary_writer_0.Pass());
EXPECT_TRUE(module_writer_0->IsUseful());
module_list_writer.AddModule(module_writer_0.Pass());
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());
auto module_writer_2 =
@ -199,6 +204,7 @@ TEST(MinidumpModuleCrashpadInfoWriter, ThreeModules) {
simple_string_dictionary_entry_writer_2b.Pass());
module_writer_2->SetSimpleAnnotations(
simple_string_dictionary_writer_2.Pass());
EXPECT_TRUE(module_writer_2->IsUseful());
module_list_writer.AddModule(module_writer_2.Pass());
EXPECT_TRUE(module_list_writer.WriteEverything(&file_writer));
@ -271,6 +277,95 @@ TEST(MinidumpModuleCrashpadInfoWriter, ThreeModules) {
file_writer.string(), simple_annotations_2->entries[1].value));
}
TEST(MinidumpModuleCrashpadInfoWriter, InitializeFromSnapshot) {
const char kKey0A[] = "k";
const char kValue0A[] = "value";
const char kKey0B[] = "hudson";
const char kValue0B[] = "estuary";
const char kKey2[] = "k";
const char kValue2[] = "different_value";
std::vector<const ModuleSnapshot*> module_snapshots;
TestModuleSnapshot module_snapshot_0;
std::map<std::string, std::string> annotations_simple_map_0;
annotations_simple_map_0[kKey0A] = kValue0A;
annotations_simple_map_0[kKey0B] = kValue0B;
module_snapshot_0.SetAnnotationsSimpleMap(annotations_simple_map_0);
module_snapshots.push_back(&module_snapshot_0);
// module_snapshot_1 is not expected to be written because it would not carry
// any MinidumpModuleCrashpadInfo data.
TestModuleSnapshot module_snapshot_1;
module_snapshots.push_back(&module_snapshot_1);
TestModuleSnapshot module_snapshot_2;
std::map<std::string, std::string> annotations_simple_map_2;
annotations_simple_map_2[kKey2] = kValue2;
module_snapshot_2.SetAnnotationsSimpleMap(annotations_simple_map_2);
module_snapshots.push_back(&module_snapshot_2);
MinidumpModuleCrashpadInfoListWriter module_list_writer;
module_list_writer.InitializeFromSnapshot(module_snapshots);
StringFileWriter file_writer;
ASSERT_TRUE(module_list_writer.WriteEverything(&file_writer));
const MinidumpModuleCrashpadInfoList* module_list =
MinidumpModuleCrashpadInfoListAtStart(file_writer.string(), 2);
ASSERT_TRUE(module_list);
ASSERT_EQ(2u, module_list->count);
const MinidumpModuleCrashpadInfo* module_0 =
MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfo>(
file_writer.string(), module_list->modules[0]);
ASSERT_TRUE(module_0);
EXPECT_EQ(MinidumpModuleCrashpadInfo::kVersion, module_0->version);
EXPECT_EQ(0u, module_0->minidump_module_list_index);
const MinidumpSimpleStringDictionary* simple_annotations_0 =
MinidumpWritableAtLocationDescriptor<MinidumpSimpleStringDictionary>(
file_writer.string(), module_0->simple_annotations);
ASSERT_TRUE(simple_annotations_0);
ASSERT_EQ(annotations_simple_map_0.size(), simple_annotations_0->count);
EXPECT_EQ(kKey0B,
MinidumpUTF8StringAtRVAAsString(
file_writer.string(), simple_annotations_0->entries[0].key));
EXPECT_EQ(kValue0B,
MinidumpUTF8StringAtRVAAsString(
file_writer.string(), simple_annotations_0->entries[0].value));
EXPECT_EQ(kKey0A,
MinidumpUTF8StringAtRVAAsString(
file_writer.string(), simple_annotations_0->entries[1].key));
EXPECT_EQ(kValue0A,
MinidumpUTF8StringAtRVAAsString(
file_writer.string(), simple_annotations_0->entries[1].value));
const MinidumpModuleCrashpadInfo* module_2 =
MinidumpWritableAtLocationDescriptor<MinidumpModuleCrashpadInfo>(
file_writer.string(), module_list->modules[1]);
ASSERT_TRUE(module_2);
EXPECT_EQ(MinidumpModuleCrashpadInfo::kVersion, module_2->version);
EXPECT_EQ(2u, module_2->minidump_module_list_index);
const MinidumpSimpleStringDictionary* simple_annotations_2 =
MinidumpWritableAtLocationDescriptor<MinidumpSimpleStringDictionary>(
file_writer.string(), module_2->simple_annotations);
ASSERT_TRUE(simple_annotations_2);
ASSERT_EQ(annotations_simple_map_2.size(), simple_annotations_2->count);
EXPECT_EQ(kKey2,
MinidumpUTF8StringAtRVAAsString(
file_writer.string(), simple_annotations_2->entries[0].key));
EXPECT_EQ(kValue2,
MinidumpUTF8StringAtRVAAsString(
file_writer.string(), simple_annotations_2->entries[0].value));
}
} // namespace
} // namespace test
} // namespace crashpad

View File

@ -41,6 +41,8 @@ MinidumpSimpleStringDictionaryEntryWriter::MinidumpSimpleStringDictionaryEntry()
void MinidumpSimpleStringDictionaryEntryWriter::SetKeyValue(
const std::string& key,
const std::string& value) {
DCHECK_EQ(state(), kStateMutable);
key_.SetUTF8(key);
value_.SetUTF8(value);
}
@ -96,9 +98,22 @@ MinidumpSimpleStringDictionaryWriter::~MinidumpSimpleStringDictionaryWriter() {
STLDeleteContainerPairSecondPointers(entries_.begin(), entries_.end());
}
void MinidumpSimpleStringDictionaryWriter::InitializeFromMap(
const std::map<std::string, std::string>& map) {
DCHECK_EQ(state(), kStateMutable);
DCHECK(entries_.empty());
for (const auto& iterator : map) {
auto entry =
make_scoped_ptr(new MinidumpSimpleStringDictionaryEntryWriter());
entry->SetKeyValue(iterator.first, iterator.second);
AddEntry(entry.Pass());
}
}
void MinidumpSimpleStringDictionaryWriter::AddEntry(
scoped_ptr<MinidumpSimpleStringDictionaryEntryWriter> entry) {
DCHECK_GE(state(), kStateMutable);
DCHECK_EQ(state(), kStateMutable);
const std::string& key = entry->Key();
auto iterator = entries_.find(key);
@ -110,6 +125,10 @@ void MinidumpSimpleStringDictionaryWriter::AddEntry(
}
}
bool MinidumpSimpleStringDictionaryWriter::IsUseful() const {
return !entries_.empty();
}
bool MinidumpSimpleStringDictionaryWriter::Freeze() {
DCHECK_EQ(state(), kStateMutable);

View File

@ -91,6 +91,16 @@ class MinidumpSimpleStringDictionaryWriter final
MinidumpSimpleStringDictionaryWriter();
~MinidumpSimpleStringDictionaryWriter() override;
//! \brief Adds an initialized MinidumpSimpleStringDictionaryEntryWriter for
//! each key-value pair in \a map to the MinidumpSimpleStringDictionary.
//!
//! \param[in] map The map to use as source data.
//!
//! \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 InitializeFromMap(const std::map<std::string, std::string>& map);
//! \brief Adds a MinidumpSimpleStringDictionaryEntryWriter to the
//! MinidumpSimpleStringDictionary.
//!
@ -104,6 +114,15 @@ class MinidumpSimpleStringDictionaryWriter final
//! \note Valid in #kStateMutable.
void AddEntry(scoped_ptr<MinidumpSimpleStringDictionaryEntryWriter> entry);
//! \brief Determines whether the object is useful.
//!
//! A useful object is one that carries data that makes a meaningful
//! contribution to a minidump file. An object carrying entries would be
//! considered useful.
//!
//! \return `true` if the object is useful, `false` otherwise.
bool IsUseful() const;
protected:
// MinidumpWritable:

View File

@ -14,6 +14,7 @@
#include "minidump/minidump_simple_string_dictionary_writer.h"
#include <map>
#include <string>
#include "gtest/gtest.h"
@ -43,6 +44,8 @@ TEST(MinidumpSimpleStringDictionaryWriter, EmptySimpleStringDictionary) {
MinidumpSimpleStringDictionaryWriter dictionary_writer;
EXPECT_FALSE(dictionary_writer.IsUseful());
EXPECT_TRUE(dictionary_writer.WriteEverything(&file_writer));
ASSERT_EQ(sizeof(MinidumpSimpleStringDictionary),
file_writer.string().size());
@ -61,6 +64,8 @@ TEST(MinidumpSimpleStringDictionaryWriter, EmptyKeyValue) {
make_scoped_ptr(new MinidumpSimpleStringDictionaryEntryWriter());
dictionary_writer.AddEntry(entry_writer.Pass());
EXPECT_TRUE(dictionary_writer.IsUseful());
EXPECT_TRUE(dictionary_writer.WriteEverything(&file_writer));
ASSERT_EQ(sizeof(MinidumpSimpleStringDictionary) +
sizeof(MinidumpSimpleStringDictionaryEntry) +
@ -93,6 +98,8 @@ TEST(MinidumpSimpleStringDictionaryWriter, OneKeyValue) {
entry_writer->SetKeyValue(kKey, kValue);
dictionary_writer.AddEntry(entry_writer.Pass());
EXPECT_TRUE(dictionary_writer.IsUseful());
EXPECT_TRUE(dictionary_writer.WriteEverything(&file_writer));
ASSERT_EQ(sizeof(MinidumpSimpleStringDictionary) +
sizeof(MinidumpSimpleStringDictionaryEntry) +
@ -137,6 +144,8 @@ TEST(MinidumpSimpleStringDictionaryWriter, ThreeKeysValues) {
entry_writer_2->SetKeyValue(kKey2, kValue2);
dictionary_writer.AddEntry(entry_writer_2.Pass());
EXPECT_TRUE(dictionary_writer.IsUseful());
EXPECT_TRUE(dictionary_writer.WriteEverything(&file_writer));
ASSERT_EQ(sizeof(MinidumpSimpleStringDictionary) +
3 * sizeof(MinidumpSimpleStringDictionaryEntry) +
@ -199,6 +208,8 @@ TEST(MinidumpSimpleStringDictionaryWriter, DuplicateKeyValue) {
entry_writer_1->SetKeyValue(kKey, kValue1);
dictionary_writer.AddEntry(entry_writer_1.Pass());
EXPECT_TRUE(dictionary_writer.IsUseful());
EXPECT_TRUE(dictionary_writer.WriteEverything(&file_writer));
ASSERT_EQ(sizeof(MinidumpSimpleStringDictionary) +
sizeof(MinidumpSimpleStringDictionaryEntry) +
@ -219,6 +230,58 @@ TEST(MinidumpSimpleStringDictionaryWriter, DuplicateKeyValue) {
dictionary->entries[0].value));
}
TEST(MinidumpSimpleStringDictionaryWriter, InitializeFromMap) {
char kKey0[] = "Dictionaries";
char kValue0[] = "USEFUL*";
char kKey1[] = "#1 Key!";
char kValue1[] = "";
char kKey2[] = "key two";
char kValue2[] = "value two";
std::map<std::string, std::string> map;
map[kKey0] = kValue0;
map[kKey1] = kValue1;
map[kKey2] = kValue2;
MinidumpSimpleStringDictionaryWriter dictionary_writer;
dictionary_writer.InitializeFromMap(map);
EXPECT_TRUE(dictionary_writer.IsUseful());
StringFileWriter file_writer;
ASSERT_TRUE(dictionary_writer.WriteEverything(&file_writer));
const MinidumpSimpleStringDictionary* dictionary =
MinidumpSimpleStringDictionaryAtStart(file_writer.string(), map.size());
ASSERT_TRUE(dictionary);
ASSERT_EQ(3u, dictionary->count);
// The entries dont appear in the order they were added. The current
// implementation uses a std::map and sorts keys, so the entires appear in
// alphabetical order. However, this is an implementation detail, and its OK
// if the writer stops sorting in this order. Testing for a specific order is
// just the easiest way to write this test while the writer will output things
// in a known order.
EXPECT_EQ(kKey1,
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
dictionary->entries[0].key));
EXPECT_EQ(kValue1,
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
dictionary->entries[0].value));
EXPECT_EQ(kKey0,
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
dictionary->entries[1].key));
EXPECT_EQ(kValue0,
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
dictionary->entries[1].value));
EXPECT_EQ(kKey2,
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
dictionary->entries[2].key));
EXPECT_EQ(kValue2,
MinidumpUTF8StringAtRVAAsString(file_writer.string(),
dictionary->entries[2].value));
}
} // namespace
} // namespace test
} // namespace crashpad

View File

@ -74,6 +74,22 @@
'thread_snapshot.h',
],
},
{
'target_name': 'snapshot_test_lib',
'type': 'static_library',
'dependencies': [
'snapshot',
'../third_party/mini_chromium/mini_chromium/base/base.gyp:base',
'../util/util.gyp:util',
],
'include_dirs': [
'..',
],
'sources': [
'test/test_module_snapshot.cc',
'test/test_module_snapshot.h',
],
},
{
'target_name': 'snapshot_test',
'type': 'executable',

View File

@ -0,0 +1,90 @@
// 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 "snapshot/test/test_module_snapshot.h"
namespace crashpad {
namespace test {
TestModuleSnapshot::TestModuleSnapshot()
: name_(),
address_(0),
size_(0),
timestamp_(0),
file_version_(),
source_version_(),
module_type_(kModuleTypeUnknown),
uuid_(),
annotations_vector_(),
annotations_simple_map_() {
}
TestModuleSnapshot::~TestModuleSnapshot() {
}
std::string TestModuleSnapshot::Name() const {
return name_;
}
uint64_t TestModuleSnapshot::Address() const {
return address_;
}
uint64_t TestModuleSnapshot::Size() const {
return size_;
}
time_t TestModuleSnapshot::Timestamp() const {
return timestamp_;
}
void TestModuleSnapshot::FileVersion(uint16_t* version_0,
uint16_t* version_1,
uint16_t* version_2,
uint16_t* version_3) const {
*version_0 = file_version_[0];
*version_1 = file_version_[1];
*version_2 = file_version_[2];
*version_3 = file_version_[3];
}
void TestModuleSnapshot::SourceVersion(uint16_t* version_0,
uint16_t* version_1,
uint16_t* version_2,
uint16_t* version_3) const {
*version_0 = source_version_[0];
*version_1 = source_version_[1];
*version_2 = source_version_[2];
*version_3 = source_version_[3];
}
ModuleSnapshot::ModuleType TestModuleSnapshot::GetModuleType() const {
return module_type_;
}
void TestModuleSnapshot::UUID(crashpad::UUID* uuid) const {
*uuid = uuid_;
}
std::vector<std::string> TestModuleSnapshot::AnnotationsVector() const {
return annotations_vector_;
}
std::map<std::string, std::string> TestModuleSnapshot::AnnotationsSimpleMap()
const {
return annotations_simple_map_;
}
} // namespace test
} // namespace crashpad

View File

@ -0,0 +1,110 @@
// 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_SNAPSHOT_TEST_TEST_MODULE_SNAPSHOT_H_
#define CRASHPAD_SNAPSHOT_TEST_TEST_MODULE_SNAPSHOT_H_
#include <stdint.h>
#include <sys/types.h>
#include <map>
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "snapshot/module_snapshot.h"
namespace crashpad {
namespace test {
//! \brief A test ModuleSnapshot that can carries arbitrary data for testing
//! purposes.
class TestModuleSnapshot final : public ModuleSnapshot {
public:
TestModuleSnapshot();
~TestModuleSnapshot();
void SetName(const std::string& name) { name_ = name; }
void SetAddressAndSize(uint64_t address, uint64_t size) {
address_ = address;
size_ = size;
}
void SetTimestamp(time_t timestamp) { timestamp_ = timestamp; }
void SetFileVersion(uint16_t file_version_0,
uint16_t file_version_1,
uint16_t file_version_2,
uint16_t file_version_3) {
file_version_[0] = file_version_0;
file_version_[1] = file_version_1;
file_version_[2] = file_version_2;
file_version_[3] = file_version_3;
}
void SetSourceVersion(uint16_t source_version_0,
uint16_t source_version_1,
uint16_t source_version_2,
uint16_t source_version_3) {
source_version_[0] = source_version_0;
source_version_[1] = source_version_1;
source_version_[2] = source_version_2;
source_version_[3] = source_version_3;
}
void SetModuleType(ModuleType module_type) { module_type_ = module_type; }
void SetUUID(const crashpad::UUID& uuid) { uuid_ = uuid; }
void SetAnnotationsVector(
const std::vector<std::string>& annotations_vector) {
annotations_vector_ = annotations_vector;
}
void SetAnnotationsSimpleMap(
const std::map<std::string, std::string>& annotations_simple_map) {
annotations_simple_map_ = annotations_simple_map;
}
// ModuleSnapshot:
std::string Name() const override;
uint64_t Address() const override;
uint64_t Size() const override;
time_t Timestamp() const override;
void FileVersion(uint16_t* version_0,
uint16_t* version_1,
uint16_t* version_2,
uint16_t* version_3) const override;
void SourceVersion(uint16_t* version_0,
uint16_t* version_1,
uint16_t* version_2,
uint16_t* version_3) const override;
ModuleType GetModuleType() const override;
void UUID(crashpad::UUID* uuid) const override;
std::vector<std::string> AnnotationsVector() const override;
std::map<std::string, std::string> AnnotationsSimpleMap() const override;
private:
std::string name_;
uint64_t address_;
uint64_t size_;
time_t timestamp_;
uint16_t file_version_[4];
uint16_t source_version_[4];
ModuleType module_type_;
crashpad::UUID uuid_;
std::vector<std::string> annotations_vector_;
std::map<std::string, std::string> annotations_simple_map_;
DISALLOW_COPY_AND_ASSIGN(TestModuleSnapshot);
};
} // namespace test
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_TEST_TEST_MODULE_SNAPSHOT_H_