// Copyright 2010 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Unit test for Minidump.  Uses a pre-generated minidump and
// verifies that certain streams are correct.

#ifdef HAVE_CONFIG_H
#include <config.h>  // Must come first
#endif

#include <iostream>
#include <fstream>
#include <sstream>
#include <stdlib.h>
#include <string>
#include <vector>

#include "breakpad_googletest_includes.h"
#include "common/using_std_string.h"
#include "google_breakpad/common/minidump_format.h"
#include "google_breakpad/processor/minidump.h"
#include "processor/logging.h"
#include "processor/synth_minidump.h"

namespace {

using google_breakpad::Minidump;
using google_breakpad::MinidumpContext;
using google_breakpad::MinidumpCrashpadInfo;
using google_breakpad::MinidumpException;
using google_breakpad::MinidumpMemoryInfo;
using google_breakpad::MinidumpMemoryInfoList;
using google_breakpad::MinidumpMemoryList;
using google_breakpad::MinidumpMemoryRegion;
using google_breakpad::MinidumpModule;
using google_breakpad::MinidumpModuleList;
using google_breakpad::MinidumpSystemInfo;
using google_breakpad::MinidumpUnloadedModule;
using google_breakpad::MinidumpUnloadedModuleList;
using google_breakpad::MinidumpThread;
using google_breakpad::MinidumpThreadList;
using google_breakpad::SynthMinidump::Context;
using google_breakpad::SynthMinidump::Dump;
using google_breakpad::SynthMinidump::Exception;
using google_breakpad::SynthMinidump::Memory;
using google_breakpad::SynthMinidump::Module;
using google_breakpad::SynthMinidump::UnloadedModule;
using google_breakpad::SynthMinidump::Section;
using google_breakpad::SynthMinidump::Stream;
using google_breakpad::SynthMinidump::String;
using google_breakpad::SynthMinidump::SystemInfo;
using google_breakpad::SynthMinidump::Thread;
using google_breakpad::test_assembler::kBigEndian;
using google_breakpad::test_assembler::kLittleEndian;
using std::ifstream;
using std::istringstream;
using std::vector;
using ::testing::Return;

class MinidumpTest : public ::testing::Test {
public:
  void SetUp() {
    minidump_file_ = string(getenv("srcdir") ? getenv("srcdir") : ".") +
      "/src/processor/testdata/minidump2.dmp";
  }
  string minidump_file_;
};

TEST_F(MinidumpTest, TestMinidumpFromFile) {
  Minidump minidump(minidump_file_);
  ASSERT_EQ(minidump.path(), minidump_file_);
  ASSERT_TRUE(minidump.Read());
  const MDRawHeader* header = minidump.header();
  ASSERT_NE(header, (MDRawHeader*)NULL);
  ASSERT_EQ(header->signature, uint32_t(MD_HEADER_SIGNATURE));

  MinidumpModuleList* md_module_list = minidump.GetModuleList();
  ASSERT_TRUE(md_module_list != NULL);
  const MinidumpModule* md_module = md_module_list->GetModuleAtIndex(0);
  ASSERT_TRUE(md_module != NULL);
  ASSERT_EQ("c:\\test_app.exe", md_module->code_file());
  ASSERT_EQ("c:\\test_app.pdb", md_module->debug_file());
  ASSERT_EQ("45D35F6C2d000", md_module->code_identifier());
  ASSERT_EQ("5A9832E5287241C1838ED98914E9B7FF1", md_module->debug_identifier());
}

TEST_F(MinidumpTest, TestMinidumpFromStream) {
  // read minidump contents into memory, construct a stringstream around them
  ifstream file_stream(minidump_file_.c_str(), std::ios::in);
  ASSERT_TRUE(file_stream.good());
  vector<char> bytes;
  file_stream.seekg(0, std::ios_base::end);
  ASSERT_TRUE(file_stream.good());
  bytes.resize(file_stream.tellg());
  file_stream.seekg(0, std::ios_base::beg);
  ASSERT_TRUE(file_stream.good());
  file_stream.read(&bytes[0], bytes.size());
  ASSERT_TRUE(file_stream.good());
  string str(&bytes[0], bytes.size());
  istringstream stream(str);
  ASSERT_TRUE(stream.good());

  // now read minidump from stringstream
  Minidump minidump(stream);
  ASSERT_EQ(minidump.path(), "");
  ASSERT_TRUE(minidump.Read());
  const MDRawHeader* header = minidump.header();
  ASSERT_NE(header, (MDRawHeader*)NULL);
  ASSERT_EQ(header->signature, uint32_t(MD_HEADER_SIGNATURE));
  //TODO: add more checks here
}

TEST_F(MinidumpTest, TestMinidumpWithCrashpadAnnotations) {
  string crashpad_minidump_file =
      string(getenv("srcdir") ? getenv("srcdir") : ".") +
      "/src/processor/testdata/minidump_crashpad_annotation.dmp";

  Minidump minidump(crashpad_minidump_file);
  ASSERT_EQ(minidump.path(), crashpad_minidump_file);
  ASSERT_TRUE(minidump.Read());

  MinidumpCrashpadInfo* crashpad_info = minidump.GetCrashpadInfo();
  ASSERT_TRUE(crashpad_info != NULL);

  const std::vector<std::vector<MinidumpCrashpadInfo::AnnotationObject>>*
      annotation_objects_list =
          crashpad_info->GetModuleCrashpadInfoAnnotationObjects();
  ASSERT_EQ(2U, annotation_objects_list->size());

  std::vector<MinidumpCrashpadInfo::AnnotationObject> annotation_objects =
      annotation_objects_list->at(0);
  ASSERT_EQ(5U, annotation_objects.size());

  std::vector<std::string> annotation_names;
  for (size_t i = 0; i < annotation_objects.size(); i++) {
    MinidumpCrashpadInfo::AnnotationObject annotation_object =
        annotation_objects.at(i);
    annotation_names.push_back(annotation_object.name);
    ASSERT_TRUE(annotation_object.type > 0);
    ASSERT_TRUE(annotation_object.value.size() > 0);
  }

  std::vector<std::string> expected_strings{
      "exceptionReason", "exceptionName", "firstexception_bt", "firstexception",
      "CounterAnnotation"};
  ASSERT_EQ(annotation_names, expected_strings);
}

TEST(Dump, ReadBackEmpty) {
  Dump dump(0);
  dump.Finish();
  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream stream(contents);
  Minidump minidump(stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(0U, minidump.GetDirectoryEntryCount());
}

TEST(Dump, ReadBackEmptyBigEndian) {
  Dump big_minidump(0, kBigEndian);
  big_minidump.Finish();
  string contents;
  ASSERT_TRUE(big_minidump.GetContents(&contents));
  istringstream stream(contents);
  Minidump minidump(stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(0U, minidump.GetDirectoryEntryCount());
}

TEST(Dump, OneStream) {
  Dump dump(0, kBigEndian);
  Stream stream(dump, 0xfbb7fa2bU);
  stream.Append("stream contents");
  dump.Add(&stream);
  dump.Finish();
  
  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(0);
  ASSERT_TRUE(dir != NULL);
  EXPECT_EQ(0xfbb7fa2bU, dir->stream_type);

  uint32_t stream_length;
  ASSERT_TRUE(minidump.SeekToStreamType(0xfbb7fa2bU, &stream_length));
  ASSERT_EQ(15U, stream_length);
  char stream_contents[15];
  ASSERT_TRUE(minidump.ReadBytes(stream_contents, sizeof(stream_contents)));
  EXPECT_EQ(string("stream contents"),
            string(stream_contents, sizeof(stream_contents)));

  EXPECT_FALSE(minidump.GetThreadList());
  EXPECT_FALSE(minidump.GetModuleList());
  EXPECT_FALSE(minidump.GetMemoryList());
  EXPECT_FALSE(minidump.GetException());
  EXPECT_FALSE(minidump.GetAssertion());
  EXPECT_FALSE(minidump.GetSystemInfo());
  EXPECT_FALSE(minidump.GetMiscInfo());
  EXPECT_FALSE(minidump.GetBreakpadInfo());
}

TEST(Dump, OneMemory) {
  Dump dump(0, kBigEndian);
  Memory memory(dump, 0x309d68010bd21b2cULL);
  memory.Append("memory contents");
  dump.Add(&memory);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(0);
  ASSERT_TRUE(dir != NULL);
  EXPECT_EQ((uint32_t) MD_MEMORY_LIST_STREAM, dir->stream_type);

  MinidumpMemoryList* memory_list = minidump.GetMemoryList();
  ASSERT_TRUE(memory_list != NULL);
  ASSERT_EQ(1U, memory_list->region_count());

  MinidumpMemoryRegion* region1 = memory_list->GetMemoryRegionAtIndex(0);
  ASSERT_EQ(0x309d68010bd21b2cULL, region1->GetBase());
  ASSERT_EQ(15U, region1->GetSize());
  const uint8_t* region1_bytes = region1->GetMemory();
  ASSERT_TRUE(memcmp("memory contents", region1_bytes, 15) == 0);
}

// One thread --- and its requisite entourage.
TEST(Dump, OneThread) {
  Dump dump(0, kLittleEndian);
  Memory stack(dump, 0x2326a0fa);
  stack.Append("stack for thread");

  MDRawContextX86 raw_context;
  const uint32_t kExpectedEIP = 0x6913f540;
  raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL;
  raw_context.edi = 0x3ecba80d;
  raw_context.esi = 0x382583b9;
  raw_context.ebx = 0x7fccc03f;
  raw_context.edx = 0xf62f8ec2;
  raw_context.ecx = 0x46a6a6a8;
  raw_context.eax = 0x6a5025e2;
  raw_context.ebp = 0xd9fabb4a;
  raw_context.eip = kExpectedEIP;
  raw_context.cs = 0xbffe6eda;
  raw_context.eflags = 0xb2ce1e2d;
  raw_context.esp = 0x659caaa4;
  raw_context.ss = 0x2e951ef7;
  Context context(dump, raw_context);
  
  Thread thread(dump, 0xa898f11b, stack, context,
                0x9e39439f, 0x4abfc15f, 0xe499898a, 0x0d43e939dcfd0372ULL);
  
  dump.Add(&stack);
  dump.Add(&context);
  dump.Add(&thread);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());

  MinidumpMemoryList* md_memory_list = minidump.GetMemoryList();
  ASSERT_TRUE(md_memory_list != NULL);
  ASSERT_EQ(1U, md_memory_list->region_count());

  MinidumpMemoryRegion* md_region = md_memory_list->GetMemoryRegionAtIndex(0);
  ASSERT_EQ(0x2326a0faU, md_region->GetBase());
  ASSERT_EQ(16U, md_region->GetSize());
  const uint8_t* region_bytes = md_region->GetMemory();
  ASSERT_TRUE(memcmp("stack for thread", region_bytes, 16) == 0);

  MinidumpThreadList* thread_list = minidump.GetThreadList();
  ASSERT_TRUE(thread_list != NULL);
  ASSERT_EQ(1U, thread_list->thread_count());

  MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0);
  ASSERT_TRUE(md_thread != NULL);
  uint32_t thread_id;
  ASSERT_TRUE(md_thread->GetThreadID(&thread_id));
  ASSERT_EQ(0xa898f11bU, thread_id);
  MinidumpMemoryRegion* md_stack = md_thread->GetMemory();
  ASSERT_TRUE(md_stack != NULL);
  ASSERT_EQ(0x2326a0faU, md_stack->GetBase());
  ASSERT_EQ(16U, md_stack->GetSize());
  const uint8_t* md_stack_bytes = md_stack->GetMemory();
  ASSERT_TRUE(memcmp("stack for thread", md_stack_bytes, 16) == 0);

  MinidumpContext* md_context = md_thread->GetContext();
  ASSERT_TRUE(md_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());

  uint64_t eip;
  ASSERT_TRUE(md_context->GetInstructionPointer(&eip));
  EXPECT_EQ(kExpectedEIP, eip);

  const MDRawContextX86* md_raw_context = md_context->GetContextX86();
  ASSERT_TRUE(md_raw_context != NULL);
  ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
            (md_raw_context->context_flags
             & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
  EXPECT_EQ(0x3ecba80dU, raw_context.edi);
  EXPECT_EQ(0x382583b9U, raw_context.esi);
  EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
  EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
  EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
  EXPECT_EQ(0x6a5025e2U, raw_context.eax);
  EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
  EXPECT_EQ(kExpectedEIP, raw_context.eip);
  EXPECT_EQ(0xbffe6edaU, raw_context.cs);
  EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
  EXPECT_EQ(0x659caaa4U, raw_context.esp);
  EXPECT_EQ(0x2e951ef7U, raw_context.ss);
}

TEST(Dump, ThreadMissingMemory) {
  Dump dump(0, kLittleEndian);
  Memory stack(dump, 0x2326a0fa);
  // Stack has no contents.

  MDRawContextX86 raw_context;
  memset(&raw_context, 0, sizeof(raw_context));
  raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL;
  Context context(dump, raw_context);

  Thread thread(dump, 0xa898f11b, stack, context,
                0x9e39439f, 0x4abfc15f, 0xe499898a, 0x0d43e939dcfd0372ULL);

  dump.Add(&stack);
  dump.Add(&context);
  dump.Add(&thread);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());

  // This should succeed even though the thread has no stack memory.
  MinidumpThreadList* thread_list = minidump.GetThreadList();
  ASSERT_TRUE(thread_list != NULL);
  ASSERT_EQ(1U, thread_list->thread_count());

  MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0);
  ASSERT_TRUE(md_thread != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_thread->GetThreadID(&thread_id));
  ASSERT_EQ(0xa898f11bU, thread_id);

