From a96f5ace5b366dda97adebaa5feafe4661695d86 Mon Sep 17 00:00:00 2001 From: Scott Graham Date: Tue, 27 Oct 2015 13:06:58 -0700 Subject: [PATCH] Capture UUID age field on Windows R=mark@chromium.org BUG=chromium:546288 Review URL: https://codereview.chromium.org/1418613013 . --- minidump/minidump_module_writer.cc | 5 +++-- minidump/minidump_module_writer_test.cc | 14 ++++++++++---- snapshot/mac/module_snapshot_mac.cc | 5 +++-- snapshot/mac/module_snapshot_mac.h | 2 +- snapshot/minidump/module_snapshot_minidump.cc | 4 +++- snapshot/minidump/module_snapshot_minidump.h | 2 +- snapshot/module_snapshot.h | 9 +++++++-- snapshot/test/test_module_snapshot.cc | 4 +++- snapshot/test/test_module_snapshot.h | 8 ++++++-- snapshot/win/module_snapshot_win.cc | 13 +++++++++---- snapshot/win/module_snapshot_win.h | 2 +- 11 files changed, 47 insertions(+), 21 deletions(-) diff --git a/minidump/minidump_module_writer.cc b/minidump/minidump_module_writer.cc index 58d399d6..7e316ea2 100644 --- a/minidump/minidump_module_writer.cc +++ b/minidump/minidump_module_writer.cc @@ -117,8 +117,9 @@ void MinidumpModuleCodeViewRecordPDB70Writer::InitializeFromSnapshot( SetPDBName(leaf_name); UUID uuid; - module_snapshot->UUID(&uuid); - SetUUIDAndAge(uuid, 0); + uint32_t age; + module_snapshot->UUIDAndAge(&uuid, &age); + SetUUIDAndAge(uuid, age); } MinidumpModuleMiscDebugRecordWriter::MinidumpModuleMiscDebugRecordWriter() diff --git a/minidump/minidump_module_writer_test.cc b/minidump/minidump_module_writer_test.cc index fdd5b0ca..06d23123 100644 --- a/minidump/minidump_module_writer_test.cc +++ b/minidump/minidump_module_writer_test.cc @@ -614,7 +614,8 @@ void InitializeTestModuleSnapshotFromMinidumpModule( TestModuleSnapshot* module_snapshot, const MINIDUMP_MODULE& minidump_module, const std::string& name, - const crashpad::UUID& uuid) { + const crashpad::UUID& uuid, + uint32_t age) { module_snapshot->SetName(name); module_snapshot->SetAddressAndSize(minidump_module.BaseOfImage, @@ -645,7 +646,7 @@ void InitializeTestModuleSnapshotFromMinidumpModule( } module_snapshot->SetModuleType(module_type); - module_snapshot->SetUUID(uuid); + module_snapshot->SetUUIDAndAge(uuid, age); } TEST(MinidumpModuleWriter, InitializeFromSnapshot) { @@ -653,6 +654,7 @@ TEST(MinidumpModuleWriter, InitializeFromSnapshot) { const char* module_paths[arraysize(expect_modules)] = {}; const char* module_names[arraysize(expect_modules)] = {}; UUID uuids[arraysize(expect_modules)] = {}; + uint32_t ages[arraysize(expect_modules)] = {}; expect_modules[0].BaseOfImage = 0x100101000; expect_modules[0].SizeOfImage = 0xf000; @@ -668,6 +670,7 @@ TEST(MinidumpModuleWriter, InitializeFromSnapshot) { {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; uuids[0].InitializeFromBytes(kUUIDBytes0); + ages[0] = 10; expect_modules[1].BaseOfImage = 0x200202000; expect_modules[1].SizeOfImage = 0x1e1000; @@ -683,6 +686,7 @@ TEST(MinidumpModuleWriter, InitializeFromSnapshot) { {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; uuids[1].InitializeFromBytes(kUUIDBytes1); + ages[1] = 20; expect_modules[2].BaseOfImage = 0x300303000; expect_modules[2].SizeOfImage = 0x2d000; @@ -698,6 +702,7 @@ TEST(MinidumpModuleWriter, InitializeFromSnapshot) { {0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0}; uuids[2].InitializeFromBytes(kUUIDBytes2); + ages[2] = 30; PointerVector module_snapshots_owner; std::vector module_snapshots; @@ -707,7 +712,8 @@ TEST(MinidumpModuleWriter, InitializeFromSnapshot) { InitializeTestModuleSnapshotFromMinidumpModule(module_snapshot, expect_modules[index], module_paths[index], - uuids[index]); + uuids[index], + ages[index]); module_snapshots.push_back(module_snapshot); } @@ -735,7 +741,7 @@ TEST(MinidumpModuleWriter, InitializeFromSnapshot) { module_names[index], &uuids[index], 0, - 0, + ages[index], nullptr, 0, false)); diff --git a/snapshot/mac/module_snapshot_mac.cc b/snapshot/mac/module_snapshot_mac.cc index cc7e1863..7ddf217d 100644 --- a/snapshot/mac/module_snapshot_mac.cc +++ b/snapshot/mac/module_snapshot_mac.cc @@ -150,9 +150,10 @@ ModuleSnapshot::ModuleType ModuleSnapshotMac::GetModuleType() const { } } -void ModuleSnapshotMac::UUID(crashpad::UUID* uuid) const { +void ModuleSnapshotMac::UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - return mach_o_image_reader_->UUID(uuid); + mach_o_image_reader_->UUID(uuid); + *age = 0; } std::vector ModuleSnapshotMac::AnnotationsVector() const { diff --git a/snapshot/mac/module_snapshot_mac.h b/snapshot/mac/module_snapshot_mac.h index fc60e400..198eae96 100644 --- a/snapshot/mac/module_snapshot_mac.h +++ b/snapshot/mac/module_snapshot_mac.h @@ -75,7 +75,7 @@ class ModuleSnapshotMac final : public ModuleSnapshot { uint16_t* version_2, uint16_t* version_3) const override; ModuleType GetModuleType() const override; - void UUID(crashpad::UUID* uuid) const override; + void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const override; std::vector AnnotationsVector() const override; std::map AnnotationsSimpleMap() const override; diff --git a/snapshot/minidump/module_snapshot_minidump.cc b/snapshot/minidump/module_snapshot_minidump.cc index 12a340d5..18989f5f 100644 --- a/snapshot/minidump/module_snapshot_minidump.cc +++ b/snapshot/minidump/module_snapshot_minidump.cc @@ -110,10 +110,12 @@ ModuleSnapshot::ModuleType ModuleSnapshotMinidump::GetModuleType() const { return kModuleTypeUnknown; } -void ModuleSnapshotMinidump::UUID(crashpad::UUID* uuid) const { +void ModuleSnapshotMinidump::UUIDAndAge(crashpad::UUID* uuid, + uint32_t* age) const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); NOTREACHED(); // https://code.google.com/p/crashpad/issues/detail?id=10 *uuid = crashpad::UUID(); + *age = 0; } std::vector ModuleSnapshotMinidump::AnnotationsVector() const { diff --git a/snapshot/minidump/module_snapshot_minidump.h b/snapshot/minidump/module_snapshot_minidump.h index b04d498a..c845c39b 100644 --- a/snapshot/minidump/module_snapshot_minidump.h +++ b/snapshot/minidump/module_snapshot_minidump.h @@ -72,7 +72,7 @@ class ModuleSnapshotMinidump final : public ModuleSnapshot { uint16_t* version_2, uint16_t* version_3) const override; ModuleType GetModuleType() const override; - void UUID(crashpad::UUID* uuid) const override; + void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const override; std::vector AnnotationsVector() const override; std::map AnnotationsSimpleMap() const override; diff --git a/snapshot/module_snapshot.h b/snapshot/module_snapshot.h index d8f1ae6b..6c397ed0 100644 --- a/snapshot/module_snapshot.h +++ b/snapshot/module_snapshot.h @@ -109,11 +109,16 @@ class ModuleSnapshot { //! \brief Returns the module’s type. virtual ModuleType GetModuleType() const = 0; - //! \brief Returns the module’s UUID in the \a uuid parameter. + //! \brief Returns the module’s UUID in the \a uuid parameter, and the age of + //! that UUID in \a age. //! //! A snapshot module’s UUID is taken directly from the module itself. If the //! module does not have a UUID, the \a uuid parameter will be zeroed out. - virtual void UUID(crashpad::UUID* uuid) const = 0; + //! + //! \a age is the number of times the UUID has been reused. This occurs on + //! Windows with incremental linking. On other platforms \a age will always be + //! `0`. + virtual void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const = 0; //! \brief Returns string annotations recorded in the module. //! diff --git a/snapshot/test/test_module_snapshot.cc b/snapshot/test/test_module_snapshot.cc index 497eb77a..fc6a4277 100644 --- a/snapshot/test/test_module_snapshot.cc +++ b/snapshot/test/test_module_snapshot.cc @@ -25,6 +25,7 @@ TestModuleSnapshot::TestModuleSnapshot() file_version_(), source_version_(), module_type_(kModuleTypeUnknown), + age_(0), uuid_(), annotations_vector_(), annotations_simple_map_() { @@ -73,8 +74,9 @@ ModuleSnapshot::ModuleType TestModuleSnapshot::GetModuleType() const { return module_type_; } -void TestModuleSnapshot::UUID(crashpad::UUID* uuid) const { +void TestModuleSnapshot::UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const { *uuid = uuid_; + *age = age_; } std::vector TestModuleSnapshot::AnnotationsVector() const { diff --git a/snapshot/test/test_module_snapshot.h b/snapshot/test/test_module_snapshot.h index 7aa5df3f..3a59645e 100644 --- a/snapshot/test/test_module_snapshot.h +++ b/snapshot/test/test_module_snapshot.h @@ -60,7 +60,10 @@ class TestModuleSnapshot final : public ModuleSnapshot { source_version_[3] = source_version_3; } void SetModuleType(ModuleType module_type) { module_type_ = module_type; } - void SetUUID(const crashpad::UUID& uuid) { uuid_ = uuid; } + void SetUUIDAndAge(const crashpad::UUID& uuid, uint32_t age) { + uuid_ = uuid; + age_ = age; + } void SetAnnotationsVector( const std::vector& annotations_vector) { annotations_vector_ = annotations_vector; @@ -85,7 +88,7 @@ class TestModuleSnapshot final : public ModuleSnapshot { uint16_t* version_2, uint16_t* version_3) const override; ModuleType GetModuleType() const override; - void UUID(crashpad::UUID* uuid) const override; + void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const override; std::vector AnnotationsVector() const override; std::map AnnotationsSimpleMap() const override; @@ -97,6 +100,7 @@ class TestModuleSnapshot final : public ModuleSnapshot { uint16_t file_version_[4]; uint16_t source_version_[4]; ModuleType module_type_; + uint32_t age_; crashpad::UUID uuid_; std::vector annotations_vector_; std::map annotations_simple_map_; diff --git a/snapshot/win/module_snapshot_win.cc b/snapshot/win/module_snapshot_win.cc index 6c583092..86aae48f 100644 --- a/snapshot/win/module_snapshot_win.cc +++ b/snapshot/win/module_snapshot_win.cc @@ -135,13 +135,18 @@ ModuleSnapshot::ModuleType ModuleSnapshotWin::GetModuleType() const { return ModuleSnapshot::kModuleTypeUnknown; } -void ModuleSnapshotWin::UUID(crashpad::UUID* uuid) const { +void ModuleSnapshotWin::UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - // TODO(scottmg): Also pass the age and pdbname through to snapshot? - DWORD age; + // TODO(scottmg): Consider passing pdbname through to snapshot. std::string pdbname; - if (!pe_image_reader_->DebugDirectoryInformation(uuid, &age, &pdbname)) + DWORD age_dword; + if (!pe_image_reader_->DebugDirectoryInformation( + uuid, &age_dword, &pdbname)) { *uuid = crashpad::UUID(); + *age = 0; + } + static_assert(sizeof(DWORD) == sizeof(uint32_t), "unexpected age size"); + *age = age_dword; } std::vector ModuleSnapshotWin::AnnotationsVector() const { diff --git a/snapshot/win/module_snapshot_win.h b/snapshot/win/module_snapshot_win.h index ee4f3ffc..7cdcc566 100644 --- a/snapshot/win/module_snapshot_win.h +++ b/snapshot/win/module_snapshot_win.h @@ -80,7 +80,7 @@ class ModuleSnapshotWin final : public ModuleSnapshot { uint16_t* version_2, uint16_t* version_3) const override; ModuleType GetModuleType() const override; - void UUID(crashpad::UUID* uuid) const override; + void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const override; std::vector AnnotationsVector() const override; std::map AnnotationsSimpleMap() const override;