toolkit/crashreporter/google-breakpad/src/processor/minidump_unittest.cc

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 // Copyright (c) 2010, Google Inc.
     2 // All rights reserved.
     3 //
     4 // Redistribution and use in source and binary forms, with or without
     5 // modification, are permitted provided that the following conditions are
     6 // met:
     7 //
     8 //     * Redistributions of source code must retain the above copyright
     9 // notice, this list of conditions and the following disclaimer.
    10 //     * Redistributions in binary form must reproduce the above
    11 // copyright notice, this list of conditions and the following disclaimer
    12 // in the documentation and/or other materials provided with the
    13 // distribution.
    14 //     * Neither the name of Google Inc. nor the names of its
    15 // contributors may be used to endorse or promote products derived from
    16 // this software without specific prior written permission.
    17 //
    18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    30 // Unit test for Minidump.  Uses a pre-generated minidump and
    31 // verifies that certain streams are correct.
    33 #include <iostream>
    34 #include <fstream>
    35 #include <sstream>
    36 #include <stdlib.h>
    37 #include <string>
    38 #include <vector>
    40 #include "breakpad_googletest_includes.h"
    41 #include "common/using_std_string.h"
    42 #include "google_breakpad/common/minidump_format.h"
    43 #include "google_breakpad/processor/minidump.h"
    44 #include "processor/logging.h"
    45 #include "processor/synth_minidump.h"
    47 namespace {
    49 using google_breakpad::Minidump;
    50 using google_breakpad::MinidumpContext;
    51 using google_breakpad::MinidumpException;
    52 using google_breakpad::MinidumpMemoryInfo;
    53 using google_breakpad::MinidumpMemoryInfoList;
    54 using google_breakpad::MinidumpMemoryList;
    55 using google_breakpad::MinidumpMemoryRegion;
    56 using google_breakpad::MinidumpModule;
    57 using google_breakpad::MinidumpModuleList;
    58 using google_breakpad::MinidumpSystemInfo;
    59 using google_breakpad::MinidumpThread;
    60 using google_breakpad::MinidumpThreadList;
    61 using google_breakpad::SynthMinidump::Context;
    62 using google_breakpad::SynthMinidump::Dump;
    63 using google_breakpad::SynthMinidump::Exception;
    64 using google_breakpad::SynthMinidump::Memory;
    65 using google_breakpad::SynthMinidump::Module;
    66 using google_breakpad::SynthMinidump::Stream;
    67 using google_breakpad::SynthMinidump::String;
    68 using google_breakpad::SynthMinidump::SystemInfo;
    69 using google_breakpad::SynthMinidump::Thread;
    70 using google_breakpad::test_assembler::kBigEndian;
    71 using google_breakpad::test_assembler::kLittleEndian;
    72 using std::ifstream;
    73 using std::istringstream;
    74 using std::vector;
    75 using ::testing::Return;
    77 class MinidumpTest : public ::testing::Test {
    78 public:
    79   void SetUp() {
    80     minidump_file_ = string(getenv("srcdir") ? getenv("srcdir") : ".") +
    81       "/src/processor/testdata/minidump2.dmp";
    82   }
    83   string minidump_file_;
    84 };
    86 TEST_F(MinidumpTest, TestMinidumpFromFile) {
    87   Minidump minidump(minidump_file_);
    88   ASSERT_EQ(minidump.path(), minidump_file_);
    89   ASSERT_TRUE(minidump.Read());
    90   const MDRawHeader* header = minidump.header();
    91   ASSERT_NE(header, (MDRawHeader*)NULL);
    92   ASSERT_EQ(header->signature, uint32_t(MD_HEADER_SIGNATURE));
    93   //TODO: add more checks here
    94 }
    96 TEST_F(MinidumpTest, TestMinidumpFromStream) {
    97   // read minidump contents into memory, construct a stringstream around them
    98   ifstream file_stream(minidump_file_.c_str(), std::ios::in);
    99   ASSERT_TRUE(file_stream.good());
   100   vector<char> bytes;
   101   file_stream.seekg(0, std::ios_base::end);
   102   ASSERT_TRUE(file_stream.good());
   103   bytes.resize(file_stream.tellg());
   104   file_stream.seekg(0, std::ios_base::beg);
   105   ASSERT_TRUE(file_stream.good());
   106   file_stream.read(&bytes[0], bytes.size());
   107   ASSERT_TRUE(file_stream.good());
   108   string str(&bytes[0], bytes.size());
   109   istringstream stream(str);
   110   ASSERT_TRUE(stream.good());
   112   // now read minidump from stringstream
   113   Minidump minidump(stream);
   114   ASSERT_EQ(minidump.path(), "");
   115   ASSERT_TRUE(minidump.Read());
   116   const MDRawHeader* header = minidump.header();
   117   ASSERT_NE(header, (MDRawHeader*)NULL);
   118   ASSERT_EQ(header->signature, uint32_t(MD_HEADER_SIGNATURE));
   119   //TODO: add more checks here
   120 }
   122 TEST(Dump, ReadBackEmpty) {
   123   Dump dump(0);
   124   dump.Finish();
   125   string contents;
   126   ASSERT_TRUE(dump.GetContents(&contents));
   127   istringstream stream(contents);
   128   Minidump minidump(stream);
   129   ASSERT_TRUE(minidump.Read());
   130   ASSERT_EQ(0U, minidump.GetDirectoryEntryCount());
   131 }
   133 TEST(Dump, ReadBackEmptyBigEndian) {
   134   Dump big_minidump(0, kBigEndian);
   135   big_minidump.Finish();
   136   string contents;
   137   ASSERT_TRUE(big_minidump.GetContents(&contents));
   138   istringstream stream(contents);
   139   Minidump minidump(stream);
   140   ASSERT_TRUE(minidump.Read());
   141   ASSERT_EQ(0U, minidump.GetDirectoryEntryCount());
   142 }
   144 TEST(Dump, OneStream) {
   145   Dump dump(0, kBigEndian);
   146   Stream stream(dump, 0xfbb7fa2bU);
   147   stream.Append("stream contents");
   148   dump.Add(&stream);
   149   dump.Finish();
   151   string contents;
   152   ASSERT_TRUE(dump.GetContents(&contents));
   153   istringstream minidump_stream(contents);
   154   Minidump minidump(minidump_stream);
   155   ASSERT_TRUE(minidump.Read());
   156   ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
   158   const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
   159   ASSERT_TRUE(dir != NULL);
   160   EXPECT_EQ(0xfbb7fa2bU, dir->stream_type);
   162   uint32_t stream_length;
   163   ASSERT_TRUE(minidump.SeekToStreamType(0xfbb7fa2bU, &stream_length));
   164   ASSERT_EQ(15U, stream_length);
   165   char stream_contents[15];
   166   ASSERT_TRUE(minidump.ReadBytes(stream_contents, sizeof(stream_contents)));
   167   EXPECT_EQ(string("stream contents"),
   168             string(stream_contents, sizeof(stream_contents)));
   170   EXPECT_FALSE(minidump.GetThreadList());
   171   EXPECT_FALSE(minidump.GetModuleList());
   172   EXPECT_FALSE(minidump.GetMemoryList());
   173   EXPECT_FALSE(minidump.GetException());
   174   EXPECT_FALSE(minidump.GetAssertion());
   175   EXPECT_FALSE(minidump.GetSystemInfo());
   176   EXPECT_FALSE(minidump.GetMiscInfo());
   177   EXPECT_FALSE(minidump.GetBreakpadInfo());
   178 }
   180 TEST(Dump, OneMemory) {
   181   Dump dump(0, kBigEndian);
   182   Memory memory(dump, 0x309d68010bd21b2cULL);
   183   memory.Append("memory contents");
   184   dump.Add(&memory);
   185   dump.Finish();
   187   string contents;
   188   ASSERT_TRUE(dump.GetContents(&contents));
   189   istringstream minidump_stream(contents);
   190   Minidump minidump(minidump_stream);
   191   ASSERT_TRUE(minidump.Read());
   192   ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
   194   const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
   195   ASSERT_TRUE(dir != NULL);
   196   EXPECT_EQ((uint32_t) MD_MEMORY_LIST_STREAM, dir->stream_type);
   198   MinidumpMemoryList *memory_list = minidump.GetMemoryList();
   199   ASSERT_TRUE(memory_list != NULL);
   200   ASSERT_EQ(1U, memory_list->region_count());
   202   MinidumpMemoryRegion *region1 = memory_list->GetMemoryRegionAtIndex(0);
   203   ASSERT_EQ(0x309d68010bd21b2cULL, region1->GetBase());
   204   ASSERT_EQ(15U, region1->GetSize());
   205   const uint8_t *region1_bytes = region1->GetMemory();
   206   ASSERT_TRUE(memcmp("memory contents", region1_bytes, 15) == 0);
   207 }
   209 // One thread --- and its requisite entourage.
   210 TEST(Dump, OneThread) {
   211   Dump dump(0, kLittleEndian);
   212   Memory stack(dump, 0x2326a0fa);
   213   stack.Append("stack for thread");
   215   MDRawContextX86 raw_context;
   216   const uint32_t kExpectedEIP = 0x6913f540;
   217   raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL;
   218   raw_context.edi = 0x3ecba80d;
   219   raw_context.esi = 0x382583b9;
   220   raw_context.ebx = 0x7fccc03f;
   221   raw_context.edx = 0xf62f8ec2;
   222   raw_context.ecx = 0x46a6a6a8;
   223   raw_context.eax = 0x6a5025e2;
   224   raw_context.ebp = 0xd9fabb4a;
   225   raw_context.eip = kExpectedEIP;
   226   raw_context.cs = 0xbffe6eda;
   227   raw_context.eflags = 0xb2ce1e2d;
   228   raw_context.esp = 0x659caaa4;
   229   raw_context.ss = 0x2e951ef7;
   230   Context context(dump, raw_context);
   232   Thread thread(dump, 0xa898f11b, stack, context,
   233                 0x9e39439f, 0x4abfc15f, 0xe499898a, 0x0d43e939dcfd0372ULL);
   235   dump.Add(&stack);
   236   dump.Add(&context);
   237   dump.Add(&thread);
   238   dump.Finish();
   240   string contents;
   241   ASSERT_TRUE(dump.GetContents(&contents));
   243   istringstream minidump_stream(contents);
   244   Minidump minidump(minidump_stream);
   245   ASSERT_TRUE(minidump.Read());
   246   ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());
   248   MinidumpMemoryList *md_memory_list = minidump.GetMemoryList();
   249   ASSERT_TRUE(md_memory_list != NULL);
   250   ASSERT_EQ(1U, md_memory_list->region_count());
   252   MinidumpMemoryRegion *md_region = md_memory_list->GetMemoryRegionAtIndex(0);
   253   ASSERT_EQ(0x2326a0faU, md_region->GetBase());
   254   ASSERT_EQ(16U, md_region->GetSize());
   255   const uint8_t *region_bytes = md_region->GetMemory();
   256   ASSERT_TRUE(memcmp("stack for thread", region_bytes, 16) == 0);
   258   MinidumpThreadList *thread_list = minidump.GetThreadList();
   259   ASSERT_TRUE(thread_list != NULL);
   260   ASSERT_EQ(1U, thread_list->thread_count());
   262   MinidumpThread *md_thread = thread_list->GetThreadAtIndex(0);
   263   ASSERT_TRUE(md_thread != NULL);
   264   uint32_t thread_id;
   265   ASSERT_TRUE(md_thread->GetThreadID(&thread_id));
   266   ASSERT_EQ(0xa898f11bU, thread_id);
   267   MinidumpMemoryRegion *md_stack = md_thread->GetMemory();
   268   ASSERT_TRUE(md_stack != NULL);
   269   ASSERT_EQ(0x2326a0faU, md_stack->GetBase());
   270   ASSERT_EQ(16U, md_stack->GetSize());
   271   const uint8_t *md_stack_bytes = md_stack->GetMemory();
   272   ASSERT_TRUE(memcmp("stack for thread", md_stack_bytes, 16) == 0);
   274   MinidumpContext *md_context = md_thread->GetContext();
   275   ASSERT_TRUE(md_context != NULL);
   276   ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
   278   uint64_t eip;
   279   ASSERT_TRUE(md_context->GetInstructionPointer(&eip));
   280   EXPECT_EQ(kExpectedEIP, eip);
   282   const MDRawContextX86 *md_raw_context = md_context->GetContextX86();
   283   ASSERT_TRUE(md_raw_context != NULL);
   284   ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
   285             (md_raw_context->context_flags
   286              & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
   287   EXPECT_EQ(0x3ecba80dU, raw_context.edi);
   288   EXPECT_EQ(0x382583b9U, raw_context.esi);
   289   EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
   290   EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
   291   EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
   292   EXPECT_EQ(0x6a5025e2U, raw_context.eax);
   293   EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
   294   EXPECT_EQ(kExpectedEIP, raw_context.eip);
   295   EXPECT_EQ(0xbffe6edaU, raw_context.cs);
   296   EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
   297   EXPECT_EQ(0x659caaa4U, raw_context.esp);
   298   EXPECT_EQ(0x2e951ef7U, raw_context.ss);
   299 }
   301 TEST(Dump, ThreadMissingMemory) {
   302   Dump dump(0, kLittleEndian);
   303   Memory stack(dump, 0x2326a0fa);
   304   // Stack has no contents.
   306   MDRawContextX86 raw_context;
   307   memset(&raw_context, 0, sizeof(raw_context));
   308   raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL;
   309   Context context(dump, raw_context);
   311   Thread thread(dump, 0xa898f11b, stack, context,
   312                 0x9e39439f, 0x4abfc15f, 0xe499898a, 0x0d43e939dcfd0372ULL);
   314   dump.Add(&stack);
   315   dump.Add(&context);
   316   dump.Add(&thread);
   317   dump.Finish();
   319   string contents;
   320   ASSERT_TRUE(dump.GetContents(&contents));
   322   istringstream minidump_stream(contents);
   323   Minidump minidump(minidump_stream);
   324   ASSERT_TRUE(minidump.Read());
   325   ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());
   327   // This should succeed even though the thread has no stack memory.
   328   MinidumpThreadList* thread_list = minidump.GetThreadList();
   329   ASSERT_TRUE(thread_list != NULL);
   330   ASSERT_EQ(1U, thread_list->thread_count());
   332   MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0);
   333   ASSERT_TRUE(md_thread != NULL);
   335   uint32_t thread_id;
   336   ASSERT_TRUE(md_thread->GetThreadID(&thread_id));
   337   ASSERT_EQ(0xa898f11bU, thread_id);
   339   MinidumpContext* md_context = md_thread->GetContext();
   340   ASSERT_NE(reinterpret_cast<MinidumpContext*>(NULL), md_context);
   342   MinidumpMemoryRegion* md_stack = md_thread->GetMemory();
   343   ASSERT_EQ(reinterpret_cast<MinidumpMemoryRegion*>(NULL), md_stack);
   344 }
   346 TEST(Dump, ThreadMissingContext) {
   347   Dump dump(0, kLittleEndian);
   348   Memory stack(dump, 0x2326a0fa);
   349   stack.Append("stack for thread");
   351   // Context is empty.
   352   Context context(dump);
   354   Thread thread(dump, 0xa898f11b, stack, context,
   355                 0x9e39439f, 0x4abfc15f, 0xe499898a, 0x0d43e939dcfd0372ULL);
   357   dump.Add(&stack);
   358   dump.Add(&context);
   359   dump.Add(&thread);
   360   dump.Finish();
   362   string contents;
   363   ASSERT_TRUE(dump.GetContents(&contents));
   365   istringstream minidump_stream(contents);
   366   Minidump minidump(minidump_stream);
   367   ASSERT_TRUE(minidump.Read());
   368   ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());
   370   // This should succeed even though the thread has no stack memory.
   371   MinidumpThreadList* thread_list = minidump.GetThreadList();
   372   ASSERT_TRUE(thread_list != NULL);
   373   ASSERT_EQ(1U, thread_list->thread_count());
   375   MinidumpThread* md_thread = thread_list->GetThreadAtIndex(0);
   376   ASSERT_TRUE(md_thread != NULL);
   378   uint32_t thread_id;
   379   ASSERT_TRUE(md_thread->GetThreadID(&thread_id));
   380   ASSERT_EQ(0xa898f11bU, thread_id);
   381   MinidumpMemoryRegion* md_stack = md_thread->GetMemory();
   382   ASSERT_NE(reinterpret_cast<MinidumpMemoryRegion*>(NULL), md_stack);
   384   MinidumpContext* md_context = md_thread->GetContext();
   385   ASSERT_EQ(reinterpret_cast<MinidumpContext*>(NULL), md_context);
   386 }
   388 TEST(Dump, OneModule) {
   389   static const MDVSFixedFileInfo fixed_file_info = {
   390     0xb2fba33a,                           // signature
   391     0x33d7a728,                           // struct_version
   392     0x31afcb20,                           // file_version_hi
   393     0xe51cdab1,                           // file_version_lo
   394     0xd1ea6907,                           // product_version_hi
   395     0x03032857,                           // product_version_lo
   396     0x11bf71d7,                           // file_flags_mask
   397     0x5fb8cdbf,                           // file_flags
   398     0xe45d0d5d,                           // file_os
   399     0x107d9562,                           // file_type
   400     0x5a8844d4,                           // file_subtype
   401     0xa8d30b20,                           // file_date_hi
   402     0x651c3e4e                            // file_date_lo
   403   };
   405   Dump dump(0, kBigEndian);
   406   String module_name(dump, "single module");
   407   Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd,
   408                 module_name,
   409                 0xb1054d2a,
   410                 0x34571371,
   411                 fixed_file_info, // from synth_minidump_unittest_data.h
   412                 NULL, NULL);
   414   dump.Add(&module);
   415   dump.Add(&module_name);
   416   dump.Finish();
   418   string contents;
   419   ASSERT_TRUE(dump.GetContents(&contents));
   420   istringstream minidump_stream(contents);
   421   Minidump minidump(minidump_stream);
   422   ASSERT_TRUE(minidump.Read());
   423   ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
   425   const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
   426   ASSERT_TRUE(dir != NULL);
   427   EXPECT_EQ((uint32_t) MD_MODULE_LIST_STREAM, dir->stream_type);
   429   MinidumpModuleList *md_module_list = minidump.GetModuleList();
   430   ASSERT_TRUE(md_module_list != NULL);
   431   ASSERT_EQ(1U, md_module_list->module_count());
   433   const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0);
   434   ASSERT_TRUE(md_module != NULL);
   435   ASSERT_EQ(0xa90206ca83eb2852ULL, md_module->base_address());
   436   ASSERT_EQ(0xada542bd, md_module->size());
   437   ASSERT_EQ("single module", md_module->code_file());
   439   const MDRawModule *md_raw_module = md_module->module();
   440   ASSERT_TRUE(md_raw_module != NULL);
   441   ASSERT_EQ(0xb1054d2aU, md_raw_module->time_date_stamp);
   442   ASSERT_EQ(0x34571371U, md_raw_module->checksum);
   443   ASSERT_TRUE(memcmp(&md_raw_module->version_info, &fixed_file_info,
   444                      sizeof(fixed_file_info)) == 0);
   445 }
   447 TEST(Dump, OneSystemInfo) {
   448   Dump dump(0, kLittleEndian);
   449   String csd_version(dump, "Petulant Pierogi");
   450   SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);
   452   dump.Add(&system_info);
   453   dump.Add(&csd_version);
   454   dump.Finish();
   456   string contents;
   457   ASSERT_TRUE(dump.GetContents(&contents));
   458   istringstream minidump_stream(contents);
   459   Minidump minidump(minidump_stream);
   460   ASSERT_TRUE(minidump.Read());
   461   ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
   463   const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
   464   ASSERT_TRUE(dir != NULL);
   465   EXPECT_EQ((uint32_t) MD_SYSTEM_INFO_STREAM, dir->stream_type);
   467   MinidumpSystemInfo *md_system_info = minidump.GetSystemInfo();
   468   ASSERT_TRUE(md_system_info != NULL);
   469   ASSERT_EQ("windows", md_system_info->GetOS());
   470   ASSERT_EQ("x86", md_system_info->GetCPU());
   471   ASSERT_EQ("Petulant Pierogi", *md_system_info->GetCSDVersion());
   472   ASSERT_EQ("GenuineIntel", *md_system_info->GetCPUVendor());
   473 }
   475 TEST(Dump, BigDump) {
   476   Dump dump(0, kLittleEndian);
   478   // A SystemInfo stream.
   479   String csd_version(dump, "Munificent Macaque");
   480   SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);
   481   dump.Add(&csd_version);
   482   dump.Add(&system_info);
   484   // Five threads!
   485   Memory stack0(dump, 0x70b9ebfc);
   486   stack0.Append("stack for thread zero");
   487   MDRawContextX86 raw_context0;
   488   raw_context0.context_flags = MD_CONTEXT_X86_INTEGER;
   489   raw_context0.eip = 0xaf0709e4;
   490   Context context0(dump, raw_context0);
   491   Thread thread0(dump, 0xbbef4432, stack0, context0,
   492                  0xd0377e7b, 0xdb8eb0cf, 0xd73bc314, 0x09d357bac7f9a163ULL);
   493   dump.Add(&stack0);
   494   dump.Add(&context0);
   495   dump.Add(&thread0);
   497   Memory stack1(dump, 0xf988cc45);
   498   stack1.Append("stack for thread one");
   499   MDRawContextX86 raw_context1;
   500   raw_context1.context_flags = MD_CONTEXT_X86_INTEGER;
   501   raw_context1.eip = 0xe4f56f81;
   502   Context context1(dump, raw_context1);
   503   Thread thread1(dump, 0x657c3f58, stack1, context1,
   504                  0xa68fa182, 0x6f3cf8dd, 0xe3a78ccf, 0x78cc84775e4534bbULL);
   505   dump.Add(&stack1);
   506   dump.Add(&context1);
   507   dump.Add(&thread1);
   509   Memory stack2(dump, 0xc8a92e7c);
   510   stack2.Append("stack for thread two");
   511   MDRawContextX86 raw_context2;
   512   raw_context2.context_flags = MD_CONTEXT_X86_INTEGER;
   513   raw_context2.eip = 0xb336a438;
   514   Context context2(dump, raw_context2);
   515   Thread thread2(dump, 0xdf4b8a71, stack2, context2,
   516                  0x674c26b6, 0x445d7120, 0x7e700c56, 0xd89bf778e7793e17ULL);
   517   dump.Add(&stack2);
   518   dump.Add(&context2);
   519   dump.Add(&thread2);
   521   Memory stack3(dump, 0x36d08e08);
   522   stack3.Append("stack for thread three");
   523   MDRawContextX86 raw_context3;
   524   raw_context3.context_flags = MD_CONTEXT_X86_INTEGER;
   525   raw_context3.eip = 0xdf99a60c;
   526   Context context3(dump, raw_context3);
   527   Thread thread3(dump, 0x86e6c341, stack3, context3,
   528                  0x32dc5c55, 0x17a2aba8, 0xe0cc75e7, 0xa46393994dae83aeULL);
   529   dump.Add(&stack3);
   530   dump.Add(&context3);
   531   dump.Add(&thread3);
   533   Memory stack4(dump, 0x1e0ab4fa);
   534   stack4.Append("stack for thread four");
   535   MDRawContextX86 raw_context4;
   536   raw_context4.context_flags = MD_CONTEXT_X86_INTEGER;
   537   raw_context4.eip = 0xaa646267;
   538   Context context4(dump, raw_context4);
   539   Thread thread4(dump, 0x261a28d4, stack4, context4,
   540                  0x6ebd389e, 0xa0cd4759, 0x30168846, 0x164f650a0cf39d35ULL);
   541   dump.Add(&stack4);
   542   dump.Add(&context4);
   543   dump.Add(&thread4);
   545   // Three modules!
   546   String module1_name(dump, "module one");
   547   Module module1(dump, 0xeb77da57b5d4cbdaULL, 0x83cd5a37, module1_name);
   548   dump.Add(&module1_name);
   549   dump.Add(&module1);
   551   String module2_name(dump, "module two");
   552   Module module2(dump, 0x8675884adfe5ac90ULL, 0xb11e4ea3, module2_name);
   553   dump.Add(&module2_name);
   554   dump.Add(&module2);
   556   String module3_name(dump, "module three");
   557   Module module3(dump, 0x95fc1544da321b6cULL, 0x7c2bf081, module3_name);
   558   dump.Add(&module3_name);
   559   dump.Add(&module3);
   561   // Add one more memory region, on top of the five stacks.
   562   Memory memory5(dump, 0x61979e828040e564ULL);
   563   memory5.Append("contents of memory 5");
   564   dump.Add(&memory5);
   566   dump.Finish();
   568   string contents;
   569   ASSERT_TRUE(dump.GetContents(&contents));
   570   istringstream minidump_stream(contents);
   571   Minidump minidump(minidump_stream);
   572   ASSERT_TRUE(minidump.Read());
   573   ASSERT_EQ(4U, minidump.GetDirectoryEntryCount());
   575   // Check the threads.
   576   MinidumpThreadList *thread_list = minidump.GetThreadList();
   577   ASSERT_TRUE(thread_list != NULL);
   578   ASSERT_EQ(5U, thread_list->thread_count());
   579   uint32_t thread_id;
   580   ASSERT_TRUE(thread_list->GetThreadAtIndex(0)->GetThreadID(&thread_id));
   581   ASSERT_EQ(0xbbef4432U, thread_id);
   582   ASSERT_EQ(0x70b9ebfcU,
   583             thread_list->GetThreadAtIndex(0)->GetMemory()->GetBase());
   584   ASSERT_EQ(0xaf0709e4U,
   585             thread_list->GetThreadAtIndex(0)->GetContext()->GetContextX86()
   586             ->eip);
   588   ASSERT_TRUE(thread_list->GetThreadAtIndex(1)->GetThreadID(&thread_id));
   589   ASSERT_EQ(0x657c3f58U, thread_id);
   590   ASSERT_EQ(0xf988cc45U,
   591             thread_list->GetThreadAtIndex(1)->GetMemory()->GetBase());
   592   ASSERT_EQ(0xe4f56f81U,
   593             thread_list->GetThreadAtIndex(1)->GetContext()->GetContextX86()
   594             ->eip);
   596   ASSERT_TRUE(thread_list->GetThreadAtIndex(2)->GetThreadID(&thread_id));
   597   ASSERT_EQ(0xdf4b8a71U, thread_id);
   598   ASSERT_EQ(0xc8a92e7cU,
   599             thread_list->GetThreadAtIndex(2)->GetMemory()->GetBase());
   600   ASSERT_EQ(0xb336a438U,
   601             thread_list->GetThreadAtIndex(2)->GetContext()->GetContextX86()
   602             ->eip);
   604   ASSERT_TRUE(thread_list->GetThreadAtIndex(3)->GetThreadID(&thread_id));
   605   ASSERT_EQ(0x86e6c341U, thread_id);
   606   ASSERT_EQ(0x36d08e08U,
   607             thread_list->GetThreadAtIndex(3)->GetMemory()->GetBase());
   608   ASSERT_EQ(0xdf99a60cU,
   609             thread_list->GetThreadAtIndex(3)->GetContext()->GetContextX86()
   610             ->eip);
   612   ASSERT_TRUE(thread_list->GetThreadAtIndex(4)->GetThreadID(&thread_id));
   613   ASSERT_EQ(0x261a28d4U, thread_id);
   614   ASSERT_EQ(0x1e0ab4faU,
   615             thread_list->GetThreadAtIndex(4)->GetMemory()->GetBase());
   616   ASSERT_EQ(0xaa646267U,
   617             thread_list->GetThreadAtIndex(4)->GetContext()->GetContextX86()
   618             ->eip);
   620   // Check the modules.
   621   MinidumpModuleList *md_module_list = minidump.GetModuleList();
   622   ASSERT_TRUE(md_module_list != NULL);
   623   ASSERT_EQ(3U, md_module_list->module_count());
   624   EXPECT_EQ(0xeb77da57b5d4cbdaULL,
   625             md_module_list->GetModuleAtIndex(0)->base_address());
   626   EXPECT_EQ(0x8675884adfe5ac90ULL,
   627             md_module_list->GetModuleAtIndex(1)->base_address());
   628   EXPECT_EQ(0x95fc1544da321b6cULL,
   629             md_module_list->GetModuleAtIndex(2)->base_address());
   630 }
   632 TEST(Dump, OneMemoryInfo) {
   633   Dump dump(0, kBigEndian);
   634   Stream stream(dump, MD_MEMORY_INFO_LIST_STREAM);
   636   // Add the MDRawMemoryInfoList header.
   637   const uint64_t kNumberOfEntries = 1;
   638   stream.D32(sizeof(MDRawMemoryInfoList))  // size_of_header
   639         .D32(sizeof(MDRawMemoryInfo))      // size_of_entry
   640         .D64(kNumberOfEntries);            // number_of_entries
   643   // Now add a MDRawMemoryInfo entry.
   644   const uint64_t kBaseAddress = 0x1000;
   645   const uint64_t kRegionSize = 0x2000;
   646   stream.D64(kBaseAddress)                         // base_address
   647         .D64(kBaseAddress)                         // allocation_base
   648         .D32(MD_MEMORY_PROTECT_EXECUTE_READWRITE)  // allocation_protection
   649         .D32(0)                                    // __alignment1
   650         .D64(kRegionSize)                          // region_size
   651         .D32(MD_MEMORY_STATE_COMMIT)               // state
   652         .D32(MD_MEMORY_PROTECT_EXECUTE_READWRITE)  // protection
   653         .D32(MD_MEMORY_TYPE_PRIVATE)               // type
   654         .D32(0);                                   // __alignment2
   656   dump.Add(&stream);
   657   dump.Finish();
   659   string contents;
   660   ASSERT_TRUE(dump.GetContents(&contents));
   661   istringstream minidump_stream(contents);
   662   Minidump minidump(minidump_stream);
   663   ASSERT_TRUE(minidump.Read());
   664   ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
   666   const MDRawDirectory *dir = minidump.GetDirectoryEntryAtIndex(0);
   667   ASSERT_TRUE(dir != NULL);
   668   EXPECT_EQ((uint32_t) MD_MEMORY_INFO_LIST_STREAM, dir->stream_type);
   670   MinidumpMemoryInfoList *info_list = minidump.GetMemoryInfoList();
   671   ASSERT_TRUE(info_list != NULL);
   672   ASSERT_EQ(1U, info_list->info_count());
   674   const MinidumpMemoryInfo *info1 = info_list->GetMemoryInfoAtIndex(0);
   675   ASSERT_EQ(kBaseAddress, info1->GetBase());
   676   ASSERT_EQ(kRegionSize, info1->GetSize());
   677   ASSERT_TRUE(info1->IsExecutable());
   678   ASSERT_TRUE(info1->IsWritable());
   680   // Should get back the same memory region here.
   681   const MinidumpMemoryInfo *info2 =
   682       info_list->GetMemoryInfoForAddress(kBaseAddress + kRegionSize / 2);
   683   ASSERT_EQ(kBaseAddress, info2->GetBase());
   684   ASSERT_EQ(kRegionSize, info2->GetSize());
   685 }
   687 TEST(Dump, OneExceptionX86) {
   688   Dump dump(0, kLittleEndian);
   690   MDRawContextX86 raw_context;
   691   raw_context.context_flags = MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL;
   692   raw_context.edi = 0x3ecba80d;
   693   raw_context.esi = 0x382583b9;
   694   raw_context.ebx = 0x7fccc03f;
   695   raw_context.edx = 0xf62f8ec2;
   696   raw_context.ecx = 0x46a6a6a8;
   697   raw_context.eax = 0x6a5025e2;
   698   raw_context.ebp = 0xd9fabb4a;
   699   raw_context.eip = 0x6913f540;
   700   raw_context.cs = 0xbffe6eda;
   701   raw_context.eflags = 0xb2ce1e2d;
   702   raw_context.esp = 0x659caaa4;
   703   raw_context.ss = 0x2e951ef7;
   704   Context context(dump, raw_context);
   706   Exception exception(dump, context,
   707                       0x1234abcd, // thread id
   708                       0xdcba4321, // exception code
   709                       0xf0e0d0c0, // exception flags
   710                       0x0919a9b9c9d9e9f9ULL); // exception address
   712   dump.Add(&context);
   713   dump.Add(&exception);
   714   dump.Finish();
   716   string contents;
   717   ASSERT_TRUE(dump.GetContents(&contents));
   719   istringstream minidump_stream(contents);
   720   Minidump minidump(minidump_stream);
   721   ASSERT_TRUE(minidump.Read());
   722   ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
   724   MinidumpException *md_exception = minidump.GetException();
   725   ASSERT_TRUE(md_exception != NULL);
   727   uint32_t thread_id;
   728   ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
   729   ASSERT_EQ(0x1234abcdU, thread_id);
   731   const MDRawExceptionStream* raw_exception = md_exception->exception();
   732   ASSERT_TRUE(raw_exception != NULL);
   733   EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
   734   EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
   735   EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
   736             raw_exception->exception_record.exception_address);
   738   MinidumpContext *md_context = md_exception->GetContext();
   739   ASSERT_TRUE(md_context != NULL);
   740   ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
   741   const MDRawContextX86 *md_raw_context = md_context->GetContextX86();
   742   ASSERT_TRUE(md_raw_context != NULL);
   743   ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
   744             (md_raw_context->context_flags
   745              & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
   746   EXPECT_EQ(0x3ecba80dU, raw_context.edi);
   747   EXPECT_EQ(0x382583b9U, raw_context.esi);
   748   EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
   749   EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
   750   EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
   751   EXPECT_EQ(0x6a5025e2U, raw_context.eax);
   752   EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
   753   EXPECT_EQ(0x6913f540U, raw_context.eip);
   754   EXPECT_EQ(0xbffe6edaU, raw_context.cs);
   755   EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
   756   EXPECT_EQ(0x659caaa4U, raw_context.esp);
   757   EXPECT_EQ(0x2e951ef7U, raw_context.ss);
   758 }
   760 TEST(Dump, OneExceptionX86XState) {
   761   Dump dump(0, kLittleEndian);
   763   MDRawContextX86 raw_context;
   764   raw_context.context_flags = MD_CONTEXT_X86_INTEGER |
   765     MD_CONTEXT_X86_CONTROL | MD_CONTEXT_X86_XSTATE;
   766   raw_context.edi = 0x3ecba80d;
   767   raw_context.esi = 0x382583b9;
   768   raw_context.ebx = 0x7fccc03f;
   769   raw_context.edx = 0xf62f8ec2;
   770   raw_context.ecx = 0x46a6a6a8;
   771   raw_context.eax = 0x6a5025e2;
   772   raw_context.ebp = 0xd9fabb4a;
   773   raw_context.eip = 0x6913f540;
   774   raw_context.cs = 0xbffe6eda;
   775   raw_context.eflags = 0xb2ce1e2d;
   776   raw_context.esp = 0x659caaa4;
   777   raw_context.ss = 0x2e951ef7;
   778   Context context(dump, raw_context);
   780   Exception exception(dump, context,
   781                       0x1234abcd, // thread id
   782                       0xdcba4321, // exception code
   783                       0xf0e0d0c0, // exception flags
   784                       0x0919a9b9c9d9e9f9ULL); // exception address
   786   dump.Add(&context);
   787   dump.Add(&exception);
   788   dump.Finish();
   790   string contents;
   791   ASSERT_TRUE(dump.GetContents(&contents));
   793   istringstream minidump_stream(contents);
   794   Minidump minidump(minidump_stream);
   795   ASSERT_TRUE(minidump.Read());
   796   ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
   798   MinidumpException *md_exception = minidump.GetException();
   799   ASSERT_TRUE(md_exception != NULL);
   801   uint32_t thread_id;
   802   ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
   803   ASSERT_EQ(0x1234abcdU, thread_id);
   805   const MDRawExceptionStream* raw_exception = md_exception->exception();
   806   ASSERT_TRUE(raw_exception != NULL);
   807   EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
   808   EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
   809   EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
   810             raw_exception->exception_record.exception_address);
   812   MinidumpContext *md_context = md_exception->GetContext();
   813   ASSERT_TRUE(md_context != NULL);
   814   ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
   815   const MDRawContextX86 *md_raw_context = md_context->GetContextX86();
   816   ASSERT_TRUE(md_raw_context != NULL);
   817   ASSERT_EQ((uint32_t) (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL),
   818             (md_raw_context->context_flags
   819              & (MD_CONTEXT_X86_INTEGER | MD_CONTEXT_X86_CONTROL)));
   820   EXPECT_EQ(0x3ecba80dU, raw_context.edi);
   821   EXPECT_EQ(0x382583b9U, raw_context.esi);
   822   EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
   823   EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
   824   EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
   825   EXPECT_EQ(0x6a5025e2U, raw_context.eax);
   826   EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
   827   EXPECT_EQ(0x6913f540U, raw_context.eip);
   828   EXPECT_EQ(0xbffe6edaU, raw_context.cs);
   829   EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
   830   EXPECT_EQ(0x659caaa4U, raw_context.esp);
   831   EXPECT_EQ(0x2e951ef7U, raw_context.ss);
   832 }
   834 // Testing that the CPU type can be loaded from a system info stream when
   835 // the CPU flags are missing from the context_flags of an exception record
   836 TEST(Dump, OneExceptionX86NoCPUFlags) {
   837   Dump dump(0, kLittleEndian);
   839   MDRawContextX86 raw_context;
   840   // Intentionally not setting CPU type in the context_flags
   841   raw_context.context_flags = 0;
   842   raw_context.edi = 0x3ecba80d;
   843   raw_context.esi = 0x382583b9;
   844   raw_context.ebx = 0x7fccc03f;
   845   raw_context.edx = 0xf62f8ec2;
   846   raw_context.ecx = 0x46a6a6a8;
   847   raw_context.eax = 0x6a5025e2;
   848   raw_context.ebp = 0xd9fabb4a;
   849   raw_context.eip = 0x6913f540;
   850   raw_context.cs = 0xbffe6eda;
   851   raw_context.eflags = 0xb2ce1e2d;
   852   raw_context.esp = 0x659caaa4;
   853   raw_context.ss = 0x2e951ef7;
   854   Context context(dump, raw_context);
   856   Exception exception(dump, context,
   857                       0x1234abcd, // thread id
   858                       0xdcba4321, // exception code
   859                       0xf0e0d0c0, // exception flags
   860                       0x0919a9b9c9d9e9f9ULL); // exception address
   862   dump.Add(&context);
   863   dump.Add(&exception);
   865   // Add system info.  This is needed as an alternative source for CPU type
   866   // information.  Note, that the CPU flags were intentionally skipped from
   867   // the context_flags and this alternative source is required.
   868   String csd_version(dump, "Service Pack 2");
   869   SystemInfo system_info(dump, SystemInfo::windows_x86, csd_version);
   870   dump.Add(&system_info);
   871   dump.Add(&csd_version);
   873   dump.Finish();
   875   string contents;
   876   ASSERT_TRUE(dump.GetContents(&contents));
   878   istringstream minidump_stream(contents);
   879   Minidump minidump(minidump_stream);
   880   ASSERT_TRUE(minidump.Read());
   881   ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());
   883   MinidumpException *md_exception = minidump.GetException();
   884   ASSERT_TRUE(md_exception != NULL);
   886   uint32_t thread_id;
   887   ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
   888   ASSERT_EQ(0x1234abcdU, thread_id);
   890   const MDRawExceptionStream* raw_exception = md_exception->exception();
   891   ASSERT_TRUE(raw_exception != NULL);
   892   EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
   893   EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
   894   EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
   895             raw_exception->exception_record.exception_address);
   897   MinidumpContext *md_context = md_exception->GetContext();
   898   ASSERT_TRUE(md_context != NULL);
   900   ASSERT_EQ((uint32_t) MD_CONTEXT_X86, md_context->GetContextCPU());
   901   const MDRawContextX86 *md_raw_context = md_context->GetContextX86();
   902   ASSERT_TRUE(md_raw_context != NULL);
   904   // Even though the CPU flags were missing from the context_flags, the
   905   // GetContext call above is expected to load the missing CPU flags from the
   906   // system info stream and set the CPU type bits in context_flags.
   907   ASSERT_EQ((uint32_t) (MD_CONTEXT_X86), md_raw_context->context_flags);
   909   EXPECT_EQ(0x3ecba80dU, raw_context.edi);
   910   EXPECT_EQ(0x382583b9U, raw_context.esi);
   911   EXPECT_EQ(0x7fccc03fU, raw_context.ebx);
   912   EXPECT_EQ(0xf62f8ec2U, raw_context.edx);
   913   EXPECT_EQ(0x46a6a6a8U, raw_context.ecx);
   914   EXPECT_EQ(0x6a5025e2U, raw_context.eax);
   915   EXPECT_EQ(0xd9fabb4aU, raw_context.ebp);
   916   EXPECT_EQ(0x6913f540U, raw_context.eip);
   917   EXPECT_EQ(0xbffe6edaU, raw_context.cs);
   918   EXPECT_EQ(0xb2ce1e2dU, raw_context.eflags);
   919   EXPECT_EQ(0x659caaa4U, raw_context.esp);
   920   EXPECT_EQ(0x2e951ef7U, raw_context.ss);
   921 }
   923 // This test covers a scenario where a dump contains an exception but the
   924 // context record of the exception is missing the CPU type information in its
   925 // context_flags.  The dump has no system info stream so it is imposible to
   926 // deduce the CPU type, hence the context record is unusable.
   927 TEST(Dump, OneExceptionX86NoCPUFlagsNoSystemInfo) {
   928   Dump dump(0, kLittleEndian);
   930   MDRawContextX86 raw_context;
   931   // Intentionally not setting CPU type in the context_flags
   932   raw_context.context_flags = 0;
   933   raw_context.edi = 0x3ecba80d;
   934   raw_context.esi = 0x382583b9;
   935   raw_context.ebx = 0x7fccc03f;
   936   raw_context.edx = 0xf62f8ec2;
   937   raw_context.ecx = 0x46a6a6a8;
   938   raw_context.eax = 0x6a5025e2;
   939   raw_context.ebp = 0xd9fabb4a;
   940   raw_context.eip = 0x6913f540;
   941   raw_context.cs = 0xbffe6eda;
   942   raw_context.eflags = 0xb2ce1e2d;
   943   raw_context.esp = 0x659caaa4;
   944   raw_context.ss = 0x2e951ef7;
   945   Context context(dump, raw_context);
   947   Exception exception(dump, context,
   948                       0x1234abcd, // thread id
   949                       0xdcba4321, // exception code
   950                       0xf0e0d0c0, // exception flags
   951                       0x0919a9b9c9d9e9f9ULL); // exception address
   953   dump.Add(&context);
   954   dump.Add(&exception);
   955   dump.Finish();
   957   string contents;
   958   ASSERT_TRUE(dump.GetContents(&contents));
   960   istringstream minidump_stream(contents);
   961   Minidump minidump(minidump_stream);
   962   ASSERT_TRUE(minidump.Read());
   963   ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
   965   MinidumpException *md_exception = minidump.GetException();
   966   ASSERT_TRUE(md_exception != NULL);
   968   uint32_t thread_id;
   969   ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
   970   ASSERT_EQ(0x1234abcdU, thread_id);
   972   const MDRawExceptionStream* raw_exception = md_exception->exception();
   973   ASSERT_TRUE(raw_exception != NULL);
   974   EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
   975   EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
   976   EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
   977             raw_exception->exception_record.exception_address);
   979   // The context record of the exception is unusable because the context_flags
   980   // don't have CPU type information and at the same time the minidump lacks
   981   // system info stream so it is impossible to deduce the CPU type.
   982   MinidumpContext *md_context = md_exception->GetContext();
   983   ASSERT_EQ(NULL, md_context);
   984 }
   986 TEST(Dump, OneExceptionARM) {
   987   Dump dump(0, kLittleEndian);
   989   MDRawContextARM raw_context;
   990   raw_context.context_flags = MD_CONTEXT_ARM_INTEGER;
   991   raw_context.iregs[0] = 0x3ecba80d;
   992   raw_context.iregs[1] = 0x382583b9;
   993   raw_context.iregs[2] = 0x7fccc03f;
   994   raw_context.iregs[3] = 0xf62f8ec2;
   995   raw_context.iregs[4] = 0x46a6a6a8;
   996   raw_context.iregs[5] = 0x6a5025e2;
   997   raw_context.iregs[6] = 0xd9fabb4a;
   998   raw_context.iregs[7] = 0x6913f540;
   999   raw_context.iregs[8] = 0xbffe6eda;
  1000   raw_context.iregs[9] = 0xb2ce1e2d;
  1001   raw_context.iregs[10] = 0x659caaa4;
  1002   raw_context.iregs[11] = 0xf0e0d0c0;
  1003   raw_context.iregs[12] = 0xa9b8c7d6;
  1004   raw_context.iregs[13] = 0x12345678;
  1005   raw_context.iregs[14] = 0xabcd1234;
  1006   raw_context.iregs[15] = 0x10203040;
  1007   raw_context.cpsr = 0x2e951ef7;
  1008   Context context(dump, raw_context);
  1010   Exception exception(dump, context,
  1011                       0x1234abcd, // thread id
  1012                       0xdcba4321, // exception code
  1013                       0xf0e0d0c0, // exception flags
  1014                       0x0919a9b9c9d9e9f9ULL); // exception address
  1016   dump.Add(&context);
  1017   dump.Add(&exception);
  1018   dump.Finish();
  1020   string contents;
  1021   ASSERT_TRUE(dump.GetContents(&contents));
  1023   istringstream minidump_stream(contents);
  1024   Minidump minidump(minidump_stream);
  1025   ASSERT_TRUE(minidump.Read());
  1026   ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
  1028   MinidumpException *md_exception = minidump.GetException();
  1029   ASSERT_TRUE(md_exception != NULL);
  1031   uint32_t thread_id;
  1032   ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
  1033   ASSERT_EQ(0x1234abcdU, thread_id);
  1035   const MDRawExceptionStream* raw_exception = md_exception->exception();
  1036   ASSERT_TRUE(raw_exception != NULL);
  1037   EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
  1038   EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
  1039   EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
  1040             raw_exception->exception_record.exception_address);
  1042   MinidumpContext *md_context = md_exception->GetContext();
  1043   ASSERT_TRUE(md_context != NULL);
  1044   ASSERT_EQ((uint32_t) MD_CONTEXT_ARM, md_context->GetContextCPU());
  1045   const MDRawContextARM *md_raw_context = md_context->GetContextARM();
  1046   ASSERT_TRUE(md_raw_context != NULL);
  1047   ASSERT_EQ((uint32_t) MD_CONTEXT_ARM_INTEGER,
  1048             (md_raw_context->context_flags
  1049              & MD_CONTEXT_ARM_INTEGER));
  1050   EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]);
  1051   EXPECT_EQ(0x382583b9U, raw_context.iregs[1]);
  1052   EXPECT_EQ(0x7fccc03fU, raw_context.iregs[2]);
  1053   EXPECT_EQ(0xf62f8ec2U, raw_context.iregs[3]);
  1054   EXPECT_EQ(0x46a6a6a8U, raw_context.iregs[4]);
  1055   EXPECT_EQ(0x6a5025e2U, raw_context.iregs[5]);
  1056   EXPECT_EQ(0xd9fabb4aU, raw_context.iregs[6]);
  1057   EXPECT_EQ(0x6913f540U, raw_context.iregs[7]);
  1058   EXPECT_EQ(0xbffe6edaU, raw_context.iregs[8]);
  1059   EXPECT_EQ(0xb2ce1e2dU, raw_context.iregs[9]);
  1060   EXPECT_EQ(0x659caaa4U, raw_context.iregs[10]);
  1061   EXPECT_EQ(0xf0e0d0c0U, raw_context.iregs[11]);
  1062   EXPECT_EQ(0xa9b8c7d6U, raw_context.iregs[12]);
  1063   EXPECT_EQ(0x12345678U, raw_context.iregs[13]);
  1064   EXPECT_EQ(0xabcd1234U, raw_context.iregs[14]);
  1065   EXPECT_EQ(0x10203040U, raw_context.iregs[15]);
  1066   EXPECT_EQ(0x2e951ef7U, raw_context.cpsr);
  1069 TEST(Dump, OneExceptionARMOldFlags) {
  1070   Dump dump(0, kLittleEndian);
  1072   MDRawContextARM raw_context;
  1073   // MD_CONTEXT_ARM_INTEGER, but with _OLD
  1074   raw_context.context_flags = MD_CONTEXT_ARM_OLD | 0x00000002;
  1075   raw_context.iregs[0] = 0x3ecba80d;
  1076   raw_context.iregs[1] = 0x382583b9;
  1077   raw_context.iregs[2] = 0x7fccc03f;
  1078   raw_context.iregs[3] = 0xf62f8ec2;
  1079   raw_context.iregs[4] = 0x46a6a6a8;
  1080   raw_context.iregs[5] = 0x6a5025e2;
  1081   raw_context.iregs[6] = 0xd9fabb4a;
  1082   raw_context.iregs[7] = 0x6913f540;
  1083   raw_context.iregs[8] = 0xbffe6eda;
  1084   raw_context.iregs[9] = 0xb2ce1e2d;
  1085   raw_context.iregs[10] = 0x659caaa4;
  1086   raw_context.iregs[11] = 0xf0e0d0c0;
  1087   raw_context.iregs[12] = 0xa9b8c7d6;
  1088   raw_context.iregs[13] = 0x12345678;
  1089   raw_context.iregs[14] = 0xabcd1234;
  1090   raw_context.iregs[15] = 0x10203040;
  1091   raw_context.cpsr = 0x2e951ef7;
  1092   Context context(dump, raw_context);
  1094   Exception exception(dump, context,
  1095                       0x1234abcd, // thread id
  1096                       0xdcba4321, // exception code
  1097                       0xf0e0d0c0, // exception flags
  1098                       0x0919a9b9c9d9e9f9ULL); // exception address
  1100   dump.Add(&context);
  1101   dump.Add(&exception);
  1102   dump.Finish();
  1104   string contents;
  1105   ASSERT_TRUE(dump.GetContents(&contents));
  1107   istringstream minidump_stream(contents);
  1108   Minidump minidump(minidump_stream);
  1109   ASSERT_TRUE(minidump.Read());
  1110   ASSERT_EQ(1U, minidump.GetDirectoryEntryCount());
  1112   MinidumpException *md_exception = minidump.GetException();
  1113   ASSERT_TRUE(md_exception != NULL);
  1115   uint32_t thread_id;
  1116   ASSERT_TRUE(md_exception->GetThreadID(&thread_id));
  1117   ASSERT_EQ(0x1234abcdU, thread_id);
  1119   const MDRawExceptionStream* raw_exception = md_exception->exception();
  1120   ASSERT_TRUE(raw_exception != NULL);
  1121   EXPECT_EQ(0xdcba4321, raw_exception->exception_record.exception_code);
  1122   EXPECT_EQ(0xf0e0d0c0, raw_exception->exception_record.exception_flags);
  1123   EXPECT_EQ(0x0919a9b9c9d9e9f9ULL,
  1124             raw_exception->exception_record.exception_address);
  1126   MinidumpContext *md_context = md_exception->GetContext();
  1127   ASSERT_TRUE(md_context != NULL);
  1128   ASSERT_EQ((uint32_t) MD_CONTEXT_ARM, md_context->GetContextCPU());
  1129   const MDRawContextARM *md_raw_context = md_context->GetContextARM();
  1130   ASSERT_TRUE(md_raw_context != NULL);
  1131   ASSERT_EQ((uint32_t) MD_CONTEXT_ARM_INTEGER,
  1132             (md_raw_context->context_flags
  1133              & MD_CONTEXT_ARM_INTEGER));
  1134   EXPECT_EQ(0x3ecba80dU, raw_context.iregs[0]);
  1135   EXPECT_EQ(0x382583b9U, raw_context.iregs[1]);
  1136   EXPECT_EQ(0x7fccc03fU, raw_context.iregs[2]);
  1137   EXPECT_EQ(0xf62f8ec2U, raw_context.iregs[3]);
  1138   EXPECT_EQ(0x46a6a6a8U, raw_context.iregs[4]);
  1139   EXPECT_EQ(0x6a5025e2U, raw_context.iregs[5]);
  1140   EXPECT_EQ(0xd9fabb4aU, raw_context.iregs[6]);
  1141   EXPECT_EQ(0x6913f540U, raw_context.iregs[7]);
  1142   EXPECT_EQ(0xbffe6edaU, raw_context.iregs[8]);
  1143   EXPECT_EQ(0xb2ce1e2dU, raw_context.iregs[9]);
  1144   EXPECT_EQ(0x659caaa4U, raw_context.iregs[10]);
  1145   EXPECT_EQ(0xf0e0d0c0U, raw_context.iregs[11]);
  1146   EXPECT_EQ(0xa9b8c7d6U, raw_context.iregs[12]);
  1147   EXPECT_EQ(0x12345678U, raw_context.iregs[13]);
  1148   EXPECT_EQ(0xabcd1234U, raw_context.iregs[14]);
  1149   EXPECT_EQ(0x10203040U, raw_context.iregs[15]);
  1150   EXPECT_EQ(0x2e951ef7U, raw_context.cpsr);
  1153 }  // namespace

mercurial