  MinidumpContext* md_context = md_thread->GetContext();
  ASSERT_NE(reinterpret_cast<MinidumpContext*>(NULL), md_context);

  MinidumpMemoryRegion* md_stack = md_thread->GetMemory();
  ASSERT_EQ(reinterpret_cast<MinidumpMemoryRegion*>(NULL), md_stack);
}

TEST(Dump, ThreadMissingContext) {
  Dump dump(0, kLittleEndian);
  Memory stack(dump, 0x2326a0fa);
  stack.Append("stack for thread");

  // Context is empty.
  Context context(dump);

  Thread thread(dump, 0xa898f11b, stack, context,
                0x9e39439f, 0x4abfc15f, 0xe499898a, 0x0d43e939dcfd0372ULL);

  dump.Add(&stack);
  dump.Add(&context);
  dump.Add(&thread);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());

  // This should succeed even though the thread has no stack memory.
  MinidumpThreadList* thread_list = minidump.GetThreadList();
  ASSERT_TRUE(thread_list != NULL);
  ASSERT_EQ(1U, thread_list->thread_count());

  MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0);
  ASSERT_TRUE(md_thread != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_thread->GetThreadID(&thread_id));
  ASSERT_EQ(0xa898f11bU, thread_id);
  MinidumpMemoryRegion* md_stack = md_thread->GetMemory();
  ASSERT_NE(reinterpret_cast<MinidumpMemoryRegion*>(NULL), md_stack);

  MinidumpContext* md_context = md_thread->GetContext();
  ASSERT_EQ(reinterpret_cast<MinidumpContext*>(NULL), md_context);
}

