1 //===-- BreakpadRecordsTest.cpp -------------------------------------------===// 2 // 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h" 11 #include "gtest/gtest.h" 12 13 using namespace lldb_private; 14 using namespace lldb_private::breakpad; 15 16 TEST(Record, classify) { 17 EXPECT_EQ(Record::Module, Record::classify("MODULE")); 18 EXPECT_EQ(Record::Info, Record::classify("INFO")); 19 EXPECT_EQ(Record::File, Record::classify("FILE")); 20 EXPECT_EQ(Record::Func, Record::classify("FUNC")); 21 EXPECT_EQ(Record::Inline, Record::classify("INLINE")); 22 EXPECT_EQ(Record::InlineOrigin, Record::classify("INLINE_ORIGIN")); 23 EXPECT_EQ(Record::Public, Record::classify("PUBLIC")); 24 EXPECT_EQ(Record::StackCFI, Record::classify("STACK CFI")); 25 EXPECT_EQ(Record::StackWin, Record::classify("STACK WIN")); 26 27 // Any obviously incorrect lines will be classified as such. 28 EXPECT_EQ(llvm::None, Record::classify("STACK")); 29 EXPECT_EQ(llvm::None, Record::classify("STACK CODE_ID")); 30 EXPECT_EQ(llvm::None, Record::classify("CODE_ID")); 31 32 // Any line which does not start with a known keyword will be classified as a 33 // line record, as those are the only ones that start without a keyword. 34 EXPECT_EQ(Record::Line, Record::classify("deadbeef")); 35 EXPECT_EQ(Record::Line, Record::classify("12")); 36 } 37 38 TEST(ModuleRecord, parse) { 39 EXPECT_EQ(ModuleRecord(llvm::Triple::Linux, llvm::Triple::x86_64, 40 UUID::fromData("@ABCDEFGHIJKLMNO", 16)), 41 ModuleRecord::parse( 42 "MODULE Linux x86_64 404142434445464748494a4b4c4d4e4f0 a.out")); 43 44 EXPECT_EQ(llvm::None, ModuleRecord::parse("MODULE")); 45 EXPECT_EQ(llvm::None, ModuleRecord::parse("MODULE Linux")); 46 EXPECT_EQ(llvm::None, ModuleRecord::parse("MODULE Linux x86_64")); 47 EXPECT_EQ(llvm::None, 48 ModuleRecord::parse("MODULE Linux x86_64 deadbeefbaadf00d")); 49 } 50 51 TEST(InfoRecord, parse) { 52 EXPECT_EQ(InfoRecord(UUID::fromData("@ABCDEFGHIJKLMNO", 16)), 53 InfoRecord::parse("INFO CODE_ID 404142434445464748494a4b4c4d4e4f")); 54 EXPECT_EQ(InfoRecord(UUID()), InfoRecord::parse("INFO CODE_ID 47 a.exe")); 55 56 EXPECT_EQ(llvm::None, InfoRecord::parse("INFO")); 57 EXPECT_EQ(llvm::None, InfoRecord::parse("INFO CODE_ID")); 58 } 59 60 TEST(FileRecord, parse) { 61 EXPECT_EQ(FileRecord(47, "foo"), FileRecord::parse("FILE 47 foo")); 62 EXPECT_EQ(llvm::None, FileRecord::parse("FILE 47")); 63 EXPECT_EQ(llvm::None, FileRecord::parse("FILE")); 64 EXPECT_EQ(llvm::None, FileRecord::parse("")); 65 } 66 67 TEST(FuncRecord, parse) { 68 EXPECT_EQ(FuncRecord(true, 0x47, 0x7, 0x8, "foo"), 69 FuncRecord::parse("FUNC m 47 7 8 foo")); 70 EXPECT_EQ(FuncRecord(false, 0x47, 0x7, 0x8, "foo"), 71 FuncRecord::parse("FUNC 47 7 8 foo")); 72 73 EXPECT_EQ(llvm::None, FuncRecord::parse("PUBLIC 47 7 8 foo")); 74 EXPECT_EQ(llvm::None, FuncRecord::parse("FUNC 47 7 8")); 75 EXPECT_EQ(llvm::None, FuncRecord::parse("FUNC 47 7")); 76 EXPECT_EQ(llvm::None, FuncRecord::parse("FUNC 47")); 77 EXPECT_EQ(llvm::None, FuncRecord::parse("FUNC m")); 78 EXPECT_EQ(llvm::None, FuncRecord::parse("FUNC")); 79 } 80 81 TEST(InlineOriginRecord, parse) { 82 EXPECT_EQ(InlineOriginRecord(47, "foo"), 83 InlineOriginRecord::parse("INLINE_ORIGIN 47 foo")); 84 EXPECT_EQ(llvm::None, InlineOriginRecord::parse("INLINE_ORIGIN 47")); 85 EXPECT_EQ(llvm::None, InlineOriginRecord::parse("INLINE_ORIGIN")); 86 EXPECT_EQ(llvm::None, InlineOriginRecord::parse("")); 87 } 88 89 TEST(InlineRecord, parse) { 90 InlineRecord record1 = InlineRecord(0, 1, 2, 3); 91 record1.Ranges.emplace_back(4, 5); 92 EXPECT_EQ(record1, InlineRecord::parse("INLINE 0 1 2 3 4 5")); 93 record1.Ranges.emplace_back(6, 7); 94 EXPECT_EQ(record1, InlineRecord::parse("INLINE 0 1 2 3 4 5 6 7")); 95 EXPECT_EQ(llvm::None, InlineRecord::parse("INLINE 0 1 2 3")); 96 EXPECT_EQ(llvm::None, InlineRecord::parse("INLINE 0 1 2 3 4 5 6")); 97 EXPECT_EQ(llvm::None, InlineRecord::parse("INLNIE 0")); 98 EXPECT_EQ(llvm::None, InlineRecord::parse("")); 99 EXPECT_EQ(llvm::None, InlineRecord::parse("FUNC")); 100 } 101 102 TEST(LineRecord, parse) { 103 EXPECT_EQ(LineRecord(0x47, 0x74, 47, 74), LineRecord::parse("47 74 47 74")); 104 EXPECT_EQ(llvm::None, LineRecord::parse("47 74 47")); 105 EXPECT_EQ(llvm::None, LineRecord::parse("47 74")); 106 EXPECT_EQ(llvm::None, LineRecord::parse("47")); 107 EXPECT_EQ(llvm::None, LineRecord::parse("")); 108 EXPECT_EQ(llvm::None, LineRecord::parse("FUNC")); 109 } 110 111 TEST(PublicRecord, parse) { 112 EXPECT_EQ(PublicRecord(true, 0x47, 0x8, "foo"), 113 PublicRecord::parse("PUBLIC m 47 8 foo")); 114 EXPECT_EQ(PublicRecord(false, 0x47, 0x8, "foo"), 115 PublicRecord::parse("PUBLIC 47 8 foo")); 116 117 EXPECT_EQ(llvm::None, PublicRecord::parse("FUNC 47 8 foo")); 118 EXPECT_EQ(llvm::None, PublicRecord::parse("PUBLIC 47 8")); 119 EXPECT_EQ(llvm::None, PublicRecord::parse("PUBLIC 47")); 120 EXPECT_EQ(llvm::None, PublicRecord::parse("PUBLIC m")); 121 EXPECT_EQ(llvm::None, PublicRecord::parse("PUBLIC")); 122 } 123 124 TEST(StackCFIRecord, parse) { 125 EXPECT_EQ(StackCFIRecord(0x47, 0x8, ".cfa: $esp 4 + $eip: .cfa 4 - ^"), 126 StackCFIRecord::parse( 127 "STACK CFI INIT 47 8 .cfa: $esp 4 + $eip: .cfa 4 - ^")); 128 129 EXPECT_EQ(StackCFIRecord(0x47, 0x8, ".cfa: $esp 4 +"), 130 StackCFIRecord::parse("STACK CFI INIT 47 8 .cfa: $esp 4 + ")); 131 132 EXPECT_EQ(StackCFIRecord(0x47, llvm::None, ".cfa: $esp 4 +"), 133 StackCFIRecord::parse("STACK CFI 47 .cfa: $esp 4 +")); 134 135 // The validity of the register value expressions is not checked 136 EXPECT_EQ(StackCFIRecord(0x47, 0x8, ".cfa: ^ ^ ^"), 137 StackCFIRecord::parse("STACK CFI INIT 47 8 .cfa: ^ ^ ^")); 138 139 EXPECT_EQ(llvm::None, StackCFIRecord::parse("STACK CFI INIT 47")); 140 EXPECT_EQ(llvm::None, StackCFIRecord::parse("STACK CFI INIT")); 141 EXPECT_EQ(llvm::None, StackCFIRecord::parse("STACK CFI")); 142 EXPECT_EQ(llvm::None, StackCFIRecord::parse("STACK")); 143 EXPECT_EQ(llvm::None, StackCFIRecord::parse("FILE 47 foo")); 144 EXPECT_EQ(llvm::None, StackCFIRecord::parse("42 47")); 145 } 146 147 TEST(StackWinRecord, parse) { 148 EXPECT_EQ( 149 StackWinRecord(0x47, 0x8, 3, 4, 5, llvm::StringRef("$eip $esp ^ =")), 150 StackWinRecord::parse("STACK WIN 4 47 8 1 2 3 4 5 6 1 $eip $esp ^ =")); 151 152 EXPECT_EQ(llvm::None, StackWinRecord::parse( 153 "STACK WIN 0 47 8 1 0 0 0 0 0 1 $eip $esp ^ =")); 154 EXPECT_EQ(llvm::None, 155 StackWinRecord::parse("STACK WIN 4 47 8 1 0 0 0 0 0 0 1")); 156 EXPECT_EQ(llvm::None, StackWinRecord::parse( 157 "STACK WIN 3 47 8 1 0 0 0 0 0 1 $eip $esp ^ =")); 158 EXPECT_EQ(llvm::None, 159 StackWinRecord::parse("STACK WIN 3 47 8 1 0 0 0 0 0 0 1")); 160 EXPECT_EQ(llvm::None, StackWinRecord::parse( 161 "STACK WIN 4 47 8 1 0 0 0 0 1 $eip $esp ^ =")); 162 EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0 0 0 0 0")); 163 EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0 0 0 0")); 164 EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0 0 0")); 165 EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0 0")); 166 EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1 0")); 167 EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8 1")); 168 EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47 8")); 169 EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4 47")); 170 EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN 4")); 171 EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK WIN")); 172 EXPECT_EQ(llvm::None, StackWinRecord::parse("STACK")); 173 EXPECT_EQ(llvm::None, StackWinRecord::parse("")); 174 EXPECT_EQ(llvm::None, StackCFIRecord::parse("FILE 47 foo")); 175 EXPECT_EQ(llvm::None, StackCFIRecord::parse("42 47")); 176 } 177