From 765e42832140a7e75f6ed57c36034dbbec3785cd Mon Sep 17 00:00:00 2001 From: Mark Mentovai Date: Tue, 28 Oct 2014 17:00:46 -0400 Subject: [PATCH] minidump: Add InitializeFromSnapshot() for MinidumpModuleCrashpadInfoListWriter and everything downstream. TEST=minidump_test R=rsesek@chromium.org Review URL: https://codereview.chromium.org/683143003 --- minidump/minidump.gyp | 2 + .../minidump_module_crashpad_info_writer.cc | 44 +++++++ .../minidump_module_crashpad_info_writer.h | 44 +++++++ ...nidump_module_crashpad_info_writer_test.cc | 95 +++++++++++++++ ...inidump_simple_string_dictionary_writer.cc | 21 +++- ...minidump_simple_string_dictionary_writer.h | 19 +++ ...mp_simple_string_dictionary_writer_test.cc | 63 ++++++++++ snapshot/snapshot.gyp | 16 +++ snapshot/test/test_module_snapshot.cc | 90 ++++++++++++++ snapshot/test/test_module_snapshot.h | 110 ++++++++++++++++++ 10 files changed, 503 insertions(+), 1 deletion(-) create mode 100644 snapshot/test/test_module_snapshot.cc create mode 100644 snapshot/test/test_module_snapshot.h diff --git a/minidump/minidump.gyp b/minidump/minidump.gyp index f6bf10b7..38a04fc4 100644 --- a/minidump/minidump.gyp +++ b/minidump/minidump.gyp @@ -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', diff --git a/minidump/minidump_module_crashpad_info_writer.cc b/minidump/minidump_module_crashpad_info_writer.cc index a7afbda9..e1a2a231 100644 --- a/minidump/minidump_module_crashpad_info_writer.cc +++ b/minidump/minidump_module_crashpad_info_writer.cc @@ -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 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& 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 module) { DCHECK_EQ(state(), kStateMutable); diff --git a/minidump/minidump_module_crashpad_info_writer.h b/minidump/minidump_module_crashpad_info_writer.h index 12929170..e9bc2792 100644 --- a/minidump/minidump_module_crashpad_info_writer.h +++ b/minidump/minidump_module_crashpad_info_writer.h @@ -16,6 +16,7 @@ #define CRASHPAD_MINIDUMP_MINIDUMP_MODULE_CRASHPAD_INFO_WRITER_H_ #include +#include #include @@ -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 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& module_snapshots); + //! \brief Adds a MinidumpModuleCrashpadInfo to the //! MinidumpModuleCrashpadInfoList. //! diff --git a/minidump/minidump_module_crashpad_info_writer_test.cc b/minidump/minidump_module_crashpad_info_writer_test.cc index 712edfba..b354a73b 100644 --- a/minidump/minidump_module_crashpad_info_writer_test.cc +++ b/minidump/minidump_module_crashpad_info_writer_test.cc @@ -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 module_snapshots; + + TestModuleSnapshot module_snapshot_0; + std::map 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 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( + 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( + 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( + 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( + 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 diff --git a/minidump/minidump_simple_string_dictionary_writer.cc b/minidump/minidump_simple_string_dictionary_writer.cc index 9218bd97..63352e66 100644 --- a/minidump/minidump_simple_string_dictionary_writer.cc +++ b/minidump/minidump_simple_string_dictionary_writer.cc @@ -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& 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 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); diff --git a/minidump/minidump_simple_string_dictionary_writer.h b/minidump/minidump_simple_string_dictionary_writer.h index 17075fe1..d7a0b59d 100644 --- a/minidump/minidump_simple_string_dictionary_writer.h +++ b/minidump/minidump_simple_string_dictionary_writer.h @@ -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& map); + //! \brief Adds a MinidumpSimpleStringDictionaryEntryWriter to the //! MinidumpSimpleStringDictionary. //! @@ -104,6 +114,15 @@ class MinidumpSimpleStringDictionaryWriter final //! \note Valid in #kStateMutable. void AddEntry(scoped_ptr 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: diff --git a/minidump/minidump_simple_string_dictionary_writer_test.cc b/minidump/minidump_simple_string_dictionary_writer_test.cc index 62b1479f..ec79787c 100644 --- a/minidump/minidump_simple_string_dictionary_writer_test.cc +++ b/minidump/minidump_simple_string_dictionary_writer_test.cc @@ -14,6 +14,7 @@ #include "minidump/minidump_simple_string_dictionary_writer.h" +#include #include #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 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 diff --git a/snapshot/snapshot.gyp b/snapshot/snapshot.gyp index 3b1a8d62..9557ba91 100644 --- a/snapshot/snapshot.gyp +++ b/snapshot/snapshot.gyp @@ -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', diff --git a/snapshot/test/test_module_snapshot.cc b/snapshot/test/test_module_snapshot.cc new file mode 100644 index 00000000..497eb77a --- /dev/null +++ b/snapshot/test/test_module_snapshot.cc @@ -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 TestModuleSnapshot::AnnotationsVector() const { + return annotations_vector_; +} + +std::map TestModuleSnapshot::AnnotationsSimpleMap() + const { + return annotations_simple_map_; +} + +} // namespace test +} // namespace crashpad diff --git a/snapshot/test/test_module_snapshot.h b/snapshot/test/test_module_snapshot.h new file mode 100644 index 00000000..6248828f --- /dev/null +++ b/snapshot/test/test_module_snapshot.h @@ -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 +#include + +#include +#include +#include + +#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& annotations_vector) { + annotations_vector_ = annotations_vector; + } + void SetAnnotationsSimpleMap( + const std::map& 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 AnnotationsVector() const override; + std::map 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 annotations_vector_; + std::map annotations_simple_map_; + + DISALLOW_COPY_AND_ASSIGN(TestModuleSnapshot); +}; + +} // namespace test +} // namespace crashpad + +#endif // CRASHPAD_SNAPSHOT_TEST_TEST_MODULE_SNAPSHOT_H_