TEST(Dump, OneUnloadedModule) {
  Dump dump(0, kBigEndian);
  String module_name(dump, "unloaded module");

  String csd_version(dump, "Windows 9000");
  SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);

  UnloadedModule unloaded_module(
      dump,
      0xa90206ca83eb2852ULL,
      0xada542bd,
      module_name,
      0x34571371,
      0xb1054d2a);

  dump.Add(&unloaded_module);
  dump.Add(&module_name);
  dump.Add(&system_info);
  dump.Add(&csd_version);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());

  const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(1);
  ASSERT_TRUE(dir != NULL);
  EXPECT_EQ((uint32_t) MD_UNLOADED_MODULE_LIST_STREAM, dir->stream_type);

  MinidumpUnloadedModuleList* md_unloaded_module_list =
      minidump.GetUnloadedModuleList();
  ASSERT_TRUE(md_unloaded_module_list != NULL);
  ASSERT_EQ(1U, md_unloaded_module_list->module_count());

  const MinidumpUnloadedModule* md_unloaded_module =
      md_unloaded_module_list->GetModuleAtIndex(0);
  ASSERT_TRUE(md_unloaded_module != NULL);
  ASSERT_EQ(0xa90206ca83eb2852ULL, md_unloaded_module->base_address());
  ASSERT_EQ(0xada542bd, md_unloaded_module->size());
  ASSERT_EQ("unloaded module", md_unloaded_module->code_file());
  ASSERT_EQ("", md_unloaded_module->debug_file());
  // time_date_stamp and size_of_image concatenated
  ASSERT_EQ("B1054D2Aada542bd", md_unloaded_module->code_identifier());
  ASSERT_EQ("", md_unloaded_module->debug_identifier());

  const MDRawUnloadedModule* md_raw_unloaded_module =
      md_unloaded_module->module();
  ASSERT_TRUE(md_raw_unloaded_module != NULL);
  ASSERT_EQ(0xb1054d2aU, md_raw_unloaded_module->time_date_stamp);
  ASSERT_EQ(0x34571371U, md_raw_unloaded_module->checksum);
}

static const MDVSFixedFileInfo fixed_file_info = {
  0xb2fba33a,                           // signature
  0x33d7a728,                           // struct_version
  0x31afcb20,                           // file_version_hi
  0xe51cdab1,                           // file_version_lo
  0xd1ea6907,                           // product_version_hi
  0x03032857,                           // product_version_lo
  0x11bf71d7,                           // file_flags_mask
  0x5fb8cdbf,                           // file_flags
  0xe45d0d5d,                           // file_os
  0x107d9562,                           // file_type
  0x5a8844d4,                           // file_subtype
  0xa8d30b20,                           // file_date_hi
  0x651c3e4e                            // file_date_lo
};

TEST(Dump, OneModule) {
  Dump dump(0, kBigEndian);
  String module_name(dump, "single module");
  Section cv_info(dump);
  cv_info
    .D32(MD_CVINFOPDB70_SIGNATURE)  // signature
    // signature, a MDGUID
    .D32(0xabcd1234)
    .D16(0xf00d)
    .D16(0xbeef)
    .Append("\x01\x02\x03\x04\x05\x06\x07\x08")
    .D32(1) // age
    .AppendCString("c:\\foo\\file.pdb");  // pdb_file_name

  String csd_version(dump, "Windows 9000");
  SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);

  Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd,
                module_name,
                0xb1054d2a,
                0x34571371,
                fixed_file_info, // from synth_minidump_unittest_data.h
                &cv_info, nullptr);

  dump.Add(&module);
  dump.Add(&module_name);
  dump.Add(&cv_info);
  dump.Add(&system_info);
  dump.Add(&csd_version);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());

  const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(1);
  ASSERT_TRUE(dir != NULL);
  EXPECT_EQ((uint32_t) MD_MODULE_LIST_STREAM, dir->stream_type);

  MinidumpModuleList* md_module_list = minidump.GetModuleList();
  ASSERT_TRUE(md_module_list != NULL);
  ASSERT_EQ(1U, md_module_list->module_count());

  const MinidumpModule* md_module = md_module_list->GetModuleAtIndex(0);
  ASSERT_TRUE(md_module != NULL);
  ASSERT_EQ(0xa90206ca83eb2852ULL, md_module->base_address());
  ASSERT_EQ(0xada542bd, md_module->size());
  ASSERT_EQ("single module", md_module->code_file());
  ASSERT_EQ("c:\\foo\\file.pdb", md_module->debug_file());
  // time_date_stamp and size_of_image concatenated
  ASSERT_EQ("B1054D2Aada542bd", md_module->code_identifier());
  ASSERT_EQ("ABCD1234F00DBEEF01020304050607081", md_module->debug_identifier());

  const MDRawModule* md_raw_module = md_module->module();
  ASSERT_TRUE(md_raw_module != NULL);
  ASSERT_EQ(0xb1054d2aU, md_raw_module->time_date_stamp);
  ASSERT_EQ(0x34571371U, md_raw_module->checksum);
  ASSERT_TRUE(memcmp(&md_raw_module->version_info, &fixed_file_info,
                     sizeof(fixed_file_info)) == 0);
}

// Test that a module with a MDCVInfoELF CV record is handled properly.
TEST(Dump, OneModuleCVELF) {
  Dump dump(0, kLittleEndian);
  String module_name(dump, "elf module");
  Section cv_info(dump);
  cv_info
    .D32(MD_CVINFOELF_SIGNATURE)  // signature
    // build_id
    .Append("\x5f\xa9\xcd\xb4\x10\x53\xdf\x1b\x86\xfa\xb7\x33\xb4\xdf"
            "\x37\x38\xce\xa3\x4a\x87");

  const MDRawSystemInfo linux_x86 = {
    MD_CPU_ARCHITECTURE_X86,              // processor_architecture
    6,                                    // processor_level
    0xd08,                                // processor_revision
    1,                                    // number_of_processors
    0,                                    // product_type
    0,                                    // major_version
    0,                                    // minor_version
    0,                                    // build_number
    MD_OS_LINUX,                          // platform_id
    0xdeadbeef,                           // csd_version_rva
    0x100,                                // suite_mask
    0,                                    // reserved2
    {                                     // cpu
      { // x86_cpu_info
        { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id
        0x6d8,                                  // version_information
        0xafe9fbff,                             // feature_information
        0xffffffff                              // amd_extended_cpu_features
      }
    }
  };
  String csd_version(dump, "Literally Linux");
  SystemInfo system_info(dump, linux_x86, csd_version);

  Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd,
                module_name,
                0xb1054d2a,
                0x34571371,
                fixed_file_info, // from synth_minidump_unittest_data.h
                &cv_info, nullptr);

  dump.Add(&module);
  dump.Add(&module_name);
  dump.Add(&cv_info);
  dump.Add(&system_info);
  dump.Add(&csd_version);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());

  MinidumpModuleList* md_module_list = minidump.GetModuleList();
  ASSERT_TRUE(md_module_list != NULL);
  ASSERT_EQ(1U, md_module_list->module_count());

  const MinidumpModule* md_module = md_module_list->GetModuleAtIndex(0);
  ASSERT_TRUE(md_module != NULL);
  ASSERT_EQ(0xa90206ca83eb2852ULL, md_module->base_address());
  ASSERT_EQ(0xada542bd, md_module->size());
  ASSERT_EQ("elf module", md_module->code_file());
  // debug_file == code_file
  ASSERT_EQ("elf module", md_module->debug_file());
  // just the build_id, directly
  ASSERT_EQ("5fa9cdb41053df1b86fab733b4df3738cea34a87",
            md_module->code_identifier());
  // build_id truncted to GUID length and treated as such, with zero
  // age appended
  ASSERT_EQ("B4CDA95F53101BDF86FAB733B4DF37380", md_module->debug_identifier());

  const MDRawModule* md_raw_module = md_module->module();
  ASSERT_TRUE(md_raw_module != NULL);
  ASSERT_EQ(0xb1054d2aU, md_raw_module->time_date_stamp);
  ASSERT_EQ(0x34571371U, md_raw_module->checksum);
  ASSERT_TRUE(memcmp(&md_raw_module->version_info, &fixed_file_info,
                     sizeof(fixed_file_info)) == 0);
}

