Coverage for /Syzygy/minidump/minidump_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%1241240.C++test

Line-by-line coverage:

   1    :  // Copyright 2015 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  
  15    :  #include "syzygy/minidump/minidump.h"
  16    :  
  17    :  #include <stdint.h>
  18    :  #include <string>
  19    :  
  20    :  #include "base/files/file_util.h"
  21    :  #include "base/files/scoped_temp_dir.h"
  22    :  #include "base/strings/utf_string_conversions.h"
  23    :  #include "gtest/gtest.h"
  24    :  #include "syzygy/core/unittest_util.h"
  25    :  #include "syzygy/minidump/unittest_util.h"
  26    :  
  27    :  namespace minidump {
  28    :  
  29    :  class MinidumpTest : public testing::Test {
  30    :   public:
  31  E :    void SetUp() override {
  32  E :      ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
  33  E :      dump_file_ = temp_dir_.path().Append(L"minidump.dmp");
  34  E :    }
  35    :  
  36  E :    const base::FilePath& dump_file() const { return dump_file_; }
  37    :  
  38    :   private:
  39    :    base::FilePath dump_file_;
  40    :    base::ScopedTempDir temp_dir_;
  41    :  };
  42    :  
  43  E :  TEST_F(MinidumpTest, OpenSuccedsForValidFile) {
  44  E :    Minidump minidump;
  45    :  
  46  E :    ASSERT_TRUE(minidump.Open(testing::TestMinidumps::GetNotepad32Dump()));
  47  E :    ASSERT_LE(1U, minidump.directory().size());
  48  E :  }
  49    :  
  50  E :  TEST_F(MinidumpTest, OpenFailsForInvalidFile) {
  51  E :    Minidump minidump;
  52    :  
  53    :    // Try opening a non-existing file.
  54  E :    ASSERT_FALSE(minidump.Open(dump_file()));
  55    :  
  56    :    // Create an empty file, opening it should fail.
  57    :    {
  58  E :      base::ScopedFILE tmp(base::OpenFile(dump_file(), "wb"));
  59  E :    }
  60  E :    ASSERT_FALSE(minidump.Open(dump_file()));
  61    :  
  62    :    // Create a file with a header, but an invalid signature.
  63    :    {
  64  E :      base::ScopedFILE tmp(base::OpenFile(dump_file(), "wb"));
  65    :  
  66  E :      MINIDUMP_HEADER hdr = {0};
  67  E :      ASSERT_EQ(sizeof(hdr), fwrite(&hdr, sizeof(char), sizeof(hdr), tmp.get()));
  68  E :    }
  69  E :    ASSERT_FALSE(minidump.Open(dump_file()));
  70    :  
  71    :    // Create a file with a valid signature, but a zero-length directory.
  72    :    {
  73  E :      base::ScopedFILE tmp(base::OpenFile(dump_file(), "wb"));
  74    :  
  75  E :      MINIDUMP_HEADER hdr = {0};
  76  E :      hdr.Signature = MINIDUMP_SIGNATURE;
  77  E :      ASSERT_EQ(sizeof(hdr), fwrite(&hdr, sizeof(char), sizeof(hdr), tmp.get()));
  78  E :    }
  79  E :    ASSERT_FALSE(minidump.Open(dump_file()));
  80    :  
  81    :    // Create a file with a valid header, but a missing directory.
  82    :    {
  83  E :      base::ScopedFILE tmp(base::OpenFile(dump_file(), "wb"));
  84    :  
  85  E :      MINIDUMP_HEADER hdr = {0};
  86  E :      hdr.Signature = MINIDUMP_SIGNATURE;
  87  E :      hdr.NumberOfStreams = 10;
  88  E :      hdr.StreamDirectoryRva = sizeof(hdr);
  89  E :      ASSERT_EQ(sizeof(hdr), fwrite(&hdr, sizeof(char), sizeof(hdr), tmp.get()));
  90  E :    }
  91  E :    ASSERT_FALSE(minidump.Open(dump_file()));
  92  E :  }
  93    :  
  94  E :  TEST_F(MinidumpTest, StreamTest) {
  95    :    // Create a file with some data to test the streams.
  96    :    {
  97  E :      base::ScopedFILE tmp(base::OpenFile(dump_file(), "wb"));
  98    :  
  99  E :      MINIDUMP_HEADER hdr = {0};
 100  E :      hdr.Signature = MINIDUMP_SIGNATURE;
 101  E :      hdr.NumberOfStreams = 1;
 102  E :      hdr.StreamDirectoryRva = sizeof(hdr);
 103  E :      ASSERT_EQ(sizeof(hdr), fwrite(&hdr, sizeof(char), sizeof(hdr), tmp.get()));
 104    :  
 105  E :      for (uint32_t i = 0; i < 100; ++i)
 106  E :        ASSERT_EQ(sizeof(i), fwrite(&i, sizeof(char), sizeof(i), tmp.get()));
 107  E :    }
 108    :  
 109  E :    Minidump minidump;
 110  E :    ASSERT_TRUE(minidump.Open(dump_file()));
 111    :  
 112    :    // Make a short, arbitrary location.
 113  E :    MINIDUMP_LOCATION_DESCRIPTOR loc = { 7, sizeof(MINIDUMP_HEADER) };
 114  E :    Minidump::Stream test = minidump.GetStreamFor(loc);
 115    :  
 116  E :    EXPECT_EQ(7U, test.GetRemainingBytes());
 117    :  
 118    :    // Read the first integer.
 119  E :    const uint32_t kSentinel = 0xCAFEBABE;
 120  E :    uint32_t tmp = kSentinel;
 121  E :    ASSERT_TRUE(test.ReadElement(&tmp));
 122  E :    EXPECT_EQ(0U, tmp);
 123  E :    EXPECT_EQ(3U, test.GetRemainingBytes());
 124    :  
 125    :    // Reading another integer should fail, as the stream doesn't cover it.
 126  E :    tmp = kSentinel;
 127  E :    ASSERT_FALSE(test.ReadElement(&tmp));
 128    :    // The failing read must not modify the input.
 129  E :    EXPECT_EQ(kSentinel, tmp);
 130    :  
 131    :    // Try the same thing with byte reads.
 132  E :    uint8_t bytes[10] = {};
 133  E :    ASSERT_FALSE(test.ReadBytes(4, &bytes));
 134    :  
 135    :    // A three-byte read should succeed.
 136  E :    ASSERT_TRUE(test.ReadBytes(3, &bytes));
 137  E :    EXPECT_EQ(0U, test.GetRemainingBytes());
 138    :  
 139    :    // Little-endian byte order assumed.
 140  E :    EXPECT_EQ(1U, bytes[0]);
 141  E :    EXPECT_EQ(0U, bytes[1]);
 142  E :    EXPECT_EQ(0U, bytes[2]);
 143    :  
 144    :    // No moar data.
 145  E :    EXPECT_FALSE(test.ReadBytes(1, &bytes));
 146    :  
 147    :    // Reset the stream to test reading via a string.
 148  E :    test = minidump.GetStreamFor(loc);
 149  E :    std::string data;
 150  E :    ASSERT_TRUE(test.ReadBytes(1, &data));
 151  E :    EXPECT_EQ(6U, test.GetRemainingBytes());
 152  E :    EXPECT_EQ(1U, data.size());
 153  E :    EXPECT_EQ(0, data[0]);
 154  E :  }
 155    :  
 156  E :  TEST_F(MinidumpTest, FindNextStream) {
 157  E :    Minidump minidump;
 158    :  
 159  E :    ASSERT_TRUE(minidump.Open(testing::TestMinidumps::GetNotepad32Dump()));
 160    :  
 161    :    Minidump::Stream sys_info =
 162  E :        minidump.FindNextStream(nullptr, SystemInfoStream);
 163  E :    ASSERT_TRUE(sys_info.IsValid());
 164    :  
 165  E :    MINIDUMP_SYSTEM_INFO info = {};
 166  E :    EXPECT_TRUE(sys_info.ReadElement(&info));
 167    :  
 168    :    Minidump::Stream invalid =
 169  E :        minidump.FindNextStream(&sys_info, SystemInfoStream);
 170  E :    EXPECT_FALSE(invalid.IsValid());
 171  E :  }
 172    :  
 173  E :  TEST_F(MinidumpTest, ReadThreadInfo) {
 174  E :    Minidump minidump;
 175    :  
 176  E :    ASSERT_TRUE(minidump.Open(testing::TestMinidumps::GetNotepad32Dump()));
 177    :  
 178    :    Minidump::Stream thread_list =
 179  E :        minidump.FindNextStream(nullptr, ThreadListStream);
 180  E :    ASSERT_TRUE(thread_list.IsValid());
 181    :  
 182  E :    ULONG32 num_threads = 0;
 183  E :    ASSERT_TRUE(thread_list.ReadElement(&num_threads));
 184    :  
 185  E :    for (size_t i = 0; i < num_threads; ++i) {
 186  E :      MINIDUMP_THREAD thread = {};
 187  E :      ASSERT_TRUE(thread_list.ReadElement(&thread));
 188    :  
 189  E :      Minidump::Stream thread_memory = minidump.GetStreamFor(thread.Stack.Memory);
 190  E :      EXPECT_TRUE(thread_memory.IsValid());
 191    :  
 192    :      Minidump::Stream thread_context =
 193  E :          minidump.GetStreamFor(thread.ThreadContext);
 194  E :      EXPECT_TRUE(thread_context.IsValid());
 195    :  
 196  E :      CONTEXT ctx = {};
 197  E :      EXPECT_TRUE(thread_context.ReadElement(&ctx));
 198  E :    }
 199  E :  }
 200    :  
 201  E :  TEST_F(MinidumpTest, ReadString) {
 202  E :    wchar_t kSomeString[] = L"some string";
 203    :  
 204    :    // Create a minimal file to test reading a string.
 205    :    {
 206  E :      base::ScopedFILE tmp(base::OpenFile(dump_file(), "wb"));
 207    :  
 208    :      // Valid header.
 209  E :      MINIDUMP_HEADER hdr = {0};
 210  E :      hdr.Signature = MINIDUMP_SIGNATURE;
 211  E :      hdr.NumberOfStreams = 1;
 212  E :      hdr.StreamDirectoryRva = sizeof(hdr);
 213  E :      ASSERT_EQ(sizeof(hdr), fwrite(&hdr, sizeof(char), sizeof(hdr), tmp.get()));
 214    :  
 215    :      // Dummy directory.
 216  E :      MINIDUMP_DIRECTORY directory = {0};
 217    :      ASSERT_EQ(sizeof(directory),
 218  E :                fwrite(&directory, sizeof(char), sizeof(directory), tmp.get()));
 219    :  
 220    :      // A string. Note that although a null terminating character is written, it
 221    :      // is not counted in the size written to the file.
 222  E :      ULONG32 size_bytes = sizeof(kSomeString) - sizeof(wchar_t);
 223    :      ASSERT_EQ(sizeof(ULONG32),
 224  E :                fwrite(&size_bytes, sizeof(char), sizeof(ULONG32), tmp.get()));
 225    :      ASSERT_EQ(sizeof(kSomeString), fwrite(&kSomeString, sizeof(char),
 226  E :                                            sizeof(kSomeString), tmp.get()));
 227  E :    }
 228    :  
 229  E :    Minidump minidump;
 230  E :    ASSERT_TRUE(minidump.Open(dump_file()));
 231    :  
 232    :    MINIDUMP_LOCATION_DESCRIPTOR loc = {
 233    :        static_cast<ULONG32>(-1),
 234  E :        sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY)};
 235  E :    Minidump::Stream test = minidump.GetStreamFor(loc);
 236  E :    std::wstring recovered;
 237  E :    ASSERT_TRUE(test.ReadString(&recovered));
 238  E :    ASSERT_EQ(kSomeString, recovered);
 239  E :  }
 240    :  
 241    :  }  // namespace minidump

Coverage information generated Thu Jan 14 17:40:38 2016.