Coverage for /Syzygy/agent/asan/asan_runtime_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
99.0%1021030.C++test

Line-by-line coverage:

   1    :  // Copyright 2012 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/agent/asan/asan_runtime.h"
  16    :  
  17    :  #include "base/bind.h"
  18    :  #include "base/command_line.h"
  19    :  #include "base/environment.h"
  20    :  #include "base/string_number_conversions.h"
  21    :  #include "base/utf_string_conversions.h"
  22    :  #include "base/memory/scoped_ptr.h"
  23    :  #include "gtest/gtest.h"
  24    :  #include "syzygy/agent/asan/asan_heap.h"
  25    :  #include "syzygy/agent/asan/unittest_util.h"
  26    :  
  27    :  namespace agent {
  28    :  namespace asan {
  29    :  
  30    :  namespace {
  31    :  
  32    :  using agent::asan::AsanErrorInfo;
  33    :  using agent::asan::HeapProxy;
  34    :  
  35    :  // A derived class to expose protected members for unit-testing.
  36    :  class TestAsanRuntime : public AsanRuntime {
  37    :   public:
  38    :    using AsanRuntime::AsanFlags;
  39    :    using AsanRuntime::kBottomFramesToSkip;
  40    :    using AsanRuntime::kCompressionReportingPeriod;
  41    :    using AsanRuntime::kExitOnFailure;
  42    :    using AsanRuntime::kIgnoredStackIds;
  43    :    using AsanRuntime::kQuarantineSize;
  44    :    using AsanRuntime::kSyzyAsanEnvVar;
  45    :    using AsanRuntime::PropagateFlagsValues;
  46    :    using AsanRuntime::flags;
  47    :    using AsanRuntime::set_flags;
  48    :  };
  49    :  
  50    :  class AsanRuntimeTest : public testing::TestWithAsanLogger {
  51    :   public:
  52  E :    AsanRuntimeTest() : current_command_line_(CommandLine::NO_PROGRAM) {
  53  E :    }
  54    :  
  55  E :    void SetUp() OVERRIDE {
  56  E :      testing::TestWithAsanLogger::SetUp();
  57  E :      scoped_ptr<base::Environment> env(base::Environment::Create());
  58  E :      ASSERT_TRUE(env.get() != NULL);
  59  E :      env->UnSetVar(TestAsanRuntime::kSyzyAsanEnvVar);
  60    :  
  61    :      // Setup the "global" state.
  62  E :      HeapProxy::Init();
  63  E :      StackCapture::Init();
  64  E :      StackCaptureCache::Init();
  65  E :    }
  66    :  
  67    :    // The test runtime instance.
  68    :    TestAsanRuntime asan_runtime_;
  69    :  
  70    :    // The value of the command-line that we want to test.
  71    :    CommandLine current_command_line_;
  72    :  };
  73    :  
  74    :  bool callback_called = false;
  75    :  
  76    :  // A simple callback that change the value of a boolean to indicate that it has
  77    :  // been called.
  78  E :  void TestCallback(CONTEXT* context, AsanErrorInfo* error_info) {
  79  E :    callback_called = true;
  80  E :  }
  81    :  
  82    :  }  // namespace
  83    :  
  84  E :  TEST_F(AsanRuntimeTest, SetUpAndTearDown) {
  85    :    ASSERT_NO_FATAL_FAILURE(
  86  E :        asan_runtime_.SetUp(current_command_line_.GetCommandLineString()));
  87  E :    ASSERT_NO_FATAL_FAILURE(asan_runtime_.TearDown());
  88  E :  }
  89    :  
  90  E :  TEST_F(AsanRuntimeTest, OnError) {
  91    :    ASSERT_NO_FATAL_FAILURE(
  92  E :        asan_runtime_.SetUp(current_command_line_.GetCommandLineString()));
  93  E :    asan_runtime_.SetErrorCallBack(base::Bind(&TestCallback));
  94  E :    callback_called = false;
  95    :    CONTEXT context;
  96  E :    RtlCaptureContext(&context);
  97  E :    StackCapture stack;
  98  E :    stack.InitFromStack();
  99  E :    AsanErrorInfo bad_access_info = {};
 100  E :    asan_runtime_.OnError(&context, &bad_access_info);
 101  E :    ASSERT_TRUE(callback_called);
 102  E :    ASSERT_NO_FATAL_FAILURE(asan_runtime_.TearDown());
 103  E :  }
 104    :  
 105  E :  TEST_F(AsanRuntimeTest, SetDefaultQuarantineMaxSize) {
 106    :    // Initialize the flags with the original command line.
 107    :    ASSERT_NO_FATAL_FAILURE(
 108  E :        asan_runtime_.SetUp(current_command_line_.GetCommandLineString()));
 109    :  
 110    :    // Double the max size of the quarantine.
 111    :    unsigned int quarantine_max_size =
 112  E :        HeapProxy::default_quarantine_max_size() * 2;
 113    :    // Increments the quarantine max size if it was set to 0.
 114  E :    if (quarantine_max_size == 0)
 115  i :      quarantine_max_size++;
 116  E :    DCHECK_GT(quarantine_max_size, 0U);
 117  E :    std::string quarantine_max_size_str = base::UintToString(quarantine_max_size);
 118    :    current_command_line_.AppendSwitchASCII(TestAsanRuntime::kQuarantineSize,
 119  E :                                            quarantine_max_size_str);
 120    :  
 121    :    // Tear down the runtime and restart it with a different command line.
 122  E :    ASSERT_NO_FATAL_FAILURE(asan_runtime_.TearDown());
 123    :    ASSERT_NO_FATAL_FAILURE(
 124  E :        asan_runtime_.SetUp(current_command_line_.GetCommandLineString()));
 125    :  
 126    :    // Ensure that the quarantine max size has been modified.
 127  E :    EXPECT_EQ(quarantine_max_size, HeapProxy::default_quarantine_max_size());
 128    :  
 129    :    // Ensure that the heap proxies use the new quarantine max size.
 130  E :    HeapProxy heap_proxy(asan_runtime_.stack_cache(), asan_runtime_.logger());
 131  E :    ASSERT_TRUE(heap_proxy.Create(0, 0, 0));
 132  E :    EXPECT_EQ(quarantine_max_size, heap_proxy.quarantine_max_size());
 133  E :    ASSERT_TRUE(heap_proxy.Destroy());
 134  E :  }
 135    :  
 136  E :  TEST_F(AsanRuntimeTest, SetCompressionReportingPeriod) {
 137    :    ASSERT_EQ(StackCaptureCache::GetDefaultCompressionReportingPeriod(),
 138  E :              StackCaptureCache::compression_reporting_period());
 139    :  
 140    :    size_t new_period =
 141  E :        StackCaptureCache::GetDefaultCompressionReportingPeriod() + 1024;
 142  E :    std::string new_period_str = base::UintToString(new_period);
 143    :    current_command_line_.AppendSwitchASCII(
 144  E :        TestAsanRuntime::kCompressionReportingPeriod, new_period_str);
 145    :  
 146    :    ASSERT_NO_FATAL_FAILURE(
 147  E :        asan_runtime_.SetUp(current_command_line_.GetCommandLineString()));
 148    :  
 149    :    // Ensure that the compression reporting period has been modified.
 150  E :    EXPECT_EQ(new_period, StackCaptureCache::compression_reporting_period());
 151  E :  }
 152    :  
 153  E :  TEST_F(AsanRuntimeTest, SetBottomFramesToSkip) {
 154  E :    size_t frames_to_skip = StackCapture::bottom_frames_to_skip() + 1;
 155  E :    std::string new_frames_to_skip_str = base::UintToString(frames_to_skip);
 156    :    current_command_line_.AppendSwitchASCII(
 157  E :        TestAsanRuntime::kBottomFramesToSkip, new_frames_to_skip_str);
 158    :  
 159    :    ASSERT_NO_FATAL_FAILURE(
 160  E :        asan_runtime_.SetUp(current_command_line_.GetCommandLineString()));
 161    :  
 162  E :    EXPECT_EQ(frames_to_skip, StackCapture::bottom_frames_to_skip());
 163  E :  }
 164    :  
 165  E :  TEST_F(AsanRuntimeTest, SetExitOnFailure) {
 166  E :    current_command_line_.AppendSwitch(TestAsanRuntime::kExitOnFailure);
 167    :  
 168    :    ASSERT_NO_FATAL_FAILURE(
 169  E :        asan_runtime_.SetUp(current_command_line_.GetCommandLineString()));
 170  E :    EXPECT_TRUE(asan_runtime_.flags()->exit_on_failure);
 171  E :  }
 172    :  
 173  E :  TEST_F(AsanRuntimeTest, ExitOnFailure) {
 174  E :    current_command_line_.AppendSwitch(TestAsanRuntime::kExitOnFailure);
 175    :  
 176    :    ASSERT_NO_FATAL_FAILURE(
 177  E :        asan_runtime_.SetUp(current_command_line_.GetCommandLineString()));
 178    :  
 179  E :    EXPECT_TRUE(asan_runtime_.flags()->exit_on_failure);
 180  E :    CONTEXT context = {};
 181  E :    RtlCaptureContext(&context);
 182    :  
 183  E :    AsanErrorInfo bad_access_info = {};
 184    :    // We need to delete the files and directory created by this unittest because
 185    :    // the EXPECT_EXIT macro will clone the process and this new process will exit
 186    :    // after the call to OnError, without calling the destructor of this class
 187    :    // (who takes care of deleting the temporary files/directories).
 188  E :    DeleteTempFileAndDirectory();
 189    :    EXPECT_EXIT(asan_runtime_.OnError(&context, &bad_access_info),
 190  E :                ::testing::ExitedWithCode(EXIT_FAILURE), "");
 191  E :  }
 192    :  
 193  E :  TEST_F(AsanRuntimeTest, IgnoredStackIds) {
 194  E :    std::string ignored_stack_ids = "0x1;0X7E577E57;0xCAFEBABE;0xffffffff";
 195    :    current_command_line_.AppendSwitchASCII(
 196  E :        TestAsanRuntime::kIgnoredStackIds, ignored_stack_ids);
 197    :  
 198    :    ASSERT_NO_FATAL_FAILURE(
 199  E :        asan_runtime_.SetUp(current_command_line_.GetCommandLineString()));
 200    :  
 201    :    EXPECT_TRUE(asan_runtime_.flags()->ignored_stack_ids.find(0x1) !=
 202  E :                asan_runtime_.flags()->ignored_stack_ids.end());
 203    :    EXPECT_TRUE(asan_runtime_.flags()->ignored_stack_ids.find(0x7E577E57) !=
 204  E :                asan_runtime_.flags()->ignored_stack_ids.end());
 205    :    EXPECT_TRUE(asan_runtime_.flags()->ignored_stack_ids.find(0xCAFEBABE) !=
 206  E :                asan_runtime_.flags()->ignored_stack_ids.end());
 207    :    EXPECT_TRUE(asan_runtime_.flags()->ignored_stack_ids.find(0xFFFFFFFF) !=
 208  E :                asan_runtime_.flags()->ignored_stack_ids.end());
 209  E :  }
 210    :  
 211  E :  TEST_F(AsanRuntimeTest, SetFlags) {
 212    :    ASSERT_NO_FATAL_FAILURE(
 213  E :        asan_runtime_.SetUp(current_command_line_.GetCommandLineString()));
 214    :  
 215  E :    TestAsanRuntime::AsanFlags flags;
 216  E :    flags.quarantine_size = HeapProxy::default_quarantine_max_size() - 1;
 217  E :    ASSERT_LT(0U, flags.quarantine_size);
 218    :    flags.reporting_period =
 219  E :        StackCaptureCache::GetDefaultCompressionReportingPeriod() - 1;
 220  E :    ASSERT_LT(0U, flags.reporting_period);
 221    :    flags.bottom_frames_to_skip =
 222  E :        StackCapture::bottom_frames_to_skip() + 1;
 223  E :    ASSERT_LT(0U, flags.bottom_frames_to_skip);
 224    :    flags.max_num_frames =
 225  E :        asan_runtime_.stack_cache()->max_num_frames() - 1;
 226  E :    ASSERT_LT(0U, flags.max_num_frames);
 227  E :    asan_runtime_.set_flags(&flags);
 228  E :    asan_runtime_.PropagateFlagsValues();
 229    :  
 230  E :    ASSERT_EQ(flags.quarantine_size, HeapProxy::default_quarantine_max_size());
 231    :    ASSERT_EQ(flags.reporting_period,
 232  E :              StackCaptureCache::compression_reporting_period());
 233  E :    ASSERT_EQ(flags.bottom_frames_to_skip, StackCapture::bottom_frames_to_skip());
 234    :    ASSERT_EQ(flags.max_num_frames,
 235  E :              asan_runtime_.stack_cache()->max_num_frames());
 236  E :  }
 237    :  
 238    :  }  // namespace asan
 239    :  }  // namespace agent

Coverage information generated Thu Jul 04 09:34:53 2013.