// Test that a build_id that's shorter than a GUID is handled properly.
TEST(Dump, CVELFShort) {
  Dump dump(0, kLittleEndian);
  String module_name(dump, "elf module");
  Section cv_info(dump);
  cv_info
    .D32(MD_CVINFOELF_SIGNATURE)  // signature
    // build_id, shorter than a GUID
    .Append("\x5f\xa9\xcd\xb4");

  const MDRawSystemInfo linux_x86 = {
    MD_CPU_ARCHITECTURE_X86,              // processor_architecture
    6,                                    // processor_level
    0xd08,                                // processor_revision
    1,                                    // number_of_processors
    0,                                    // product_type
    0,                                    // major_version
    0,                                    // minor_version
    0,                                    // build_number
    MD_OS_LINUX,                          // platform_id
    0xdeadbeef,                           // csd_version_rva
    0x100,                                // suite_mask
    0,                                    // reserved2
    {                                     // cpu
      { // x86_cpu_info
        { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id
        0x6d8,                                  // version_information
        0xafe9fbff,                             // feature_information
        0xffffffff                              // amd_extended_cpu_features
      }
    }
  };
  String csd_version(dump, "Literally Linux");
  SystemInfo system_info(dump, linux_x86, csd_version);

  Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd,
                module_name,
                0xb1054d2a,
                0x34571371,
                fixed_file_info, // from synth_minidump_unittest_data.h
                &cv_info, nullptr);

  dump.Add(&module);
  dump.Add(&module_name);
  dump.Add(&cv_info);
  dump.Add(&system_info);
  dump.Add(&csd_version);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());

  MinidumpModuleList* md_module_list = minidump.GetModuleList();
  ASSERT_TRUE(md_module_list != NULL);
  ASSERT_EQ(1U, md_module_list->module_count());

  const MinidumpModule* md_module = md_module_list->GetModuleAtIndex(0);
  ASSERT_TRUE(md_module != NULL);
  // just the build_id, directly
  ASSERT_EQ("5fa9cdb4", md_module->code_identifier());
  // build_id expanded to GUID length and treated as such, with zero
  // age appended
  ASSERT_EQ("B4CDA95F0000000000000000000000000", md_module->debug_identifier());
}

// Test that a build_id that's very long is handled properly.
TEST(Dump, CVELFLong) {
  Dump dump(0, kLittleEndian);
  String module_name(dump, "elf module");
  Section cv_info(dump);
  cv_info
    .D32(MD_CVINFOELF_SIGNATURE)  // signature
    // build_id, lots of bytes
    .Append("\x5f\xa9\xcd\xb4\x10\x53\xdf\x1b\x86\xfa\xb7\x33\xb4\xdf"
            "\x37\x38\xce\xa3\x4a\x87\x01\x02\x03\x04\x05\x06\x07\x08"
            "\x09\x0a\x0b\x0c\x0d\x0e\x0f");


  const MDRawSystemInfo linux_x86 = {
    MD_CPU_ARCHITECTURE_X86,              // processor_architecture
    6,                                    // processor_level
    0xd08,                                // processor_revision
    1,                                    // number_of_processors
    0,                                    // product_type
    0,                                    // major_version
    0,                                    // minor_version
    0,                                    // build_number
    MD_OS_LINUX,                          // platform_id
    0xdeadbeef,                           // csd_version_rva
    0x100,                                // suite_mask
    0,                                    // reserved2
    {                                     // cpu
      { // x86_cpu_info
        { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id
        0x6d8,                                  // version_information
        0xafe9fbff,                             // feature_information
        0xffffffff                              // amd_extended_cpu_features
      }
    }
  };
  String csd_version(dump, "Literally Linux");
  SystemInfo system_info(dump, linux_x86, csd_version);

  Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd,
                module_name,
                0xb1054d2a,
                0x34571371,
                fixed_file_info, // from synth_minidump_unittest_data.h
                &cv_info, nullptr);

  dump.Add(&module);
  dump.Add(&module_name);
  dump.Add(&cv_info);
  dump.Add(&system_info);
  dump.Add(&csd_version);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());

  MinidumpModuleList* md_module_list = minidump.GetModuleList();
  ASSERT_TRUE(md_module_list != NULL);
  ASSERT_EQ(1U, md_module_list->module_count());

  const MinidumpModule* md_module = md_module_list->GetModuleAtIndex(0);
  ASSERT_TRUE(md_module != NULL);
  // just the build_id, directly
  ASSERT_EQ(
      "5fa9cdb41053df1b86fab733b4df3738cea34a870102030405060708090a0b0c0d0e0f",
      md_module->code_identifier());
  // build_id truncated to GUID length and treated as such, with zero
  // age appended.
  ASSERT_EQ("B4CDA95F53101BDF86FAB733B4DF37380", md_module->debug_identifier());
}

TEST(Dump, OneSystemInfo) {
  Dump dump(0, kLittleEndian);
  String csd_version(dump, "Petulant Pierogi");
  SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);

  dump.Add(&system_info);
  dump.Add(&csd_version);
  dump.Finish();
                         
  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(0);
  ASSERT_TRUE(dir != NULL);
  EXPECT_EQ((uint32_t) MD_SYSTEM_INFO_STREAM, dir->stream_type);

  MinidumpSystemInfo* md_system_info = minidump.GetSystemInfo();
  ASSERT_TRUE(md_system_info != NULL);
  ASSERT_EQ("windows", md_system_info->GetOS());
  ASSERT_EQ("x86", md_system_info->GetCPU());
  ASSERT_EQ("Petulant Pierogi", *md_system_info->GetCSDVersion());
  ASSERT_EQ("GenuineIntel", *md_system_info->GetCPUVendor());
}

