mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-26 23:01:05 +08:00
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:
parent
0a4ea0b52d
commit
765e428321
@ -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',
|
||||
|
@ -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);
|
||||
|
@ -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 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;
|
||||
@ -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.
|
||||
//!
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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 don’t 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 it’s 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
|
||||
|
@ -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',
|
||||
|
90
snapshot/test/test_module_snapshot.cc
Normal file
90
snapshot/test/test_module_snapshot.cc
Normal 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
|
110
snapshot/test/test_module_snapshot.h
Normal file
110
snapshot/test/test_module_snapshot.h
Normal 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_
|
Loading…
x
Reference in New Issue
Block a user