brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.5 KiB · c805665 Raw
447 lines · cpp
1//===- MinidumpYAMLTest.cpp - Tests for Minidump<->YAML code --------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/Object/Minidump.h"10#include "llvm/ObjectYAML/yaml2obj.h"11#include "llvm/Support/YAMLTraits.h"12#include "llvm/Testing/Support/Error.h"13#include "gtest/gtest.h"14 15using namespace llvm;16using namespace llvm::minidump;17 18static Expected<std::unique_ptr<object::MinidumpFile>>19toBinary(SmallVectorImpl<char> &Storage, StringRef Yaml) {20  Storage.clear();21  raw_svector_ostream OS(Storage);22  yaml::Input YIn(Yaml);23  if (!yaml::convertYAML(YIn, OS, [](const Twine &Msg) {}))24    return createStringError(std::errc::invalid_argument,25                             "unable to convert YAML");26 27  return object::MinidumpFile::create(MemoryBufferRef(OS.str(), "Binary"));28}29 30TEST(MinidumpYAML, Basic) {31  SmallString<0> Storage;32  auto ExpectedFile = toBinary(Storage, R"(33--- !minidump34Streams:35  - Type:            SystemInfo36    Processor Arch:  ARM6437    Platform ID:     Linux38    CPU:39      CPUID:           0x0506070840  - Type:            LinuxMaps41    Text:             |42      400d9000-400db000 r-xp 00000000 b3:04 227        /system/bin/app_process43      400db000-400dc000 r--p 00001000 b3:04 227        /system/bin/app_process44 45  - Type:            LinuxAuxv46    Content:         DEADBEEFBAADF00D)");47  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());48  object::MinidumpFile &File = **ExpectedFile;49 50  ASSERT_EQ(3u, File.streams().size());51 52  EXPECT_EQ(StreamType::SystemInfo, File.streams()[0].Type);53  auto ExpectedSysInfo = File.getSystemInfo();54  ASSERT_THAT_EXPECTED(ExpectedSysInfo, Succeeded());55  const SystemInfo &SysInfo = *ExpectedSysInfo;56  EXPECT_EQ(ProcessorArchitecture::ARM64, SysInfo.ProcessorArch);57  EXPECT_EQ(OSPlatform::Linux, SysInfo.PlatformId);58  EXPECT_EQ(0x05060708u, SysInfo.CPU.Arm.CPUID);59 60  EXPECT_EQ(StreamType::LinuxMaps, File.streams()[1].Type);61  EXPECT_EQ("400d9000-400db000 r-xp 00000000 b3:04 227        "62            "/system/bin/app_process\n"63            "400db000-400dc000 r--p 00001000 b3:04 227        "64            "/system/bin/app_process\n",65            toStringRef(*File.getRawStream(StreamType::LinuxMaps)));66 67  EXPECT_EQ(StreamType::LinuxAuxv, File.streams()[2].Type);68  EXPECT_EQ((ArrayRef<uint8_t>{0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, 0xF0, 0x0D}),69            File.getRawStream(StreamType::LinuxAuxv));70}71 72TEST(MinidumpYAML, RawContent) {73  SmallString<0> Storage;74  auto ExpectedFile = toBinary(Storage, R"(75--- !minidump76Streams:77  - Type:            LinuxAuxv78    Size:            979    Content:         DEADBEEFBAADF00D)");80  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());81  object::MinidumpFile &File = **ExpectedFile;82 83  EXPECT_EQ(84      (ArrayRef<uint8_t>{0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, 0xF0, 0x0D, 0x00}),85      File.getRawStream(StreamType::LinuxAuxv));86}87 88TEST(MinidumpYAML, X86SystemInfo) {89  SmallString<0> Storage;90  auto ExpectedFile = toBinary(Storage, R"(91--- !minidump92Streams:93  - Type:            SystemInfo94    Processor Arch:  X8695    Platform ID:     Linux96    CPU:97      Vendor ID:       LLVMLLVMLLVM98      Version Info:    0x0102030499      Feature Info:    0x05060708100      AMD Extended Features: 0x09000102)");101  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());102  object::MinidumpFile &File = **ExpectedFile;103 104  ASSERT_EQ(1u, File.streams().size());105 106  auto ExpectedSysInfo = File.getSystemInfo();107  ASSERT_THAT_EXPECTED(ExpectedSysInfo, Succeeded());108  const SystemInfo &SysInfo = *ExpectedSysInfo;109  EXPECT_EQ(ProcessorArchitecture::X86, SysInfo.ProcessorArch);110  EXPECT_EQ(OSPlatform::Linux, SysInfo.PlatformId);111  EXPECT_EQ("LLVMLLVMLLVM", StringRef(SysInfo.CPU.X86.VendorID,112                                      sizeof(SysInfo.CPU.X86.VendorID)));113  EXPECT_EQ(0x01020304u, SysInfo.CPU.X86.VersionInfo);114  EXPECT_EQ(0x05060708u, SysInfo.CPU.X86.FeatureInfo);115  EXPECT_EQ(0x09000102u, SysInfo.CPU.X86.AMDExtendedFeatures);116}117 118TEST(MinidumpYAML, OtherSystemInfo) {119  SmallString<0> Storage;120  auto ExpectedFile = toBinary(Storage, R"(121--- !minidump122Streams:123  - Type:            SystemInfo124    Processor Arch:  PPC125    Platform ID:     Linux126    CPU:127      Features:        000102030405060708090a0b0c0d0e0f)");128  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());129  object::MinidumpFile &File = **ExpectedFile;130 131  ASSERT_EQ(1u, File.streams().size());132 133  auto ExpectedSysInfo = File.getSystemInfo();134  ASSERT_THAT_EXPECTED(ExpectedSysInfo, Succeeded());135  const SystemInfo &SysInfo = *ExpectedSysInfo;136  EXPECT_EQ(ProcessorArchitecture::PPC, SysInfo.ProcessorArch);137  EXPECT_EQ(OSPlatform::Linux, SysInfo.PlatformId);138  EXPECT_EQ(139      (ArrayRef<uint8_t>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}),140      ArrayRef(SysInfo.CPU.Other.ProcessorFeatures));141}142 143// Test that we can parse a normal-looking ExceptionStream.144TEST(MinidumpYAML, ExceptionStream) {145  SmallString<0> Storage;146  auto ExpectedFile = toBinary(Storage, R"(147--- !minidump148Streams:149  - Type:            Exception150    Thread ID:  0x7151    Exception Record:152      Exception Code:  0x23153      Exception Flags: 0x5154      Exception Record: 0x0102030405060708155      Exception Address: 0x0a0b0c0d0e0f1011156      Number of Parameters: 2157      Parameter 0: 0x22158      Parameter 1: 0x24159    Thread Context:  3DeadBeefDefacedABadCafe)");160  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());161  object::MinidumpFile &File = **ExpectedFile;162 163  ASSERT_EQ(1u, File.streams().size());164 165  auto ExceptionIterator = File.getExceptionStreams().begin();166 167  Expected<const ExceptionStream &> ExpectedStream = *ExceptionIterator;168 169  ASSERT_THAT_EXPECTED(ExpectedStream, Succeeded());170 171  const minidump::ExceptionStream &Stream = *ExpectedStream;172  EXPECT_EQ(0x7u, Stream.ThreadId);173  const minidump::Exception &Exception = Stream.ExceptionRecord;174  EXPECT_EQ(0x23u, Exception.ExceptionCode);175  EXPECT_EQ(0x5u, Exception.ExceptionFlags);176  EXPECT_EQ(0x0102030405060708u, Exception.ExceptionRecord);177  EXPECT_EQ(0x0a0b0c0d0e0f1011u, Exception.ExceptionAddress);178  EXPECT_EQ(2u, Exception.NumberParameters);179  EXPECT_EQ(0x22u, Exception.ExceptionInformation[0]);180  EXPECT_EQ(0x24u, Exception.ExceptionInformation[1]);181 182  Expected<ArrayRef<uint8_t>> ExpectedContext =183      File.getRawData(Stream.ThreadContext);184  ASSERT_THAT_EXPECTED(ExpectedContext, Succeeded());185  EXPECT_EQ((ArrayRef<uint8_t>{0x3d, 0xea, 0xdb, 0xee, 0xfd, 0xef, 0xac, 0xed,186                               0xab, 0xad, 0xca, 0xfe}),187            *ExpectedContext);188}189 190// Test that we can parse an exception stream with no ExceptionInformation.191TEST(MinidumpYAML, ExceptionStream_NoParameters) {192  SmallString<0> Storage;193  auto ExpectedFile = toBinary(Storage, R"(194--- !minidump195Streams:196  - Type:            Exception197    Thread ID:  0x7198    Exception Record:199      Exception Code:  0x23200      Exception Flags: 0x5201      Exception Record: 0x0102030405060708202      Exception Address: 0x0a0b0c0d0e0f1011203    Thread Context:  3DeadBeefDefacedABadCafe)");204  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());205  object::MinidumpFile &File = **ExpectedFile;206 207  ASSERT_EQ(1u, File.streams().size());208 209  auto ExceptionIterator = File.getExceptionStreams().begin();210 211  Expected<const ExceptionStream &> ExpectedStream = *ExceptionIterator;212  ASSERT_THAT_EXPECTED(ExpectedStream, Succeeded());213 214  const minidump::ExceptionStream &Stream = *ExpectedStream;215  EXPECT_EQ(0x7u, Stream.ThreadId);216  const minidump::Exception &Exception = Stream.ExceptionRecord;217  EXPECT_EQ(0x23u, Exception.ExceptionCode);218  EXPECT_EQ(0x5u, Exception.ExceptionFlags);219  EXPECT_EQ(0x0102030405060708u, Exception.ExceptionRecord);220  EXPECT_EQ(0x0a0b0c0d0e0f1011u, Exception.ExceptionAddress);221  EXPECT_EQ(0u, Exception.NumberParameters);222 223  Expected<ArrayRef<uint8_t>> ExpectedContext =224      File.getRawData(Stream.ThreadContext);225  ASSERT_THAT_EXPECTED(ExpectedContext, Succeeded());226  EXPECT_EQ((ArrayRef<uint8_t>{0x3d, 0xea, 0xdb, 0xee, 0xfd, 0xef, 0xac, 0xed,227                               0xab, 0xad, 0xca, 0xfe}),228            *ExpectedContext);229}230 231// Test that we can parse an ExceptionStream where the stated number of232// parameters is greater than the actual size of the ExceptionInformation233// array.234TEST(MinidumpYAML, ExceptionStream_TooManyParameters) {235  SmallString<0> Storage;236  auto ExpectedFile = toBinary(Storage, R"(237--- !minidump238Streams:239  - Type:            Exception240    Thread ID:  0x8241    Exception Record:242      Exception Code: 0243      Number of Parameters: 16244      Parameter 0: 0x0245      Parameter 1: 0xff246      Parameter 2: 0xee247      Parameter 3: 0xdd248      Parameter 4: 0xcc249      Parameter 5: 0xbb250      Parameter 6: 0xaa251      Parameter 7: 0x99252      Parameter 8: 0x88253      Parameter 9: 0x77254      Parameter 10: 0x66255      Parameter 11: 0x55256      Parameter 12: 0x44257      Parameter 13: 0x33258      Parameter 14: 0x22259    Thread Context:  3DeadBeefDefacedABadCafe)");260  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());261  object::MinidumpFile &File = **ExpectedFile;262 263  ASSERT_EQ(1u, File.streams().size());264 265  auto ExceptionIterator = File.getExceptionStreams().begin();266 267  Expected<const ExceptionStream &> ExpectedStream = *ExceptionIterator;268 269  ASSERT_THAT_EXPECTED(ExpectedStream, Succeeded());270 271  const minidump::ExceptionStream &Stream = *ExpectedStream;272  EXPECT_EQ(0x8u, Stream.ThreadId);273  const minidump::Exception &Exception = Stream.ExceptionRecord;274  EXPECT_EQ(0x0u, Exception.ExceptionCode);275  EXPECT_EQ(0x0u, Exception.ExceptionFlags);276  EXPECT_EQ(0x00u, Exception.ExceptionRecord);277  EXPECT_EQ(0x0u, Exception.ExceptionAddress);278  EXPECT_EQ(16u, Exception.NumberParameters);279  EXPECT_EQ(0x0u, Exception.ExceptionInformation[0]);280  for (int Index = 1; Index < 15; ++Index) {281    EXPECT_EQ(0x110u - Index * 0x11, Exception.ExceptionInformation[Index]);282  }283 284  Expected<ArrayRef<uint8_t>> ExpectedContext =285      File.getRawData(Stream.ThreadContext);286  ASSERT_THAT_EXPECTED(ExpectedContext, Succeeded());287  EXPECT_EQ((ArrayRef<uint8_t>{0x3d, 0xea, 0xdb, 0xee, 0xfd, 0xef, 0xac, 0xed,288                               0xab, 0xad, 0xca, 0xfe}),289            *ExpectedContext);290}291 292// Test that we can parse an ExceptionStream where the number of293// ExceptionInformation parameters provided is greater than the294// specified Number of Parameters.295TEST(MinidumpYAML, ExceptionStream_ExtraParameter) {296  SmallString<0> Storage;297  auto ExpectedFile = toBinary(Storage, R"(298--- !minidump299Streams:300  - Type:            Exception301    Thread ID:  0x7302    Exception Record:303      Exception Code:  0x23304      Exception Flags: 0x5305      Exception Record: 0x0102030405060708306      Exception Address: 0x0a0b0c0d0e0f1011307      Number of Parameters: 2308      Parameter 0: 0x99309      Parameter 1: 0x23310      Parameter 2: 0x42311    Thread Context:  3DeadBeefDefacedABadCafe)");312  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());313  object::MinidumpFile &File = **ExpectedFile;314 315  ASSERT_EQ(1u, File.streams().size());316 317  auto ExceptionIterator = File.getExceptionStreams().begin();318 319  Expected<const ExceptionStream &> ExpectedStream = *ExceptionIterator;320 321  ASSERT_THAT_EXPECTED(ExpectedStream, Succeeded());322 323  const minidump::ExceptionStream &Stream = *ExpectedStream;324  EXPECT_EQ(0x7u, Stream.ThreadId);325  const minidump::Exception &Exception = Stream.ExceptionRecord;326  EXPECT_EQ(0x23u, Exception.ExceptionCode);327  EXPECT_EQ(0x5u, Exception.ExceptionFlags);328  EXPECT_EQ(0x0102030405060708u, Exception.ExceptionRecord);329  EXPECT_EQ(0x0a0b0c0d0e0f1011u, Exception.ExceptionAddress);330  EXPECT_EQ(2u, Exception.NumberParameters);331  EXPECT_EQ(0x99u, Exception.ExceptionInformation[0]);332  EXPECT_EQ(0x23u, Exception.ExceptionInformation[1]);333  EXPECT_EQ(0x42u, Exception.ExceptionInformation[2]);334 335  Expected<ArrayRef<uint8_t>> ExpectedContext =336      File.getRawData(Stream.ThreadContext);337  ASSERT_THAT_EXPECTED(ExpectedContext, Succeeded());338  EXPECT_EQ((ArrayRef<uint8_t>{0x3d, 0xea, 0xdb, 0xee, 0xfd, 0xef, 0xac, 0xed,339                               0xab, 0xad, 0xca, 0xfe}),340            *ExpectedContext);341}342 343TEST(MinidumpYAML, MemoryRegion_64bit) {344  SmallString<0> Storage;345  auto ExpectedFile = toBinary(Storage, R"(346--- !minidump347Streams:348  - Type:            Memory64List349    Memory Ranges:350      - Start of Memory Range: 0x7FFFFFCF0818283351        Content:               '68656c6c6f'352      - Start of Memory Range: 0x7FFFFFFF0818283353        Content:               '776f726c64'354        )");355 356  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());357  object::MinidumpFile &File = **ExpectedFile;358 359  ASSERT_THAT(File.streams().size(), 1u);360 361  Error Err = Error::success();362  iterator_range<object::MinidumpFile::FallibleMemory64Iterator> MemoryList =363      File.getMemory64List(Err);364 365  ASSERT_THAT_ERROR(std::move(Err), Succeeded());366  auto Iterator = MemoryList.begin();367 368  auto DescOnePair = *Iterator;369  const minidump::MemoryDescriptor_64 &DescOne = DescOnePair.first;370  ASSERT_THAT(DescOne.StartOfMemoryRange, 0x7FFFFFCF0818283u);371  ASSERT_THAT(DescOne.DataSize, 5u);372  ++Iterator;373  ASSERT_THAT_ERROR(std::move(Err), Succeeded());374 375  auto DescTwoPair = *Iterator;376  const minidump::MemoryDescriptor_64 &DescTwo = DescTwoPair.first;377  ASSERT_THAT(DescTwo.StartOfMemoryRange, 0x7FFFFFFF0818283u);378  ASSERT_THAT(DescTwo.DataSize, 5u);379  ++Iterator;380  ASSERT_THAT_ERROR(std::move(Err), Succeeded());381 382  const std::optional<ArrayRef<uint8_t>> ExpectedContent =383      File.getRawStream(StreamType::Memory64List);384  ASSERT_TRUE(ExpectedContent);385  const size_t ExpectedStreamSize =386      sizeof(Memory64ListHeader) + (sizeof(MemoryDescriptor_64) * 2);387  ASSERT_THAT(ExpectedContent->size(), ExpectedStreamSize);388 389  Expected<minidump::Memory64ListHeader> ExpectedHeader =390      File.getMemoryList64Header();391  ASSERT_THAT_EXPECTED(ExpectedHeader, Succeeded());392  ASSERT_THAT(ExpectedHeader->BaseRVA, 92u);393 394  Expected<ArrayRef<uint8_t>> DescOneExpectedContentSlice = DescOnePair.second;395  ASSERT_THAT_EXPECTED(DescOneExpectedContentSlice, Succeeded());396  ASSERT_THAT(DescOneExpectedContentSlice->size(), 5u);397  ASSERT_THAT(*DescOneExpectedContentSlice, arrayRefFromStringRef("hello"));398 399  Expected<ArrayRef<uint8_t>> DescTwoExpectedContentSlice = DescTwoPair.second;400  ASSERT_THAT_EXPECTED(DescTwoExpectedContentSlice, Succeeded());401  ASSERT_THAT(*DescTwoExpectedContentSlice, arrayRefFromStringRef("world"));402 403  ASSERT_EQ(Iterator, MemoryList.end());404}405 406// Test that we can parse multiple exception streams.407TEST(MinidumpYAML, ExceptionStream_MultipleExceptions) {408  SmallString<0> Storage;409  auto ExpectedFile = toBinary(Storage, R"(410--- !minidump411Streams:412  - Type:            Exception413    Thread ID:  0x7414    Exception Record:415      Exception Code:  0x23416      Exception Flags: 0x5417      Exception Record: 0x0102030405060708418      Exception Address: 0x0a0b0c0d0e0f1011419      Number of Parameters: 2420      Parameter 0: 0x99421      Parameter 1: 0x23422      Parameter 2: 0x42423    Thread Context:  3DeadBeefDefacedABadCafe424  - Type:            Exception425    Thread ID:  0x5426    Exception Record:427      Exception Code:  0x23428      Exception Flags: 0x5429      Exception Record: 0x0102030405060708430      Exception Address: 0x0a0b0c0d0e0f1011431    Thread Context:  3DeadBeefDefacedABadCafe)");432 433  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());434  object::MinidumpFile &File = **ExpectedFile;435 436  ASSERT_EQ(2u, File.streams().size());437 438  size_t count = 0;439  for (auto exception_stream : File.getExceptionStreams()) {440    count++;441    ASSERT_THAT_EXPECTED(exception_stream, Succeeded());442    ASSERT_THAT(0x23u, exception_stream->ExceptionRecord.ExceptionCode);443  }444 445  ASSERT_THAT(2u, count);446}447