TEST(Dump, BigDump) {
  Dump dump(0, kLittleEndian);

  // A SystemInfo stream.
  String csd_version(dump, "Munificent Macaque");
  SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);
  dump.Add(&csd_version);
  dump.Add(&system_info);

  // Five threads!
  Memory stack0(dump, 0x70b9ebfc);
  stack0.Append("stack for thread zero");
  MDRawContextX86 raw_context0;
  raw_context0.context_flags = MD_CONTEXT_X86_INTEGER;
  raw_context0.eip = 0xaf0709e4;
  Context context0(dump, raw_context0);
  Thread thread0(dump, 0xbbef4432, stack0, context0,
                 0xd0377e7b, 0xdb8eb0cf, 0xd73bc314, 0x09d357bac7f9a163ULL);
  dump.Add(&stack0);
  dump.Add(&context0);
  dump.Add(&thread0);

  Memory stack1(dump, 0xf988cc45);
  stack1.Append("stack for thread one");
  MDRawContextX86 raw_context1;
  raw_context1.context_flags = MD_CONTEXT_X86_INTEGER;
  raw_context1.eip = 0xe4f56f81;
  Context context1(dump, raw_context1);
  Thread thread1(dump, 0x657c3f58, stack1, context1,
                 0xa68fa182, 0x6f3cf8dd, 0xe3a78ccf, 0x78cc84775e4534bbULL);
  dump.Add(&stack1);
  dump.Add(&context1);
  dump.Add(&thread1);

  Memory stack2(dump, 0xc8a92e7c);
  stack2.Append("stack for thread two");
  MDRawContextX86 raw_context2;
  raw_context2.context_flags = MD_CONTEXT_X86_INTEGER;
  raw_context2.eip = 0xb336a438;
  Context context2(dump, raw_context2);
  Thread thread2(dump, 0xdf4b8a71, stack2, context2,
                 0x674c26b6, 0x445d7120, 0x7e700c56, 0xd89bf778e7793e17ULL);
  dump.Add(&stack2);
  dump.Add(&context2);
  dump.Add(&thread2);

  Memory stack3(dump, 0x36d08e08);
  stack3.Append("stack for thread three");
  MDRawContextX86 raw_context3;
  raw_context3.context_flags = MD_CONTEXT_X86_INTEGER;
  raw_context3.eip = 0xdf99a60c;
  Context context3(dump, raw_context3);
  Thread thread3(dump, 0x86e6c341, stack3, context3,
                 0x32dc5c55, 0x17a2aba8, 0xe0cc75e7, 0xa46393994dae83aeULL);
  dump.Add(&stack3);
  dump.Add(&context3);
  dump.Add(&thread3);

  Memory stack4(dump, 0x1e0ab4fa);
  stack4.Append("stack for thread four");
  MDRawContextX86 raw_context4;
  raw_context4.context_flags = MD_CONTEXT_X86_INTEGER;
  raw_context4.eip = 0xaa646267;
  Context context4(dump, raw_context4);
  Thread thread4(dump, 0x261a28d4, stack4, context4,
                 0x6ebd389e, 0xa0cd4759, 0x30168846, 0x164f650a0cf39d35ULL);
  dump.Add(&stack4);
  dump.Add(&context4);
  dump.Add(&thread4);

  // Three modules!
  String module1_name(dump, "module one");
  Module module1(dump, 0xeb77da57b5d4cbdaULL, 0x83cd5a37, module1_name);
  dump.Add(&module1_name);
  dump.Add(&module1);

  String module2_name(dump, "module two");
  Module module2(dump, 0x8675884adfe5ac90ULL, 0xb11e4ea3, module2_name);
  dump.Add(&module2_name);
  dump.Add(&module2);

  String module3_name(dump, "module three");
  Module module3(dump, 0x95fc1544da321b6cULL, 0x7c2bf081, module3_name);
  dump.Add(&module3_name);
  dump.Add(&module3);

  // Unloaded modules!
  uint64_t umodule1_base = 0xeb77da57b5d4cbdaULL;
  uint32_t umodule1_size = 0x83cd5a37;
  String umodule1_name(dump, "unloaded module one");
  UnloadedModule unloaded_module1(dump, umodule1_base, umodule1_size,
                                  umodule1_name);
  dump.Add(&umodule1_name);
  dump.Add(&unloaded_module1);

  uint64_t umodule2_base = 0xeb77da57b5d4cbdaULL;
  uint32_t umodule2_size = 0x83cd5a37;
  String umodule2_name(dump, "unloaded module two");
  UnloadedModule unloaded_module2(dump, umodule2_base, umodule2_size,
                                  umodule2_name);
  dump.Add(&umodule2_name);
  dump.Add(&unloaded_module2);

  uint64_t umodule3_base = 0xeb77da5839a20000ULL;
  uint32_t umodule3_size = 0x83cd5a37;
  String umodule3_name(dump, "unloaded module three");
  UnloadedModule unloaded_module3(dump, umodule3_base, umodule3_size,
                                  umodule3_name);
  dump.Add(&umodule3_name);
  dump.Add(&unloaded_module3);


  // Add one more memory region, on top of the five stacks.
  Memory memory5(dump, 0x61979e828040e564ULL);
  memory5.Append("contents of memory 5");
  dump.Add(&memory5);

  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(5U, minidump.GetDirectoryEntryCount());

  // Check the threads.
  MinidumpThreadList* thread_list = minidump.GetThreadList();
  ASSERT_TRUE(thread_list != NULL);
  ASSERT_EQ(5U, thread_list->thread_count());
  uint32_t thread_id;
  ASSERT_TRUE(thread_list->GetThreadAtIndex(0)->GetThreadID(&thread_id));
  ASSERT_EQ(0xbbef4432U, thread_id);
  ASSERT_EQ(0x70b9ebfcU,
            thread_list->GetThreadAtIndex(0)->GetMemory()->GetBase());
  ASSERT_EQ(0xaf0709e4U,
            thread_list->GetThreadAtIndex(0)->GetContext()->GetContextX86()
            ->eip);

  ASSERT_TRUE(thread_list->GetThreadAtIndex(1)->GetThreadID(&thread_id));
  ASSERT_EQ(0x657c3f58U, thread_id);
  ASSERT_EQ(0xf988cc45U,
            thread_list->GetThreadAtIndex(1)->GetMemory()->GetBase());
  ASSERT_EQ(0xe4f56f81U,
            thread_list->GetThreadAtIndex(1)->GetContext()->GetContextX86()
            ->eip);

  ASSERT_TRUE(thread_list->GetThreadAtIndex(2)->GetThreadID(&thread_id));
  ASSERT_EQ(0xdf4b8a71U, thread_id);
  ASSERT_EQ(0xc8a92e7cU,
            thread_list->GetThreadAtIndex(2)->GetMemory()->GetBase());
  ASSERT_EQ(0xb336a438U,
            thread_list->GetThreadAtIndex(2)->GetContext()->GetContextX86()
            ->eip);

  ASSERT_TRUE(thread_list->GetThreadAtIndex(3)->GetThreadID(&thread_id));
  ASSERT_EQ(0x86e6c341U, thread_id);
  ASSERT_EQ(0x36d08e08U,
            thread_list->GetThreadAtIndex(3)->GetMemory()->GetBase());
  ASSERT_EQ(0xdf99a60cU,
            thread_list->GetThreadAtIndex(3)->GetContext()->GetContextX86()
            ->eip);

  ASSERT_TRUE(thread_list->GetThreadAtIndex(4)->GetThreadID(&thread_id));
  ASSERT_EQ(0x261a28d4U, thread_id);
  ASSERT_EQ(0x1e0ab4faU,
            thread_list->GetThreadAtIndex(4)->GetMemory()->GetBase());
  ASSERT_EQ(0xaa646267U,
            thread_list->GetThreadAtIndex(4)->GetContext()->GetContextX86()
            ->eip);

  // Check the modules.
  MinidumpModuleList* md_module_list = minidump.GetModuleList();
  ASSERT_TRUE(md_module_list != NULL);
  ASSERT_EQ(3U, md_module_list->module_count());
  EXPECT_EQ(0xeb77da57b5d4cbdaULL,
            md_module_list->GetModuleAtIndex(0)->base_address());
  EXPECT_EQ(0x8675884adfe5ac90ULL,
            md_module_list->GetModuleAtIndex(1)->base_address());
  EXPECT_EQ(0x95fc1544da321b6cULL,
            md_module_list->GetModuleAtIndex(2)->base_address());

  // Check unloaded modules
  MinidumpUnloadedModuleList* md_unloaded_module_list =
      minidump.GetUnloadedModuleList();
  ASSERT_TRUE(md_unloaded_module_list != NULL);
  ASSERT_EQ(3U, md_unloaded_module_list->module_count());
  EXPECT_EQ(umodule1_base,
            md_unloaded_module_list->GetModuleAtIndex(0)->base_address());
  EXPECT_EQ(umodule2_base,
            md_unloaded_module_list->GetModuleAtIndex(1)->base_address());
  EXPECT_EQ(umodule3_base,
            md_unloaded_module_list->GetModuleAtIndex(2)->base_address());

  const MinidumpUnloadedModule* umodule =
      md_unloaded_module_list->GetModuleForAddress(
          umodule1_base + umodule1_size / 2);
  EXPECT_EQ(umodule1_base, umodule->base_address());

  umodule = md_unloaded_module_list->GetModuleAtSequence(0);
  EXPECT_EQ(umodule1_base, umodule->base_address());

  EXPECT_EQ(NULL, md_unloaded_module_list->GetMainModule());

}

TEST(Dump, OneMemoryInfo) {
  Dump dump(0, kBigEndian);
  Stream stream(dump, MD_MEMORY_INFO_LIST_STREAM);

  // Add the MDRawMemoryInfoList header.
  const uint64_t kNumberOfEntries = 1;
  stream.D32(sizeof(MDRawMemoryInfoList))  // size_of_header
        .D32(sizeof(MDRawMemoryInfo))      // size_of_entry
        .D64(kNumberOfEntries);            // number_of_entries

  
  // Now add a MDRawMemoryInfo entry.
  const uint64_t kBaseAddress = 0x1000;
  const uint64_t kRegionSize = 0x2000;
  stream.D64(kBaseAddress)                         // base_address
        .D64(kBaseAddress)                         // allocation_base
        .D32(MD_MEMORY_PROTECT_EXECUTE_READWRITE)  // allocation_protection
        .D32(0)                                    // __alignment1
        .D64(kRegionSize)                          // region_size
        .D32(MD_MEMORY_STATE_COMMIT)               // state
        .D32(MD_MEMORY_PROTECT_EXECUTE_READWRITE)  // protection
        .D32(MD_MEMORY_TYPE_PRIVATE)               // type
        .D32(0);                                   // __alignment2

  dump.Add(&stream);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));
  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  const MDRawDirectory* dir = minidump.GetDirectoryEntryAtIndex(0);
  ASSERT_TRUE(dir != NULL);
  EXPECT_EQ((uint32_t) MD_MEMORY_INFO_LIST_STREAM, dir->stream_type);

  MinidumpMemoryInfoList* info_list = minidump.GetMemoryInfoList();
  ASSERT_TRUE(info_list != NULL);
  ASSERT_EQ(1U, info_list->info_count());

  const MinidumpMemoryInfo* info1 = info_list->GetMemoryInfoAtIndex(0);
  ASSERT_EQ(kBaseAddress, info1->GetBase());
  ASSERT_EQ(kRegionSize, info1->GetSize());
  ASSERT_TRUE(info1->IsExecutable());
  ASSERT_TRUE(info1->IsWritable());

  // Should get back the same memory region here.
  const MinidumpMemoryInfo* info2 =
      info_list->GetMemoryInfoForAddress(kBaseAddress + kRegionSize / 2);
  ASSERT_EQ(kBaseAddress, info2->GetBase());
  ASSERT_EQ(kRegionSize, info2->GetSize());
}

