diff options
author | Ted Mielczarek <ted@mielczarek.org> | 2016-04-05 09:34:20 -0400 |
---|---|---|
committer | Ted Mielczarek <ted@mielczarek.org> | 2016-04-05 09:34:20 -0400 |
commit | 6c8f80aa8b3ba8120c4158c069bb298c044dedf9 (patch) | |
tree | 2164203da75d894883e042368c34370f6c3af4c8 /src/common/linux/file_id_unittest.cc | |
parent | sample_app: enable C++11 for Android builds (diff) | |
download | breakpad-6c8f80aa8b3ba8120c4158c069bb298c044dedf9.tar.xz |
Switch the Linux minidump writer to use MDCVInfoELF for CV data.
This preserves full build ids in minidumps, which are useful for
tracking down the right version of system libraries from Linux
distributions.
The default build id produced by GNU binutils' ld is a 160-bit SHA-1
hash of some parts of the binary, which is exactly 20 bytes:
https://sourceware.org/binutils/docs-2.26/ld/Options.html#index-g_t_002d_002dbuild_002did-292
The bulk of the changes here are to change the signatures of the
FileID methods to use a wasteful_vector instead of raw pointers, since
build ids can be of arbitrary length.
The previous change that added support for this in the processor code
preserved the return value of `Minidump::debug_identifier()` as the
current `GUID+age` treatment for backwards-compatibility, and exposed
the full build id from `Minidump::code_identifier()`, which was
previously stubbed out for Linux dumps. This change keeps the debug ID
in the `dump_syms` output the same to match.
R=mark@chromium.org, thestig@chromium.org
BUG=
Review URL: https://codereview.chromium.org/1688743002 .
Diffstat (limited to 'src/common/linux/file_id_unittest.cc')
-rw-r--r-- | src/common/linux/file_id_unittest.cc | 176 |
1 files changed, 117 insertions, 59 deletions
diff --git a/src/common/linux/file_id_unittest.cc b/src/common/linux/file_id_unittest.cc index 760eae82..ec11bb25 100644 --- a/src/common/linux/file_id_unittest.cc +++ b/src/common/linux/file_id_unittest.cc @@ -33,6 +33,7 @@ #include <stdlib.h> #include <string> +#include <vector> #include "common/linux/elf_gnu_compat.h" #include "common/linux/elfutils.h" @@ -45,13 +46,11 @@ #include "breakpad_googletest_includes.h" using namespace google_breakpad; -using google_breakpad::ElfClass32; -using google_breakpad::ElfClass64; -using google_breakpad::SafeReadLink; using google_breakpad::synth_elf::ELF; using google_breakpad::synth_elf::Notes; using google_breakpad::test_assembler::kLittleEndian; using google_breakpad::test_assembler::Section; +using std::vector; using ::testing::Types; namespace { @@ -64,6 +63,8 @@ void PopulateSection(Section* section, int size, int prime_number) { section->Append(1, (i % prime_number) % 256); } +typedef wasteful_vector<uint8_t> id_vector; + } // namespace #ifndef __ANDROID__ @@ -87,19 +88,20 @@ TEST(FileIDStripTest, StripSelf) { sprintf(cmdline, "strip \"%s\"", templ.c_str()); ASSERT_EQ(0, system(cmdline)) << "Failed to execute: " << cmdline; - uint8_t identifier1[sizeof(MDGUID)]; - uint8_t identifier2[sizeof(MDGUID)]; + PageAllocator allocator; + id_vector identifier1(&allocator, kDefaultBuildIdSize); + id_vector identifier2(&allocator, kDefaultBuildIdSize); + FileID fileid1(exe_name); EXPECT_TRUE(fileid1.ElfFileIdentifier(identifier1)); FileID fileid2(templ.c_str()); EXPECT_TRUE(fileid2.ElfFileIdentifier(identifier2)); - char identifier_string1[37]; - char identifier_string2[37]; - FileID::ConvertIdentifierToString(identifier1, identifier_string1, - 37); - FileID::ConvertIdentifierToString(identifier2, identifier_string2, - 37); - EXPECT_STREQ(identifier_string1, identifier_string2); + + string identifier_string1 = + FileID::ConvertIdentifierToUUIDString(identifier1); + string identifier_string2 = + FileID::ConvertIdentifierToUUIDString(identifier2); + EXPECT_EQ(identifier_string1, identifier_string2); } #endif // !__ANDROID__ @@ -116,8 +118,22 @@ public: elfdata = &elfdata_v[0]; } + id_vector make_vector() { + return id_vector(&allocator, kDefaultBuildIdSize); + } + + template<size_t N> + string get_file_id(const uint8_t (&data)[N]) { + id_vector expected_identifier(make_vector()); + expected_identifier.insert(expected_identifier.end(), + &data[0], + data + N); + return FileID::ConvertIdentifierToUUIDString(expected_identifier); + } + vector<uint8_t> elfdata_v; uint8_t* elfdata; + PageAllocator allocator; }; typedef Types<ElfClass32, ElfClass64> ElfClasses; @@ -125,10 +141,8 @@ typedef Types<ElfClass32, ElfClass64> ElfClasses; TYPED_TEST_CASE(FileIDTest, ElfClasses); TYPED_TEST(FileIDTest, ElfClass) { - uint8_t identifier[sizeof(MDGUID)]; const char expected_identifier_string[] = - "80808080-8080-0000-0000-008080808080"; - char identifier_string[sizeof(expected_identifier_string)]; + "80808080808000000000008080808080"; const size_t kTextSectionSize = 128; ELF elf(EM_386, TypeParam::kClass, kLittleEndian); @@ -140,58 +154,106 @@ TYPED_TEST(FileIDTest, ElfClass) { elf.Finish(); this->GetElfContents(elf); + id_vector identifier(this->make_vector()); EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, identifier)); - FileID::ConvertIdentifierToString(identifier, identifier_string, - sizeof(identifier_string)); - EXPECT_STREQ(expected_identifier_string, identifier_string); + string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier); + EXPECT_EQ(expected_identifier_string, identifier_string); } TYPED_TEST(FileIDTest, BuildID) { - const uint8_t kExpectedIdentifier[sizeof(MDGUID)] = + const uint8_t kExpectedIdentifierBytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; - char expected_identifier_string[] = - "00000000-0000-0000-0000-000000000000"; - FileID::ConvertIdentifierToString(kExpectedIdentifier, - expected_identifier_string, - sizeof(expected_identifier_string)); + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13}; + const string expected_identifier_string = + this->get_file_id(kExpectedIdentifierBytes); + + ELF elf(EM_386, TypeParam::kClass, kLittleEndian); + Section text(kLittleEndian); + text.Append(4096, 0); + elf.AddSection(".text", text, SHT_PROGBITS); + Notes notes(kLittleEndian); + notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes, + sizeof(kExpectedIdentifierBytes)); + elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE); + elf.Finish(); + this->GetElfContents(elf); - uint8_t identifier[sizeof(MDGUID)]; - char identifier_string[sizeof(expected_identifier_string)]; + id_vector identifier(this->make_vector()); + EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, + identifier)); + EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size()); + + string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier); + EXPECT_EQ(expected_identifier_string, identifier_string); +} + +// Test that a build id note with fewer bytes than usual is handled. +TYPED_TEST(FileIDTest, BuildIDShort) { + const uint8_t kExpectedIdentifierBytes[] = + {0x00, 0x01, 0x02, 0x03}; + const string expected_identifier_string = + this->get_file_id(kExpectedIdentifierBytes); ELF elf(EM_386, TypeParam::kClass, kLittleEndian); Section text(kLittleEndian); text.Append(4096, 0); elf.AddSection(".text", text, SHT_PROGBITS); Notes notes(kLittleEndian); - notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifier, - sizeof(kExpectedIdentifier)); + notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes, + sizeof(kExpectedIdentifierBytes)); elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE); elf.Finish(); this->GetElfContents(elf); + id_vector identifier(this->make_vector()); EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, identifier)); + EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size()); - FileID::ConvertIdentifierToString(identifier, identifier_string, - sizeof(identifier_string)); - EXPECT_STREQ(expected_identifier_string, identifier_string); + string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier); + EXPECT_EQ(expected_identifier_string, identifier_string); } -TYPED_TEST(FileIDTest, BuildIDPH) { - const uint8_t kExpectedIdentifier[sizeof(MDGUID)] = +// Test that a build id note with more bytes than usual is handled. +TYPED_TEST(FileIDTest, BuildIDLong) { + const uint8_t kExpectedIdentifierBytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; - char expected_identifier_string[] = - "00000000-0000-0000-0000-000000000000"; - FileID::ConvertIdentifierToString(kExpectedIdentifier, - expected_identifier_string, - sizeof(expected_identifier_string)); + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; + const string expected_identifier_string = + this->get_file_id(kExpectedIdentifierBytes); - uint8_t identifier[sizeof(MDGUID)]; - char identifier_string[sizeof(expected_identifier_string)]; + ELF elf(EM_386, TypeParam::kClass, kLittleEndian); + Section text(kLittleEndian); + text.Append(4096, 0); + elf.AddSection(".text", text, SHT_PROGBITS); + Notes notes(kLittleEndian); + notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes, + sizeof(kExpectedIdentifierBytes)); + elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE); + elf.Finish(); + this->GetElfContents(elf); + + id_vector identifier(this->make_vector()); + EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, + identifier)); + EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size()); + + string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier); + EXPECT_EQ(expected_identifier_string, identifier_string); +} + +TYPED_TEST(FileIDTest, BuildIDPH) { + const uint8_t kExpectedIdentifierBytes[] = + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13}; + const string expected_identifier_string = + this->get_file_id(kExpectedIdentifierBytes); ELF elf(EM_386, TypeParam::kClass, kLittleEndian); Section text(kLittleEndian); @@ -200,31 +262,25 @@ TYPED_TEST(FileIDTest, BuildIDPH) { Notes notes(kLittleEndian); notes.AddNote(0, "Linux", reinterpret_cast<const uint8_t *>("\0x42\0x02\0\0"), 4); - notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifier, - sizeof(kExpectedIdentifier)); + notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes, + sizeof(kExpectedIdentifierBytes)); int note_idx = elf.AddSection(".note", notes, SHT_NOTE); elf.AddSegment(note_idx, note_idx, PT_NOTE); elf.Finish(); this->GetElfContents(elf); + id_vector identifier(this->make_vector()); EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, identifier)); + EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size()); - FileID::ConvertIdentifierToString(identifier, identifier_string, - sizeof(identifier_string)); - EXPECT_STREQ(expected_identifier_string, identifier_string); + string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier); + EXPECT_EQ(expected_identifier_string, identifier_string); } // Test to make sure two files with different text sections produce // different hashes when not using a build id. TYPED_TEST(FileIDTest, UniqueHashes) { - char identifier_string_1[] = - "00000000-0000-0000-0000-000000000000"; - char identifier_string_2[] = - "00000000-0000-0000-0000-000000000000"; - uint8_t identifier_1[sizeof(MDGUID)]; - uint8_t identifier_2[sizeof(MDGUID)]; - { ELF elf1(EM_386, TypeParam::kClass, kLittleEndian); Section foo_1(kLittleEndian); @@ -237,10 +293,11 @@ TYPED_TEST(FileIDTest, UniqueHashes) { this->GetElfContents(elf1); } + id_vector identifier_1(this->make_vector()); EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, identifier_1)); - FileID::ConvertIdentifierToString(identifier_1, identifier_string_1, - sizeof(identifier_string_1)); + string identifier_string_1 = + FileID::ConvertIdentifierToUUIDString(identifier_1); { ELF elf2(EM_386, TypeParam::kClass, kLittleEndian); @@ -254,10 +311,11 @@ TYPED_TEST(FileIDTest, UniqueHashes) { this->GetElfContents(elf2); } + id_vector identifier_2(this->make_vector()); EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata, identifier_2)); - FileID::ConvertIdentifierToString(identifier_2, identifier_string_2, - sizeof(identifier_string_2)); + string identifier_string_2 = + FileID::ConvertIdentifierToUUIDString(identifier_2); - EXPECT_STRNE(identifier_string_1, identifier_string_2); + EXPECT_NE(identifier_string_1, identifier_string_2); } |