Coverage for /Syzygy/agent/asan/heaps/large_block_heap_unittest.cc

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

Line-by-line coverage:

   1    :  // Copyright 2014 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/heaps/large_block_heap.h"
  16    :  
  17    :  #include "syzygy/agent/asan/unittest_util.h"
  18    :  #include "syzygy/agent/asan/memory_notifiers/null_memory_notifier.h"
  19    :  
  20    :  namespace agent {
  21    :  namespace asan {
  22    :  namespace heaps {
  23    :  
  24    :  namespace {
  25    :  
  26    :  // Provides an ordering for BlockInfo objects.
  27    :  struct BlockInfoLessThan {
  28  E :    bool operator()(const BlockInfo& bi1, const BlockInfo& bi2) const {
  29  E :      return bi1.header < bi2.header;
  30  E :    }
  31    :  };
  32    :  
  33    :  typedef std::set<BlockInfo, BlockInfoLessThan> BlockInfoSet;
  34    :  
  35  E :  testing::DummyHeap dummy_heap;
  36  E :  agent::asan::memory_notifiers::NullMemoryNotifier dummy_notifier;
  37    :  
  38    :  // A LargeBlockHeap that uses a null memory notifier.
  39    :  class TestLargeBlockHeap : public LargeBlockHeap {
  40    :   public:
  41    :    using LargeBlockHeap::FreeAllAllocations;
  42    :  
  43  E :    TestLargeBlockHeap() : LargeBlockHeap(&dummy_notifier, &dummy_heap) {
  44  E :    }
  45    :  };
  46    :  
  47    :  }  // namespace
  48    :  
  49  E :  TEST(LargeBlockHeapTest, GetHeapTypeIsValid) {
  50  E :    TestLargeBlockHeap h;
  51  E :    EXPECT_EQ(kLargeBlockHeap, h.GetHeapType());
  52  E :  }
  53    :  
  54  E :  TEST(LargeBlockHeapTest, FeaturesAreValid) {
  55  E :    TestLargeBlockHeap h;
  56    :    EXPECT_EQ(HeapInterface::kHeapSupportsIsAllocated |
  57    :                  HeapInterface::kHeapSupportsGetAllocationSize |
  58    :                  HeapInterface::kHeapReportsReservations,
  59  E :              h.GetHeapFeatures());
  60  E :  }
  61    :  
  62  E :  TEST(LargeBlockHeapTest, EndToEnd) {
  63  E :    TestLargeBlockHeap h;
  64  E :    EXPECT_EQ(0u, h.size());
  65    :  
  66  E :    BlockLayout layout = {};
  67  E :    BlockInfo block = {};
  68    :  
  69    :    // Allocate and free a zero-sized allocation. This should succeed by
  70    :    // definition.
  71  E :    void* alloc = h.AllocateBlock(0, 0, 0, &layout);
  72  E :    EXPECT_EQ(1u, h.size());
  73  E :    BlockInitialize(layout, alloc, false, &block);
  74  E :    EXPECT_TRUE(h.FreeBlock(block));
  75  E :    EXPECT_EQ(0u, h.size());
  76    :  
  77    :    // Make a bunch of different sized allocations.
  78  E :    BlockInfoSet blocks;
  79  E :    for (size_t i = 1, j = 1; i < 1024 * 1024; i <<= 1, ++j) {
  80  E :      void* alloc = h.AllocateBlock(i, 0, 0, &layout);
  81  E :      EXPECT_EQ(j, h.size());
  82  E :      EXPECT_EQ(0u, layout.block_size % GetPageSize());
  83  E :      EXPECT_EQ(0u, reinterpret_cast<uintptr_t>(alloc) % GetPageSize());
  84  E :      EXPECT_LE(GetPageSize(), layout.header_size + layout.header_padding_size);
  85  E :      EXPECT_EQ(i, layout.body_size);
  86  E :      EXPECT_LE(GetPageSize(), layout.trailer_padding_size + layout.trailer_size);
  87  E :      BlockInitialize(layout, alloc, false, &block);
  88  E :      blocks.insert(block);
  89  E :    }
  90    :  
  91    :    // Now free them.
  92  E :    BlockInfoSet::const_iterator it = blocks.begin();
  93  E :    for (; it != blocks.end(); ++it)
  94  E :      EXPECT_TRUE(h.FreeBlock(*it));
  95  E :    EXPECT_EQ(0u, h.size());
  96  E :  }
  97    :  
  98  E :  TEST(LargeBlockHeapTest, ZeroSizedAllocationsHaveDistinctAddresses) {
  99  E :    TestLargeBlockHeap h;
 100    :  
 101  E :    void* a1 = h.Allocate(0);
 102  E :    EXPECT_TRUE(a1 != NULL);
 103  E :    void* a2 = h.Allocate(0);
 104  E :    EXPECT_TRUE(a2 != NULL);
 105  E :    EXPECT_NE(a1, a2);
 106  E :    EXPECT_TRUE(h.Free(a1));
 107  E :    EXPECT_TRUE(h.Free(a2));
 108    :  
 109  E :    BlockLayout layout = {};
 110    :  
 111  E :    BlockInfo b1 = {};
 112  E :    a1 = h.AllocateBlock(0, 0, 0, &layout);
 113  E :    EXPECT_TRUE(a1 != NULL);
 114  E :    BlockInitialize(layout, a1, false, &b1);
 115    :  
 116  E :    BlockInfo b2 = {};
 117  E :    a2 = h.AllocateBlock(0, 0, 0, &layout);
 118  E :    EXPECT_TRUE(a2 != NULL);
 119  E :    BlockInitialize(layout, a2, false, &b2);
 120    :  
 121  E :    EXPECT_NE(a1, a2);
 122  E :    EXPECT_NE(b1.header, b2.header);
 123    :  
 124  E :    EXPECT_TRUE(h.FreeBlock(b1));
 125  E :    EXPECT_TRUE(h.FreeBlock(b2));
 126  E :  }
 127    :  
 128  E :  TEST(LargeBlockHeapTest, IsAllocated) {
 129  E :    TestLargeBlockHeap h;
 130    :  
 131  E :    EXPECT_FALSE(h.IsAllocated(NULL));
 132    :  
 133  E :    void* a = h.Allocate(100);
 134  E :    EXPECT_TRUE(h.IsAllocated(a));
 135  E :    EXPECT_FALSE(h.IsAllocated(reinterpret_cast<uint8*>(a) - 1));
 136  E :    EXPECT_FALSE(h.IsAllocated(reinterpret_cast<uint8*>(a) + 1));
 137    :  
 138  E :    EXPECT_TRUE(h.Free(a));
 139  E :    EXPECT_FALSE(h.IsAllocated(a));
 140  E :  }
 141    :  
 142  E :  TEST(LargeBlockHeapTest, GetAllocationSize) {
 143  E :    TestLargeBlockHeap h;
 144    :  
 145  E :    void* alloc = h.Allocate(67);
 146  E :    ASSERT_TRUE(alloc != NULL);
 147  E :    EXPECT_EQ(67u, h.GetAllocationSize(alloc));
 148  E :    EXPECT_TRUE(h.Free(alloc));
 149  E :  }
 150    :  
 151  E :  TEST(LargeBlockHeapTest, Lock) {
 152  E :    TestLargeBlockHeap h;
 153    :  
 154  E :    h.Lock();
 155  E :    EXPECT_TRUE(h.TryLock());
 156  E :    h.Unlock();
 157  E :    h.Unlock();
 158  E :  }
 159    :  
 160  E :  TEST(LargeBlockHeapTest, FreeAllAllocations) {
 161  E :    const size_t kAllocCount = 10;
 162  E :    TestLargeBlockHeap h;
 163  E :    for (size_t i = 0; i < kAllocCount; ++i)
 164  E :      h.Allocate(42);
 165  E :    EXPECT_EQ(kAllocCount, h.size());
 166  E :    h.FreeAllAllocations();
 167  E :    EXPECT_EQ(0U, h.size());
 168  E :  }
 169    :  
 170  E :  TEST(LargeBlockHeapTest, DestructionWithOutstandingAllocationsSucceeds) {
 171  E :    const size_t kAllocCount = 10;
 172  E :    TestLargeBlockHeap h;
 173    :    // Create some allocations and intentionally leak them. They should be
 174    :    // automatically released in the LargeBlockHeap destructor. This will only
 175    :    // fail due to a CHECK in the LargeBlockHeap that ensure that there's no more
 176    :    // alive allocations after calling FreeAllAllocations.
 177  E :    for (size_t i = 0; i < kAllocCount; ++i)
 178  E :      h.Allocate(42);
 179  E :    EXPECT_EQ(kAllocCount, h.size());
 180  E :  }
 181    :  
 182    :  }  // namespace heaps
 183    :  }  // namespace asan
 184    :  }  // namespace agent

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