TEST(Dump, OneExceptionX86) {
  Dump dump(0, kLittleEndian);

  MDRawContextX86 raw_context;
  raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL;
  raw_context.edi = 0x3ecba80d;
  raw_context.esi = 0x382583b9;
  raw_context.ebx = 0x7fccc03f;
  raw_context.edx = 0xf62f8ec2;
  raw_context.ecx = 0x46a6a6a8;
  raw_context.eax = 0x6a5025e2;
  raw_context.ebp = 0xd9fabb4a;
  raw_context.eip = 0x6913f540;
  raw_context.cs = 0xbffe6eda;
  raw_context.eflags = 0xb2ce1e2d;
  raw_context.esp = 0x659caaa4;
  raw_context.ss = 0x2e951ef7;
  Context context(dump, raw_context);

  Exception exception(dump, context,
                      0x1234abcd, // thread id
                      0xdcba4321, // exception code
                      0xf0e0d0c0, // exception flags
                      0x0919a9b9c9d9e9f9ULL); // exception address
  
  dump.Add(&context);
  dump.Add(&exception);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  MinidumpException* md_exception = minidump.GetException();
  ASSERT_TRUE(md_exception != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
  ASSERT_EQ(0x1234abcdU, thread_id);

  const MDRawExceptionStream* raw_exception = md_exception->exception();
  ASSERT_TRUE(raw_exception != NULL);
  EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
  EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
  EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
            raw_exception->exception_record.exception_address);

  MinidumpContext* md_context = md_exception->GetContext();
  ASSERT_TRUE(md_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
  const MDRawContextX86* md_raw_context = md_context->GetContextX86();
  ASSERT_TRUE(md_raw_context != NULL);
  ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
            (md_raw_context->context_flags
             & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
  EXPECT_EQ(0x3ecba80dU, raw_context.edi);
  EXPECT_EQ(0x382583b9U, raw_context.esi);
  EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
  EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
  EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
  EXPECT_EQ(0x6a5025e2U, raw_context.eax);
  EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
  EXPECT_EQ(0x6913f540U, raw_context.eip);
  EXPECT_EQ(0xbffe6edaU, raw_context.cs);
  EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
  EXPECT_EQ(0x659caaa4U, raw_context.esp);
  EXPECT_EQ(0x2e951ef7U, raw_context.ss);
}

TEST(Dump, OneExceptionX86XState) {
  Dump dump(0, kLittleEndian);

  MDRawContextX86 raw_context;
  raw_context.context_flags = MD_CONTEXT_X86_INTEGER |
    MD_CONTEXT_X86_CONTROL | MD_CONTEXT_X86_XSTATE;
  raw_context.edi = 0x3ecba80d;
  raw_context.esi = 0x382583b9;
  raw_context.ebx = 0x7fccc03f;
  raw_context.edx = 0xf62f8ec2;
  raw_context.ecx = 0x46a6a6a8;
  raw_context.eax = 0x6a5025e2;
  raw_context.ebp = 0xd9fabb4a;
  raw_context.eip = 0x6913f540;
  raw_context.cs = 0xbffe6eda;
  raw_context.eflags = 0xb2ce1e2d;
  raw_context.esp = 0x659caaa4;
  raw_context.ss = 0x2e951ef7;
  Context context(dump, raw_context);

  Exception exception(dump, context,
                      0x1234abcd, // thread id
                      0xdcba4321, // exception code
                      0xf0e0d0c0, // exception flags
                      0x0919a9b9c9d9e9f9ULL); // exception address
  
  dump.Add(&context);
  dump.Add(&exception);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  MinidumpException* md_exception = minidump.GetException();
  ASSERT_TRUE(md_exception != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
  ASSERT_EQ(0x1234abcdU, thread_id);

  const MDRawExceptionStream* raw_exception = md_exception->exception();
  ASSERT_TRUE(raw_exception != NULL);
  EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
  EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
  EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
            raw_exception->exception_record.exception_address);

  MinidumpContext* md_context = md_exception->GetContext();
  ASSERT_TRUE(md_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
  const MDRawContextX86* md_raw_context = md_context->GetContextX86();
  ASSERT_TRUE(md_raw_context != NULL);
  ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
            (md_raw_context->context_flags
             & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
  EXPECT_EQ(0x3ecba80dU, raw_context.edi);
  EXPECT_EQ(0x382583b9U, raw_context.esi);
  EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
  EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
  EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
  EXPECT_EQ(0x6a5025e2U, raw_context.eax);
  EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
  EXPECT_EQ(0x6913f540U, raw_context.eip);
  EXPECT_EQ(0xbffe6edaU, raw_context.cs);
  EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
  EXPECT_EQ(0x659caaa4U, raw_context.esp);
  EXPECT_EQ(0x2e951ef7U, raw_context.ss);
}

// Testing that the CPU type can be loaded from a system info stream when
// the CPU flags are missing from the context_flags of an exception record
TEST(Dump, OneExceptionX86NoCPUFlags) {
  Dump dump(0, kLittleEndian);

  MDRawContextX86 raw_context;
  // Intentionally not setting CPU type in the context_flags
  raw_context.context_flags = 0;
  raw_context.edi = 0x3ecba80d;
  raw_context.esi = 0x382583b9;
  raw_context.ebx = 0x7fccc03f;
  raw_context.edx = 0xf62f8ec2;
  raw_context.ecx = 0x46a6a6a8;
  raw_context.eax = 0x6a5025e2;
  raw_context.ebp = 0xd9fabb4a;
  raw_context.eip = 0x6913f540;
  raw_context.cs = 0xbffe6eda;
  raw_context.eflags = 0xb2ce1e2d;
  raw_context.esp = 0x659caaa4;
  raw_context.ss = 0x2e951ef7;
  Context context(dump, raw_context);

  Exception exception(dump, context,
                      0x1234abcd, // thread id
                      0xdcba4321, // exception code
                      0xf0e0d0c0, // exception flags
                      0x0919a9b9c9d9e9f9ULL); // exception address
  
  dump.Add(&context);
  dump.Add(&exception);

  // Add system info.  This is needed as an alternative source for CPU type
  // information.  Note, that the CPU flags were intentionally skipped from
  // the context_flags and this alternative source is required.
  String csd_version(dump, "Service Pack 2");
  SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);
  dump.Add(&system_info);
  dump.Add(&csd_version);

  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());

  MinidumpException* md_exception = minidump.GetException();
  ASSERT_TRUE(md_exception != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
  ASSERT_EQ(0x1234abcdU, thread_id);

  const MDRawExceptionStream* raw_exception = md_exception->exception();
  ASSERT_TRUE(raw_exception != NULL);
  EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
  EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
  EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
            raw_exception->exception_record.exception_address);

  MinidumpContext* md_context = md_exception->GetContext();
  ASSERT_TRUE(md_context != NULL);

  ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
  const MDRawContextX86* md_raw_context = md_context->GetContextX86();
  ASSERT_TRUE(md_raw_context != NULL);

  // Even though the CPU flags were missing from the context_flags, the
  // GetContext call above is expected to load the missing CPU flags from the
  // system info stream and set the CPU type bits in context_flags.
  ASSERT_EQ((uint32_t) (MD_CONTEXT_X86), md_raw_context->context_flags);

  EXPECT_EQ(0x3ecba80dU, raw_context.edi);
  EXPECT_EQ(0x382583b9U, raw_context.esi);
  EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
  EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
  EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
  EXPECT_EQ(0x6a5025e2U, raw_context.eax);
  EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
  EXPECT_EQ(0x6913f540U, raw_context.eip);
  EXPECT_EQ(0xbffe6edaU, raw_context.cs);
  EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
  EXPECT_EQ(0x659caaa4U, raw_context.esp);
  EXPECT_EQ(0x2e951ef7U, raw_context.ss);
}

// This test covers a scenario where a dump contains an exception but the
// context record of the exception is missing the CPU type information in its
// context_flags.  The dump has no system info stream so it is imposible to
// deduce the CPU type, hence the context record is unusable.
TEST(Dump, OneExceptionX86NoCPUFlagsNoSystemInfo) {
  Dump dump(0, kLittleEndian);

  MDRawContextX86 raw_context;
  // Intentionally not setting CPU type in the context_flags
  raw_context.context_flags = 0;
  raw_context.edi = 0x3ecba80d;
  raw_context.esi = 0x382583b9;
  raw_context.ebx = 0x7fccc03f;
  raw_context.edx = 0xf62f8ec2;
  raw_context.ecx = 0x46a6a6a8;
  raw_context.eax = 0x6a5025e2;
  raw_context.ebp = 0xd9fabb4a;
  raw_context.eip = 0x6913f540;
  raw_context.cs = 0xbffe6eda;
  raw_context.eflags = 0xb2ce1e2d;
  raw_context.esp = 0x659caaa4;
  raw_context.ss = 0x2e951ef7;
  Context context(dump, raw_context);

  Exception exception(dump, context,
                      0x1234abcd, // thread id
                      0xdcba4321, // exception code
                      0xf0e0d0c0, // exception flags
                      0x0919a9b9c9d9e9f9ULL); // exception address
  
  dump.Add(&context);
  dump.Add(&exception);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  MinidumpException* md_exception = minidump.GetException();
  ASSERT_TRUE(md_exception != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
  ASSERT_EQ(0x1234abcdU, thread_id);

  const MDRawExceptionStream* raw_exception = md_exception->exception();
  ASSERT_TRUE(raw_exception != NULL);
  EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
  EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
  EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
            raw_exception->exception_record.exception_address);

  // The context record of the exception is unusable because the context_flags
  // don't have CPU type information and at the same time the minidump lacks
  // system info stream so it is impossible to deduce the CPU type.
  MinidumpContext* md_context = md_exception->GetContext();
  ASSERT_EQ(NULL, md_context);
}

TEST(Dump, OneExceptionARM) {
  Dump dump(0, kLittleEndian);

  MDRawContextARM raw_context;
  raw_context.context_flags = MD_CONTEXT_ARM_INTEGER;
  raw_context.iregs[0] = 0x3ecba80d;
  raw_context.iregs[1] = 0x382583b9;
  raw_context.iregs[2] = 0x7fccc03f;
  raw_context.iregs[3] = 0xf62f8ec2;
  raw_context.iregs[4] = 0x46a6a6a8;
  raw_context.iregs[5] = 0x6a5025e2;
  raw_context.iregs[6] = 0xd9fabb4a;
  raw_context.iregs[7] = 0x6913f540;
  raw_context.iregs[8] = 0xbffe6eda;
  raw_context.iregs[9] = 0xb2ce1e2d;
  raw_context.iregs[10] = 0x659caaa4;
  raw_context.iregs[11] = 0xf0e0d0c0;
  raw_context.iregs[12] = 0xa9b8c7d6;
  raw_context.iregs[13] = 0x12345678;
  raw_context.iregs[14] = 0xabcd1234;
  raw_context.iregs[15] = 0x10203040;
  raw_context.cpsr = 0x2e951ef7;
  Context context(dump, raw_context);

  Exception exception(dump, context,
                      0x1234abcd, // thread id
                      0xdcba4321, // exception code
                      0xf0e0d0c0, // exception flags
                      0x0919a9b9c9d9e9f9ULL); // exception address
  
  dump.Add(&context);
  dump.Add(&exception);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  MinidumpException* md_exception = minidump.GetException();
  ASSERT_TRUE(md_exception != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
  ASSERT_EQ(0x1234abcdU, thread_id);

  const MDRawExceptionStream* raw_exception = md_exception->exception();
  ASSERT_TRUE(raw_exception != NULL);
  EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
  EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
  EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
            raw_exception->exception_record.exception_address);

  MinidumpContext* md_context = md_exception->GetContext();
  ASSERT_TRUE(md_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_ARM, md_context->GetContextCPU());
  const MDRawContextARM* md_raw_context = md_context->GetContextARM();
  ASSERT_TRUE(md_raw_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_ARM_INTEGER,
            (md_raw_context->context_flags
             & MD_CONTEXT_ARM_INTEGER));
  EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]);
  EXPECT_EQ(0x382583b9U, raw_context.iregs[1]);
  EXPECT_EQ(0x7fccc03fU, raw_context.iregs[2]);
  EXPECT_EQ(0xf62f8ec2U, raw_context.iregs[3]);
  EXPECT_EQ(0x46a6a6a8U, raw_context.iregs[4]);
  EXPECT_EQ(0x6a5025e2U, raw_context.iregs[5]);
  EXPECT_EQ(0xd9fabb4aU, raw_context.iregs[6]);
  EXPECT_EQ(0x6913f540U, raw_context.iregs[7]);
  EXPECT_EQ(0xbffe6edaU, raw_context.iregs[8]);
  EXPECT_EQ(0xb2ce1e2dU, raw_context.iregs[9]);
  EXPECT_EQ(0x659caaa4U, raw_context.iregs[10]);
  EXPECT_EQ(0xf0e0d0c0U, raw_context.iregs[11]);
  EXPECT_EQ(0xa9b8c7d6U, raw_context.iregs[12]);
  EXPECT_EQ(0x12345678U, raw_context.iregs[13]);
  EXPECT_EQ(0xabcd1234U, raw_context.iregs[14]);
  EXPECT_EQ(0x10203040U, raw_context.iregs[15]);
  EXPECT_EQ(0x2e951ef7U, raw_context.cpsr);
}

