Coverage for /Syzygy/refinery/validators/exception_handler_validator_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
98.9%92930.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/refinery/validators/exception_handler_validator.h"
  16    :  
  17    :  #include <string>
  18    :  
  19    :  #include "base/logging.h"
  20    :  #include "gtest/gtest.h"
  21    :  #include "syzygy/minidump/minidump.h"
  22    :  #include "syzygy/minidump/unittest_util.h"
  23    :  #include "syzygy/refinery/unittest_util.h"
  24    :  #include "syzygy/refinery/analyzers/memory_analyzer.h"
  25    :  #include "syzygy/refinery/analyzers/thread_analyzer.h"
  26    :  #include "syzygy/refinery/process_state/process_state.h"
  27    :  #include "syzygy/refinery/process_state/process_state_util.h"
  28    :  #include "syzygy/refinery/process_state/refinery.pb.h"
  29    :  
  30    :  namespace refinery {
  31    :  
  32    :  namespace {
  33    :  
  34  E :  bool RunAnalysis(const minidump::Minidump& dump, ProcessState* process_state) {
  35  E :    MemoryAnalyzer memory_analyzer;
  36    :    if (memory_analyzer.Analyze(dump, process_state) !=
  37  E :        Analyzer::ANALYSIS_COMPLETE) {
  38  i :      return false;
  39    :    }
  40  E :    ThreadAnalyzer thread_analyzer;
  41    :    return thread_analyzer.Analyze(dump, process_state) ==
  42  E :           Analyzer::ANALYSIS_COMPLETE;
  43  E :  }
  44    :  
  45    :  testing::MinidumpSpecification::MemorySpecification CreateTibMemorySpec(
  46    :      Address tib_addr,
  47  E :      Address exception_registration_record_addr) {
  48  E :    std::string tib_buffer;
  49  E :    tib_buffer.resize(sizeof(NT_TIB));
  50  E :    NT_TIB* tib = reinterpret_cast<NT_TIB*>(&tib_buffer.at(0));
  51    :    tib->ExceptionList = reinterpret_cast<EXCEPTION_REGISTRATION_RECORD*>(
  52  E :        exception_registration_record_addr);
  53    :    return testing::MinidumpSpecification::MemorySpecification(tib_addr,
  54  E :                                                               tib_buffer);
  55  E :  }
  56    :  
  57  E :  void SetExceptionRegistrationRecordNext(void* buffer, Address next_addr) {
  58    :    EXCEPTION_REGISTRATION_RECORD* record =
  59  E :        reinterpret_cast<EXCEPTION_REGISTRATION_RECORD*>(buffer);
  60  E :    record->Next = reinterpret_cast<EXCEPTION_REGISTRATION_RECORD*>(next_addr);
  61  E :  }
  62    :  
  63    :  }  // namespace
  64    :  
  65  E :  TEST(ExceptionHandlerValidatorTest, AnalyzeMinidump) {
  66    :    // Process the minidump for memory and thread data.
  67  E :    ProcessState process_state;
  68    :  
  69  E :    minidump::Minidump minidump;
  70  E :    ASSERT_TRUE(minidump.Open(testing::TestMinidumps::GetNotepad32Dump()));
  71  E :    ASSERT_TRUE(RunAnalysis(minidump, &process_state));
  72    :  
  73    :    // Run the validator.
  74  E :    ValidationReport report;
  75  E :    ExceptionHandlerValidator validator;
  76    :    ASSERT_EQ(Validator::VALIDATION_COMPLETE,
  77  E :              validator.Validate(&process_state, &report));
  78  E :    ASSERT_EQ(0, report.error_size());
  79  E :  }
  80    :  
  81    :  namespace {
  82    :  const size_t kThreadId = 1U;
  83    :  const Address kStackAddr = 80ULL;
  84    :  const Address kStackSize = 2 * sizeof(EXCEPTION_REGISTRATION_RECORD);
  85    :  const Address kTebAddress = 8000ULL;
  86    :  }  // namespace
  87    :  
  88    :  class ExceptionHandlerValidatorSyntheticTest
  89    :      : public testing::SyntheticMinidumpTest {
  90    :   protected:
  91    :    void PerformTest(const std::string& stack_buffer,
  92    :                     bool include_teb,
  93    :                     Address exception_registration_record_addr,
  94    :                     Validator::ValidationResult expected_validation_result,
  95    :                     bool is_violation_expected,
  96  E :                     ViolationType expected_violation) {
  97    :      // Generate a synthetic minidump with a thread, as well as memory for its
  98    :      // stack and teb.
  99    :      testing::MinidumpSpecification::ThreadSpecification thread_spec(
 100  E :          kThreadId, kStackAddr, kStackSize);
 101  E :      thread_spec.SetTebAddress(kTebAddress);
 102    :  
 103    :      testing::MinidumpSpecification::MemorySpecification stack_memory_spec(
 104  E :          kStackAddr, stack_buffer);
 105  E :      testing::MinidumpSpecification spec;
 106  E :      ASSERT_TRUE(spec.AddMemoryRegion(stack_memory_spec));
 107    :  
 108  E :      if (include_teb) {
 109    :        testing::MinidumpSpecification::MemorySpecification teb_memory_spec =
 110  E :            CreateTibMemorySpec(kTebAddress, exception_registration_record_addr);
 111  E :        ASSERT_TRUE(spec.AddMemoryRegion(teb_memory_spec));
 112  E :      }
 113    :  
 114  E :      ASSERT_TRUE(spec.AddThread(thread_spec));
 115  E :      ASSERT_NO_FATAL_FAILURE(Serialize(spec));
 116    :  
 117    :      // Perform analysis and validation, then inspect the report.
 118  E :      ASSERT_NO_FATAL_FAILURE(Analyze());
 119  E :      ASSERT_EQ(expected_validation_result, Validate());
 120  E :      if (expected_validation_result != Validator::VALIDATION_COMPLETE) {
 121  E :        return;
 122    :      }
 123    :  
 124  E :      ASSERT_EQ(is_violation_expected ? 1 : 0, report_.error_size());
 125  E :      if (is_violation_expected)
 126  E :        ASSERT_EQ(expected_violation, report_.error(0).type());
 127  E :    }
 128    :  
 129  E :    void Analyze() {
 130  E :      minidump::Minidump minidump;
 131  E :      ASSERT_TRUE(minidump.Open(dump_file()));
 132  E :      ASSERT_TRUE(RunAnalysis(minidump, &process_state_));
 133  E :    }
 134    :  
 135  E :    Validator::ValidationResult Validate() {
 136  E :      ExceptionHandlerValidator validator;
 137  E :      return validator.Validate(&process_state_, &report_);
 138  E :    }
 139    :  
 140    :    ProcessState process_state_;
 141    :    ValidationReport report_;
 142    :  };
 143    :  
 144  E :  TEST_F(ExceptionHandlerValidatorSyntheticTest, TebNotInDumpTest) {
 145  E :    std::string stack_buffer;
 146  E :    stack_buffer.resize(kStackSize);
 147  E :    Address unused_addr = 0ULL;
 148    :    ASSERT_NO_FATAL_FAILURE(PerformTest(stack_buffer, false /* No Teb */,
 149    :                                        unused_addr, Validator::VALIDATION_ERROR,
 150  E :                                        false, VIOLATION_UNKNOWN));
 151  E :  }
 152    :  
 153    :  TEST_F(ExceptionHandlerValidatorSyntheticTest,
 154  E :         NoExceptionRegistrationRecordTest) {
 155  E :    std::string stack_buffer;
 156  E :    stack_buffer.resize(kStackSize);
 157  E :    Address no_exception_registration_record_addr = static_cast<Address>(-1);
 158    :    ASSERT_NO_FATAL_FAILURE(
 159    :        PerformTest(stack_buffer, true, no_exception_registration_record_addr,
 160    :                    Validator::VALIDATION_COMPLETE, true,
 161  E :                    VIOLATION_NO_EXCEPTION_REGISTRATION_RECORD));
 162  E :  }
 163    :  
 164    :  TEST_F(ExceptionHandlerValidatorSyntheticTest,
 165  E :         ExceptionRegistrationRecordNotInStackTest) {
 166  E :    std::string stack_buffer;
 167  E :    stack_buffer.resize(kStackSize);
 168  E :    Address exception_registration_record_addr = kStackAddr + kStackSize;
 169    :    ASSERT_NO_FATAL_FAILURE(
 170    :        PerformTest(stack_buffer, true, exception_registration_record_addr,
 171    :                    Validator::VALIDATION_COMPLETE, true,
 172  E :                    VIOLATION_EXCEPTION_REGISTRATION_RECORD_NOT_IN_STACK));
 173  E :  }
 174    :  
 175    :  TEST_F(ExceptionHandlerValidatorSyntheticTest,
 176  E :         ExceptionRegistrationRecordAddressIncreaseTest) {
 177  E :    std::string stack_buffer;
 178  E :    stack_buffer.resize(kStackSize);
 179  E :    size_t record_size = sizeof(EXCEPTION_REGISTRATION_RECORD);
 180    :    SetExceptionRegistrationRecordNext(&stack_buffer.at(0),
 181  E :                                       static_cast<Address>(-1));
 182  E :    SetExceptionRegistrationRecordNext(&stack_buffer.at(record_size), kStackAddr);
 183    :  
 184  E :    Address exception_registration_record_addr = kStackAddr + record_size;
 185    :    ASSERT_NO_FATAL_FAILURE(
 186    :        PerformTest(stack_buffer, true, exception_registration_record_addr,
 187    :                    Validator::VALIDATION_COMPLETE, true,
 188  E :                    VIOLATION_EXCEPTION_CHAIN_ADDRESS_DECREASE));
 189  E :  }
 190    :  
 191  E :  TEST_F(ExceptionHandlerValidatorSyntheticTest, BasicTest) {
 192  E :    std::string stack_buffer;
 193  E :    stack_buffer.resize(kStackSize);
 194  E :    size_t record_size = sizeof(EXCEPTION_REGISTRATION_RECORD);
 195    :    SetExceptionRegistrationRecordNext(&stack_buffer.at(0),
 196  E :                                       kStackAddr + record_size);
 197    :    SetExceptionRegistrationRecordNext(&stack_buffer.at(record_size),
 198  E :                                       static_cast<Address>(-1));
 199    :  
 200  E :    Address exception_registration_record_addr = kStackAddr;
 201    :    ASSERT_NO_FATAL_FAILURE(
 202    :        PerformTest(stack_buffer, true, exception_registration_record_addr,
 203  E :                    Validator::VALIDATION_COMPLETE, false, VIOLATION_UNKNOWN));
 204  E :  }
 205    :  
 206    :  }  // namespace refinery

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