Coverage for /Syzygy/refinery/analyzers/exception_analyzer_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
0.0%00101.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/analyzers/exception_analyzer.h"
  16    :  
  17    :  #include <stdint.h>
  18    :  
  19    :  #include <vector>
  20    :  
  21    :  #include "base/files/scoped_temp_dir.h"
  22    :  #include "gtest/gtest.h"
  23    :  #include "syzygy/minidump/minidump.h"
  24    :  #include "syzygy/minidump/unittest_util.h"
  25    :  #include "syzygy/refinery/unittest_util.h"
  26    :  #include "syzygy/refinery/analyzers/analyzer_util.h"
  27    :  #include "syzygy/refinery/analyzers/thread_analyzer.h"
  28    :  #include "syzygy/refinery/process_state/process_state.h"
  29    :  #include "syzygy/refinery/process_state/process_state_util.h"
  30    :  #include "syzygy/refinery/process_state/refinery.pb.h"
  31    :  
  32  m :  namespace refinery {
  33    :  
  34  m :  TEST(ExceptionAnalyzerTest, AnalyzeMinidump) {
  35  m :    minidump::FileMinidump minidump;
  36  m :    ASSERT_TRUE(minidump.Open(testing::TestMinidumps::GetNotepad32Dump()));
  37    :  
  38  m :    ProcessState process_state;
  39  m :    SimpleProcessAnalysis analysis(&process_state);
  40    :  
  41  m :    ThreadAnalyzer thread_analyzer;
  42  m :    ASSERT_EQ(Analyzer::ANALYSIS_COMPLETE,
  43  m :              thread_analyzer.Analyze(minidump, analysis));
  44    :  
  45  m :    ExceptionAnalyzer analyzer;
  46  m :    ASSERT_EQ(Analyzer::ANALYSIS_COMPLETE, analyzer.Analyze(minidump, analysis));
  47    :  
  48    :    // Ensure one thread has exception data.
  49  m :    StackLayerPtr stack_layer;
  50  m :    ASSERT_TRUE(process_state.FindLayer(&stack_layer));
  51  m :    for (StackRecordPtr stack : *stack_layer) {
  52  m :      const Stack& stack_proto = stack->data();
  53  m :      if (stack_proto.has_thread_info() &&
  54  m :          stack_proto.thread_info().has_exception())
  55  m :        return;
  56  m :    }
  57  m :    FAIL() << "No exception data found.";
  58  m :  }
  59    :  
  60  m :  class ExceptionAnalyzerSyntheticTest : public testing::SyntheticMinidumpTest {};
  61    :  
  62  m :  TEST_F(ExceptionAnalyzerSyntheticTest, NoExceptionTest) {
  63    :    // Create a minidump with no exception data.
  64  m :    const char kData[] = "ABCD";
  65  m :    testing::MinidumpSpecification::MemorySpecification mem_spec(80ULL, kData);
  66  m :    testing::MinidumpSpecification spec;
  67  m :    ASSERT_TRUE(spec.AddMemoryRegion(mem_spec));
  68  m :    ASSERT_NO_FATAL_FAILURE(Serialize(spec));
  69    :  
  70    :    // Ensure analysis succeeds.
  71  m :    minidump::FileMinidump minidump;
  72  m :    ASSERT_TRUE(minidump.Open(dump_file()));
  73    :  
  74  m :    ProcessState process_state;
  75  m :    SimpleProcessAnalysis analysis(&process_state);
  76  m :    ExceptionAnalyzer analyzer;
  77  m :    ASSERT_EQ(Analyzer::ANALYSIS_COMPLETE, analyzer.Analyze(minidump, analysis));
  78  m :  }
  79    :  
  80  m :  TEST_F(ExceptionAnalyzerSyntheticTest, BasicTest) {
  81  m :    using MemorySpecification =
  82  m :        testing::MinidumpSpecification::MemorySpecification;
  83  m :    using ThreadSpecification =
  84  m :        testing::MinidumpSpecification::ThreadSpecification;
  85  m :    using ExceptionSpecification =
  86  m :        testing::MinidumpSpecification::ExceptionSpecification;
  87    :  
  88    :    // Generate a synthetic minidump with an exception (as well as thread
  89    :    // information and backing memory).
  90  m :    const size_t kThreadId = 42;
  91  m :    const Address kStackAddr = 80ULL;
  92  m :    const Address kStackSize = 16U;
  93    :  
  94  m :    ThreadSpecification thread_spec(kThreadId, kStackAddr, kStackSize);
  95  m :    MemorySpecification memory_spec;
  96  m :    testing::MinidumpSpecification spec;
  97  m :    thread_spec.FillStackMemorySpecification(&memory_spec);
  98  m :    ASSERT_TRUE(spec.AddMemoryRegion(memory_spec));
  99  m :    ASSERT_TRUE(spec.AddThread(thread_spec));
 100  m :    ExceptionSpecification exception_spec(kThreadId);
 101  m :    ASSERT_TRUE(spec.AddException(exception_spec));
 102    :  
 103  m :    ASSERT_NO_FATAL_FAILURE(Serialize(spec));
 104    :  
 105    :    // Analyze.
 106  m :    minidump::FileMinidump minidump;
 107  m :    ASSERT_TRUE(minidump.Open(dump_file()));
 108    :  
 109  m :    ProcessState process_state;
 110  m :    SimpleProcessAnalysis analysis(&process_state);
 111  m :    ThreadAnalyzer thread_analyzer;
 112  m :    ASSERT_EQ(Analyzer::ANALYSIS_COMPLETE,
 113  m :              thread_analyzer.Analyze(minidump, analysis));
 114    :  
 115  m :    ExceptionAnalyzer analyzer;
 116  m :    ASSERT_EQ(Analyzer::ANALYSIS_COMPLETE, analyzer.Analyze(minidump, analysis));
 117    :  
 118    :    // Validate.
 119  m :    StackRecordPtr stack_record;
 120  m :    ASSERT_TRUE(process_state.FindStackRecord(kThreadId, &stack_record));
 121  m :    const Stack& stack_proto = stack_record->data();
 122  m :    ASSERT_TRUE(stack_proto.has_thread_info() &&
 123  m :                stack_proto.thread_info().has_exception());
 124  m :    const Exception& exception = stack_proto.thread_info().exception();
 125  m :    ASSERT_EQ(kThreadId, exception.thread_id());
 126  m :    ASSERT_EQ(exception_spec.exception_code, exception.exception_code());
 127  m :    ASSERT_EQ(exception_spec.exception_flags, exception.exception_flags());
 128  m :    ASSERT_EQ(exception_spec.exception_record, exception.exception_record());
 129  m :    ASSERT_EQ(exception_spec.exception_address, exception.exception_address());
 130  m :    ASSERT_EQ(exception_spec.exception_information.size(),
 131  m :              exception.exception_information_size());
 132  m :    ASSERT_EQ(exception_spec.exception_information[0],
 133  m :              exception.exception_information(0));
 134  m :    ASSERT_EQ(exception_spec.exception_information[1],
 135  m :              exception.exception_information(1));
 136    :  
 137    :    // Validate RegisterInformation once implemented.
 138  m :    const RegisterInformation& reg_info = exception.register_info();
 139  m :    const CONTEXT* ctx =
 140  m :        reinterpret_cast<const CONTEXT*>(&exception_spec.context_data.at(0));
 141  m :    ASSERT_EQ(ctx->SegGs, reg_info.seg_gs());
 142  m :    ASSERT_EQ(ctx->SegFs, reg_info.seg_fs());
 143  m :    ASSERT_EQ(ctx->SegEs, reg_info.seg_es());
 144  m :    ASSERT_EQ(ctx->SegDs, reg_info.seg_ds());
 145  m :    ASSERT_EQ(ctx->Edi, reg_info.edi());
 146  m :    ASSERT_EQ(ctx->Esi, reg_info.esi());
 147  m :    ASSERT_EQ(ctx->Ebx, reg_info.ebx());
 148  m :    ASSERT_EQ(ctx->Edx, reg_info.edx());
 149  m :    ASSERT_EQ(ctx->Ecx, reg_info.ecx());
 150  m :    ASSERT_EQ(ctx->Eax, reg_info.eax());
 151  m :    ASSERT_EQ(ctx->Ebp, reg_info.ebp());
 152  m :    ASSERT_EQ(ctx->Eip, reg_info.eip());
 153  m :    ASSERT_EQ(ctx->SegCs, reg_info.seg_cs());
 154  m :    ASSERT_EQ(ctx->EFlags, reg_info.eflags());
 155  m :    ASSERT_EQ(ctx->Esp, reg_info.esp());
 156  m :    ASSERT_EQ(ctx->SegSs, reg_info.seg_ss());
 157  m :  }
 158    :  
 159  m :  }  // namespace refinery

Coverage information generated Fri Jul 29 11:00:21 2016.