TEST(Dump, OneExceptionARMOldFlags) {
  Dump dump(0, kLittleEndian);

  MDRawContextARM raw_context;
  // MD_CONTEXT_ARM_INTEGER, but with _OLD
  raw_context.context_flags = MD_CONTEXT_ARM_OLD | 0x00000002;
  raw_context.iregs[0] = 0x3ecba80d;
  raw_context.iregs[1] = 0x382583b9;
  raw_context.iregs[2] = 0x7fccc03f;
  raw_context.iregs[3] = 0xf62f8ec2;
  raw_context.iregs[4] = 0x46a6a6a8;
  raw_context.iregs[5] = 0x6a5025e2;
  raw_context.iregs[6] = 0xd9fabb4a;
  raw_context.iregs[7] = 0x6913f540;
  raw_context.iregs[8] = 0xbffe6eda;
  raw_context.iregs[9] = 0xb2ce1e2d;
  raw_context.iregs[10] = 0x659caaa4;
  raw_context.iregs[11] = 0xf0e0d0c0;
  raw_context.iregs[12] = 0xa9b8c7d6;
  raw_context.iregs[13] = 0x12345678;
  raw_context.iregs[14] = 0xabcd1234;
  raw_context.iregs[15] = 0x10203040;
  raw_context.cpsr = 0x2e951ef7;
  Context context(dump, raw_context);

  Exception exception(dump, context,
                      0x1234abcd, // thread id
                      0xdcba4321, // exception code
                      0xf0e0d0c0, // exception flags
                      0x0919a9b9c9d9e9f9ULL); // exception address
  
  dump.Add(&context);
  dump.Add(&exception);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  MinidumpException* md_exception = minidump.GetException();
  ASSERT_TRUE(md_exception != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
  ASSERT_EQ(0x1234abcdU, thread_id);

  const MDRawExceptionStream* raw_exception = md_exception->exception();
  ASSERT_TRUE(raw_exception != NULL);
  EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
  EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
  EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
            raw_exception->exception_record.exception_address);

  MinidumpContext* md_context = md_exception->GetContext();
  ASSERT_TRUE(md_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_ARM, md_context->GetContextCPU());
  const MDRawContextARM* md_raw_context = md_context->GetContextARM();
  ASSERT_TRUE(md_raw_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_ARM_INTEGER,
            (md_raw_context->context_flags
             & MD_CONTEXT_ARM_INTEGER));
  EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]);
  EXPECT_EQ(0x382583b9U, raw_context.iregs[1]);
  EXPECT_EQ(0x7fccc03fU, raw_context.iregs[2]);
  EXPECT_EQ(0xf62f8ec2U, raw_context.iregs[3]);
  EXPECT_EQ(0x46a6a6a8U, raw_context.iregs[4]);
  EXPECT_EQ(0x6a5025e2U, raw_context.iregs[5]);
  EXPECT_EQ(0xd9fabb4aU, raw_context.iregs[6]);
  EXPECT_EQ(0x6913f540U, raw_context.iregs[7]);
  EXPECT_EQ(0xbffe6edaU, raw_context.iregs[8]);
  EXPECT_EQ(0xb2ce1e2dU, raw_context.iregs[9]);
  EXPECT_EQ(0x659caaa4U, raw_context.iregs[10]);
  EXPECT_EQ(0xf0e0d0c0U, raw_context.iregs[11]);
  EXPECT_EQ(0xa9b8c7d6U, raw_context.iregs[12]);
  EXPECT_EQ(0x12345678U, raw_context.iregs[13]);
  EXPECT_EQ(0xabcd1234U, raw_context.iregs[14]);
  EXPECT_EQ(0x10203040U, raw_context.iregs[15]);
  EXPECT_EQ(0x2e951ef7U, raw_context.cpsr);
}

TEST(Dump, OneExceptionMIPS) {
  Dump dump(0, kLittleEndian);

  MDRawContextMIPS raw_context;
  raw_context.context_flags = MD_CONTEXT_MIPS_INTEGER;
  raw_context.iregs[0] = 0x3ecba80d;
  raw_context.iregs[1] = 0x382583b9;
  raw_context.iregs[2] = 0x7fccc03f;
  raw_context.iregs[3] = 0xf62f8ec2;
  raw_context.iregs[4] = 0x46a6a6a8;
  raw_context.iregs[5] = 0x6a5025e2;
  raw_context.iregs[6] = 0xd9fabb4a;
  raw_context.iregs[7] = 0x6913f540;
  raw_context.iregs[8] = 0xbffe6eda;
  raw_context.iregs[9] = 0xb2ce1e2d;
  raw_context.iregs[10] = 0x659caaa4;
  raw_context.iregs[11] = 0xf0e0d0c0;
  raw_context.iregs[12] = 0xa9b8c7d6;
  raw_context.iregs[13] = 0x12345678;
  raw_context.iregs[14] = 0xabcd1234;
  raw_context.iregs[15] = 0x10203040;
  raw_context.iregs[16] = 0xa80d3ecb;
  raw_context.iregs[17] = 0x83b93825;
  raw_context.iregs[18] = 0xc03f7fcc;
  raw_context.iregs[19] = 0x8ec2f62f;
  raw_context.iregs[20] = 0xa6a846a6;
  raw_context.iregs[21] = 0x25e26a50;
  raw_context.iregs[22] = 0xbb4ad9fa;
  raw_context.iregs[23] = 0xf5406913;
  raw_context.iregs[24] = 0x6edabffe;
  raw_context.iregs[25] = 0x1e2db2ce;
  raw_context.iregs[26] = 0xaaa4659c;
  raw_context.iregs[27] = 0xd0c0f0e0;
  raw_context.iregs[28] = 0xc7d6a9b8;
  raw_context.iregs[29] = 0x56781234;
  raw_context.iregs[30] = 0x1234abcd;
  raw_context.iregs[31] = 0x30401020;

  Context context(dump, raw_context);

  Exception exception(dump, context,
                      0x1234abcd,  // Thread id.
                      0xdcba4321,  // Exception code.
                      0xf0e0d0c0,  // Exception flags.
                      0x0919a9b9); // Exception address.
  
  dump.Add(&context);
  dump.Add(&exception);
  dump.Finish();

  string contents;
  ASSERT_TRUE(dump.GetContents(&contents));

  istringstream minidump_stream(contents);
  Minidump minidump(minidump_stream);
  ASSERT_TRUE(minidump.Read());
  ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());

  MinidumpException* md_exception = minidump.GetException();
  ASSERT_TRUE(md_exception != NULL);

  uint32_t thread_id;
  ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
  ASSERT_EQ(0x1234abcdU, thread_id);

  const MDRawExceptionStream* raw_exception = md_exception->exception();
  ASSERT_TRUE(raw_exception != NULL);
  EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
  EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
  EXPECT_EQ(0x0919a9b9U,
            raw_exception->exception_record.exception_address);

  MinidumpContext* md_context = md_exception->GetContext();
  ASSERT_TRUE(md_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_MIPS, md_context->GetContextCPU());
  const MDRawContextMIPS* md_raw_context = md_context->GetContextMIPS();
  ASSERT_TRUE(md_raw_context != NULL);
  ASSERT_EQ((uint32_t) MD_CONTEXT_MIPS_INTEGER,
            (md_raw_context->context_flags & MD_CONTEXT_MIPS_INTEGER));
  EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]);
  EXPECT_EQ(0x382583b9U, raw_context.iregs[1]);
  EXPECT_EQ(0x7fccc03fU, raw_context.iregs[2]);
  EXPECT_EQ(0xf62f8ec2U, raw_context.iregs[3]);
  EXPECT_EQ(0x46a6a6a8U, raw_context.iregs[4]);
  EXPECT_EQ(0x6a5025e2U, raw_context.iregs[5]);
  EXPECT_EQ(0xd9fabb4aU, raw_context.iregs[6]);
  EXPECT_EQ(0x6913f540U, raw_context.iregs[7]);
  EXPECT_EQ(0xbffe6edaU, raw_context.iregs[8]);
  EXPECT_EQ(0xb2ce1e2dU, raw_context.iregs[9]);
  EXPECT_EQ(0x659caaa4U, raw_context.iregs[10]);
  EXPECT_EQ(0xf0e0d0c0U, raw_context.iregs[11]);
  EXPECT_EQ(0xa9b8c7d6U, raw_context.iregs[12]);
  EXPECT_EQ(0x12345678U, raw_context.iregs[13]);
  EXPECT_EQ(0xabcd1234U, raw_context.iregs[14]);
  EXPECT_EQ(0x10203040U, raw_context.iregs[15]);
  EXPECT_EQ(0xa80d3ecbU, raw_context.iregs[16]);
  EXPECT_EQ(0x83b93825U, raw_context.iregs[17]);
  EXPECT_EQ(0xc03f7fccU, raw_context.iregs[18]);
  EXPECT_EQ(0x8ec2f62fU, raw_context.iregs[19]);
  EXPECT_EQ(0xa6a846a6U, raw_context.iregs[20]);
  EXPECT_EQ(0x25e26a50U, raw_context.iregs[21]);
  EXPECT_EQ(0xbb4ad9faU, raw_context.iregs[22]);
  EXPECT_EQ(0xf5406913U, raw_context.iregs[23]);
  EXPECT_EQ(0x6edabffeU, raw_context.iregs[24]);
  EXPECT_EQ(0x1e2db2ceU, raw_context.iregs[25]);
  EXPECT_EQ(0xaaa4659cU, raw_context.iregs[26]);
  EXPECT_EQ(0xd0c0f0e0U, raw_context.iregs[27]);
  EXPECT_EQ(0xc7d6a9b8U, raw_context.iregs[28]);
  EXPECT_EQ(0x56781234U, raw_context.iregs[29]);
  EXPECT_EQ(0x1234abcdU, raw_context.iregs[30]);
  EXPECT_EQ(0x30401020U, raw_context.iregs[31]);
}

}  // namespace
