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

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
98.7%3093130.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_heap.h"
  16    :  
  17    :  #include "base/rand_util.h"
  18    :  #include "base/sha1.h"
  19    :  #include "gtest/gtest.h"
  20    :  #include "syzygy/agent/asan/asan_logger.h"
  21    :  #include "syzygy/agent/asan/asan_shadow.h"
  22    :  #include "syzygy/agent/asan/unittest_util.h"
  23    :  #include "syzygy/trace/common/clock.h"
  24    :  
  25    :  namespace agent {
  26    :  namespace asan {
  27    :  
  28    :  namespace {
  29    :  
  30    :  // A derived class to expose protected members for unit-testing.
  31    :  class TestShadow : public Shadow {
  32    :   public:
  33    :    using Shadow::kShadowSize;
  34    :    using Shadow::shadow_;
  35    :  };
  36    :  
  37    :  // A derived class to expose protected members for unit-testing.
  38    :  class TestHeapProxy : public HeapProxy {
  39    :   public:
  40    :    using HeapProxy::BlockHeader;
  41    :    using HeapProxy::BlockTrailer;
  42    :    using HeapProxy::FindAddressBlock;
  43    :    using HeapProxy::GetAllocSize;
  44    :    using HeapProxy::GetBadAccessKind;
  45    :    using HeapProxy::GetTimeSinceFree;
  46    :    using HeapProxy::ToBlockHeader;
  47    :    using HeapProxy::GetBlockTrailer;
  48    :  
  49  E :    explicit TestHeapProxy(StackCaptureCache* stack_cache, AsanLogger* logger)
  50    :        : HeapProxy(stack_cache, logger) {
  51  E :    }
  52    :  
  53    :    // Verify that the access to @p addr contained in @p header is an underflow.
  54  E :    bool IsUnderflowAccess(uint8* addr, BlockHeader* header) {
  55  E :      return GetBadAccessKind(addr, header) == HEAP_BUFFER_UNDERFLOW;
  56  E :    }
  57    :  
  58    :    // Verify that the access to @p addr contained in @p header is an overflow.
  59  E :    bool IsOverflowAccess(uint8* addr, BlockHeader* header) {
  60  E :      return GetBadAccessKind(addr, header) == HEAP_BUFFER_OVERFLOW;
  61  E :    }
  62    :  
  63    :    // Verify that the access to @p addr contained in @p header is an use after
  64    :    // free.
  65  E :    bool IsUseAfterAccess(uint8* addr, BlockHeader* header) {
  66  E :      return GetBadAccessKind(addr, header) == USE_AFTER_FREE;
  67  E :    }
  68    :  
  69  E :    bool IsQuarantined(BlockHeader* header) {
  70  E :      EXPECT_TRUE(header != NULL);
  71  E :      return header->state == QUARANTINED;
  72  E :    }
  73    :  
  74    :    // Determines if the address @p mem corresponds to a block in quarantine.
  75  E :    bool InQuarantine(const void* mem) {
  76  E :      base::AutoLock lock(lock_);
  77  E :      BlockHeader* current_block = head_;
  78  E :      while (current_block != NULL) {
  79  E :        void* block_alloc = static_cast<void*>(ToAlloc(current_block));
  80  E :        EXPECT_TRUE(block_alloc != NULL);
  81  E :        if (block_alloc == mem) {
  82  E :          EXPECT_TRUE(current_block->state == QUARANTINED);
  83  E :          return true;
  84    :        }
  85  E :        current_block = GetBlockTrailer(current_block)->next_free_block;
  86  E :      }
  87  E :      return false;
  88  E :    }
  89    :  };
  90    :  
  91    :  class HeapTest : public testing::TestWithAsanLogger {
  92    :   public:
  93  E :    HeapTest() : stack_cache_(&logger_), proxy_(&stack_cache_, &logger_) {
  94  E :    }
  95    :  
  96  E :    virtual void SetUp() OVERRIDE {
  97  E :      testing::TestWithAsanLogger::SetUp();
  98    :  
  99  E :      HeapProxy::Init();
 100  E :      Shadow::SetUp();
 101    :  
 102  E :      logger_.set_instance_id(instance_id());
 103  E :      logger_.Init();
 104  E :      ASSERT_TRUE(proxy_.Create(0, 0, 0));
 105  E :    }
 106    :  
 107  E :    virtual void TearDown() OVERRIDE {
 108  E :      ASSERT_TRUE(proxy_.Destroy());
 109  E :      Shadow::TearDown();
 110  E :      testing::TestWithAsanLogger::TearDown();
 111  E :    }
 112    :  
 113    :    // Verifies that [alloc, alloc + size) is accessible, and that
 114    :    // [alloc - 1] and [alloc+size] are poisoned.
 115  E :    void VerifyAllocAccess(void* alloc, size_t size) {
 116  E :      uint8* mem = reinterpret_cast<uint8*>(alloc);
 117  E :      ASSERT_FALSE(Shadow::IsAccessible(mem - 1));
 118  E :      ASSERT_EQ(Shadow::GetShadowMarkerForAddress(mem - 1),
 119    :                Shadow::kHeapLeftRedzone);
 120  E :      for (size_t i = 0; i < size; ++i)
 121  E :        ASSERT_TRUE(Shadow::IsAccessible(mem + i));
 122  E :      ASSERT_FALSE(Shadow::IsAccessible(mem + size));
 123  E :    }
 124    :  
 125    :    // Verifies that [alloc-1, alloc+size] is poisoned.
 126  E :    void VerifyFreedAccess(void* alloc, size_t size) {
 127  E :      uint8* mem = reinterpret_cast<uint8*>(alloc);
 128  E :      ASSERT_FALSE(Shadow::IsAccessible(mem - 1));
 129  E :      ASSERT_EQ(Shadow::GetShadowMarkerForAddress(mem - 1),
 130    :                Shadow::kHeapLeftRedzone);
 131  E :      for (size_t i = 0; i < size; ++i) {
 132  E :        ASSERT_FALSE(Shadow::IsAccessible(mem + i));
 133  E :        ASSERT_EQ(Shadow::GetShadowMarkerForAddress(mem + i),
 134    :                  Shadow::kHeapFreedByte);
 135  E :      }
 136  E :      ASSERT_FALSE(Shadow::IsAccessible(mem + size));
 137  E :    }
 138    :  
 139  E :    void RandomSetMemory(void* alloc, size_t size) {
 140  E :      base::RandBytes(alloc, size);
 141  E :    }
 142    :  
 143    :   protected:
 144    :    // Arbitrary constant for all size limit.
 145    :    static const size_t kMaxAllocSize = 134584;
 146    :  
 147    :    AsanLogger logger_;
 148    :    StackCaptureCache stack_cache_;
 149    :    TestHeapProxy proxy_;
 150    :  };
 151    :  
 152    :  }  // namespace
 153    :  
 154  E :  TEST_F(HeapTest, ToFromHandle) {
 155  E :    HANDLE handle = HeapProxy::ToHandle(&proxy_);
 156  E :    ASSERT_TRUE(handle != NULL);
 157  E :    ASSERT_EQ(&proxy_, HeapProxy::FromHandle(handle));
 158  E :  }
 159    :  
 160  E :  TEST_F(HeapTest, SetQuarantineMaxSize) {
 161  E :    size_t quarantine_size = proxy_.quarantine_max_size() * 2;
 162    :    // Increments the quarantine max size if it was set to 0.
 163  E :    if (quarantine_size == 0)
 164  i :      quarantine_size++;
 165  E :    DCHECK_GT(quarantine_size, 0U);
 166  E :    proxy_.SetQuarantineMaxSize(quarantine_size);
 167  E :    ASSERT_EQ(quarantine_size, proxy_.quarantine_max_size());
 168  E :  }
 169    :  
 170  E :  TEST_F(HeapTest, PopOnSetQuarantineMaxSize) {
 171  E :    const size_t kAllocSize = 100;
 172  E :    const size_t real_alloc_size = TestHeapProxy::GetAllocSize(kAllocSize);
 173  E :    LPVOID mem = proxy_.Alloc(0, kAllocSize);
 174  E :    ASSERT_FALSE(proxy_.InQuarantine(mem));
 175  E :    proxy_.SetQuarantineMaxSize(real_alloc_size);
 176  E :    ASSERT_TRUE(proxy_.Free(0, mem));
 177    :    // The quarantine is just large enough to keep this block.
 178  E :    ASSERT_TRUE(proxy_.InQuarantine(mem));
 179    :    // We resize the quarantine to a smaller size, the block should pop out.
 180  E :    proxy_.SetQuarantineMaxSize(real_alloc_size - 1);
 181  E :    ASSERT_FALSE(proxy_.InQuarantine(mem));
 182  E :  }
 183    :  
 184  E :  TEST_F(HeapTest, Quarantine) {
 185  E :    const size_t kAllocSize = 100;
 186  E :    const size_t real_alloc_size = TestHeapProxy::GetAllocSize(kAllocSize);
 187  E :    const size_t number_of_allocs = 16;
 188  E :    proxy_.SetQuarantineMaxSize(real_alloc_size * number_of_allocs);
 189    :  
 190  E :    LPVOID mem = proxy_.Alloc(0, kAllocSize);
 191  E :    ASSERT_TRUE(mem != NULL);
 192  E :    ASSERT_TRUE(proxy_.Free(0, mem));
 193    :    // Allocate a bunch of blocks until the first one is pushed out of the
 194    :    // quarantine.
 195  E :    for (size_t i = 0;i < number_of_allocs; ++i) {
 196  E :      ASSERT_TRUE(proxy_.InQuarantine(mem));
 197  E :      LPVOID mem2 = proxy_.Alloc(0, kAllocSize);
 198  E :      ASSERT_TRUE(mem2 != NULL);
 199  E :      ASSERT_TRUE(proxy_.Free(0, mem2));
 200  E :      ASSERT_TRUE(proxy_.InQuarantine(mem2));
 201  E :    }
 202    :  
 203  E :    ASSERT_FALSE(proxy_.InQuarantine(mem));
 204  E :  }
 205    :  
 206  E :  TEST_F(HeapTest, UnpoisonsQuarantine) {
 207  E :    const size_t kAllocSize = 100;
 208  E :    const size_t real_alloc_size = TestHeapProxy::GetAllocSize(kAllocSize);
 209  E :    proxy_.SetQuarantineMaxSize(real_alloc_size);
 210    :  
 211    :    // Allocate a memory block and directly free it, this puts it in the
 212    :    // quarantine.
 213  E :    void* mem = proxy_.Alloc(0, kAllocSize);
 214  E :    ASSERT_TRUE(mem != NULL);
 215  E :    ASSERT_TRUE(proxy_.Free(0, mem));
 216  E :    ASSERT_TRUE(proxy_.InQuarantine(mem));
 217    :  
 218    :    // Assert that the shadow memory has been correctly poisoned.
 219  E :    intptr_t mem_start = reinterpret_cast<intptr_t>(proxy_.ToBlockHeader(mem));
 220  E :    ASSERT_TRUE((mem_start & 7) == 0);
 221  E :    size_t shadow_start = mem_start >> 3;
 222  E :    size_t shadow_alloc_size = real_alloc_size >> 3;
 223  E :    for (size_t i = shadow_start; i < shadow_start + shadow_alloc_size; ++i) {
 224  E :      ASSERT_NE(TestShadow::kHeapAddressableByte, TestShadow::shadow_[i]);
 225  E :    }
 226    :  
 227    :    // Flush the quarantine.
 228  E :    proxy_.SetQuarantineMaxSize(0);
 229    :  
 230    :    // Assert that the quarantine has been correctly unpoisoned.
 231  E :    for (size_t i = shadow_start; i < shadow_start + shadow_alloc_size; ++i) {
 232  E :      ASSERT_EQ(TestShadow::kHeapAddressableByte, TestShadow::shadow_[i]);
 233  E :    }
 234  E :  }
 235    :  
 236  E :  TEST_F(HeapTest, Realloc) {
 237  E :    const size_t kAllocSize = 100;
 238    :    // As a special case, a realloc with a NULL input should succeed.
 239  E :    LPVOID mem = proxy_.ReAlloc(0, NULL, kAllocSize);
 240  E :    ASSERT_TRUE(mem != NULL);
 241  E :    mem = proxy_.ReAlloc(0, mem, kAllocSize + 5);
 242  E :    ASSERT_TRUE(mem != NULL);
 243    :  
 244    :    // We always fail reallocs with the in-place flag.
 245    :    ASSERT_EQ(NULL,
 246  E :              proxy_.ReAlloc(HEAP_REALLOC_IN_PLACE_ONLY, NULL, kAllocSize));
 247    :    ASSERT_EQ(NULL,
 248  E :              proxy_.ReAlloc(HEAP_REALLOC_IN_PLACE_ONLY, mem, kAllocSize - 10));
 249    :    ASSERT_EQ(NULL,
 250  E :              proxy_.ReAlloc(HEAP_REALLOC_IN_PLACE_ONLY, mem, kAllocSize + 10));
 251    :  
 252  E :    ASSERT_TRUE(proxy_.Free(0, mem));
 253  E :  }
 254    :  
 255  E :  TEST_F(HeapTest, AllocFree) {
 256  E :    const size_t kAllocSize = 100;
 257  E :    LPVOID mem = proxy_.Alloc(0, kAllocSize);
 258  E :    ASSERT_TRUE(mem != NULL);
 259  E :    ASSERT_EQ(kAllocSize, proxy_.Size(0, mem));
 260  E :    const size_t kReAllocSize = 2 * kAllocSize;
 261  E :    mem = proxy_.ReAlloc(0, mem, kReAllocSize);
 262  E :    ASSERT_EQ(kReAllocSize, proxy_.Size(0, mem));
 263  E :    ASSERT_TRUE(proxy_.Free(0, mem));
 264  E :  }
 265    :  
 266  E :  TEST_F(HeapTest, DoubleFree) {
 267  E :    const size_t kAllocSize = 100;
 268    :    // Ensure that the quarantine is large enough to keep this block, this is
 269    :    // needed for the use-after-free check.
 270  E :    proxy_.SetQuarantineMaxSize(TestHeapProxy::GetAllocSize(kAllocSize));
 271  E :    LPVOID mem = proxy_.Alloc(0, kAllocSize);
 272  E :    ASSERT_TRUE(mem != NULL);
 273  E :    ASSERT_TRUE(proxy_.Free(0, mem));
 274  E :    ASSERT_TRUE(proxy_.IsQuarantined(proxy_.ToBlockHeader(mem)));
 275  E :    ASSERT_FALSE(proxy_.Free(0, mem));
 276  E :    ASSERT_TRUE(LogContains(HeapProxy::kAttemptingDoubleFree));
 277  E :  }
 278    :  
 279  E :  TEST_F(HeapTest, AllocsAccessibility) {
 280    :    // Ensure that the quarantine is large enough to keep the allocated blocks in
 281    :    // this test.
 282  E :    proxy_.SetQuarantineMaxSize(kMaxAllocSize * 2);
 283  E :    for (size_t size = 10; size < kMaxAllocSize; size = size * 5 + 123) {
 284    :      // Do an alloc/realloc/free and test that access is correctly managed.
 285  E :      void* mem = proxy_.Alloc(0, size);
 286  E :      ASSERT_TRUE(mem != NULL);
 287  E :      ASSERT_NO_FATAL_FAILURE(VerifyAllocAccess(mem, size));
 288  E :      RandomSetMemory(mem, size);
 289    :  
 290  E :      size_t new_size = size;
 291  E :      while (new_size == size)
 292  E :        new_size = base::RandInt(size / 2, size * 2);
 293    :  
 294  E :      unsigned char sha1_before[base::kSHA1Length] = {};
 295    :      base::SHA1HashBytes(reinterpret_cast<unsigned char*>(mem),
 296    :                          std::min(size, new_size),
 297  E :                          sha1_before);
 298    :  
 299  E :      void* new_mem = proxy_.ReAlloc(0, mem, size * 2);
 300  E :      ASSERT_TRUE(new_mem != NULL);
 301  E :      ASSERT_NE(mem, new_mem);
 302    :  
 303  E :      unsigned char sha1_after[base::kSHA1Length] = {};
 304    :      base::SHA1HashBytes(reinterpret_cast<unsigned char*>(new_mem),
 305    :                          std::min(size, new_size),
 306  E :                          sha1_after);
 307  E :      ASSERT_EQ(0, memcmp(sha1_before, sha1_after, base::kSHA1Length));
 308    :  
 309  E :      ASSERT_NO_FATAL_FAILURE(VerifyFreedAccess(mem, size));
 310  E :      ASSERT_NO_FATAL_FAILURE(VerifyAllocAccess(new_mem, size * 2));
 311    :  
 312  E :      ASSERT_TRUE(proxy_.Free(0, new_mem));
 313  E :      ASSERT_NO_FATAL_FAILURE(VerifyFreedAccess(new_mem, size * 2));
 314  E :    }
 315  E :  }
 316    :  
 317  E :  TEST_F(HeapTest, AllocZeroBytes) {
 318  E :    void* mem1 = proxy_.Alloc(0, 0);
 319  E :    ASSERT_TRUE(mem1 != NULL);
 320  E :    void* mem2 = proxy_.Alloc(0, 0);
 321  E :    ASSERT_TRUE(mem2 != NULL);
 322  E :    ASSERT_NE(mem1, mem2);
 323  E :    ASSERT_TRUE(proxy_.Free(0, mem1));
 324  E :    ASSERT_TRUE(proxy_.Free(0, mem2));
 325  E :  }
 326    :  
 327  E :  TEST_F(HeapTest, Size) {
 328  E :    for (size_t size = 10; size < kMaxAllocSize; size = size * 5 + 123) {
 329  E :      void* mem = proxy_.Alloc(0, size);
 330  E :      ASSERT_FALSE(mem == NULL);
 331  E :      ASSERT_EQ(size, proxy_.Size(0, mem));
 332  E :      ASSERT_TRUE(proxy_.Free(0, mem));
 333  E :    }
 334  E :  }
 335    :  
 336  E :  TEST_F(HeapTest, Validate) {
 337  E :    for (size_t size = 10; size < kMaxAllocSize; size = size * 5 + 123) {
 338  E :      void* mem = proxy_.Alloc(0, size);
 339  E :      ASSERT_FALSE(mem == NULL);
 340  E :      ASSERT_TRUE(proxy_.Validate(0, mem));
 341  E :      ASSERT_TRUE(proxy_.Free(0, mem));
 342  E :    }
 343  E :  }
 344    :  
 345  E :  TEST_F(HeapTest, Compact) {
 346    :    // Compact should return a non-zero size.
 347  E :    ASSERT_LT(0U, proxy_.Compact(0));
 348    :  
 349    :    // TODO(siggi): It may not be possible to allocate the size returned due
 350    :    //     to padding - fix and test.
 351  E :  }
 352    :  
 353  E :  TEST_F(HeapTest, LockUnlock) {
 354    :    // We can't really test these, aside from not crashing.
 355  E :    ASSERT_TRUE(proxy_.Lock());
 356  E :    ASSERT_TRUE(proxy_.Unlock());
 357  E :  }
 358    :  
 359  E :  TEST_F(HeapTest, Walk) {
 360    :    // We assume at least two entries to walk through.
 361  E :    PROCESS_HEAP_ENTRY entry = {};
 362  E :    ASSERT_TRUE(proxy_.Walk(&entry));
 363  E :    ASSERT_TRUE(proxy_.Walk(&entry));
 364  E :  }
 365    :  
 366  E :  TEST_F(HeapTest, SetQueryInformation) {
 367  E :    ULONG compat_flag = -1;
 368  E :    unsigned long ret = 0;
 369    :    // Get the current value of the compat flag.
 370    :    ASSERT_TRUE(
 371    :        proxy_.QueryInformation(HeapCompatibilityInformation,
 372  E :                                &compat_flag, sizeof(compat_flag), &ret));
 373  E :    ASSERT_EQ(sizeof(compat_flag), ret);
 374  E :    ASSERT_TRUE(compat_flag != -1);
 375    :  
 376    :    // Put the heap in LFH, which should always succeed, except when a debugger
 377    :    // is attached. When a debugger is attached, the heap is wedged in certain
 378    :    // debug settings.
 379  E :    if (base::debug::BeingDebugged()) {
 380  i :      LOG(WARNING) << "Can't test HeapProxy::SetInformation under debugger.";
 381  i :      return;
 382    :    }
 383    :  
 384  E :    compat_flag = 2;
 385    :    ASSERT_TRUE(
 386    :        proxy_.SetInformation(HeapCompatibilityInformation,
 387  E :                              &compat_flag, sizeof(compat_flag)));
 388  E :  }
 389    :  
 390  E :  TEST_F(HeapTest, FindAddressBlock) {
 391  E :    const size_t kAllocSize = 100;
 392  E :    void* mem = proxy_.Alloc(0, kAllocSize);
 393  E :    ASSERT_FALSE(mem == NULL);
 394  E :    ASSERT_FALSE(proxy_.FindAddressBlock(static_cast<const uint8*>(mem)) == NULL);
 395    :    uint8* out_of_bounds_address =
 396  E :        static_cast<uint8*>(mem) + kAllocSize * 2;
 397  E :    ASSERT_TRUE(proxy_.FindAddressBlock(out_of_bounds_address) == NULL);
 398  E :    ASSERT_TRUE(proxy_.Free(0, mem));
 399  E :  }
 400    :  
 401  E :  TEST_F(HeapTest, GetBadAccessKind) {
 402  E :    const size_t kAllocSize = 100;
 403    :    // Ensure that the quarantine is large enough to keep this block, this is
 404    :    // needed for the use-after-free check.
 405  E :    proxy_.SetQuarantineMaxSize(TestHeapProxy::GetAllocSize(kAllocSize));
 406  E :    uint8* mem = static_cast<uint8*>(proxy_.Alloc(0, kAllocSize));
 407  E :    ASSERT_FALSE(mem == NULL);
 408    :    TestHeapProxy::BlockHeader* header =
 409  E :        const_cast<TestHeapProxy::BlockHeader*>(proxy_.ToBlockHeader(mem));
 410  E :    uint8* heap_underflow_address = mem - 1;
 411  E :    uint8* heap_overflow_address = mem + kAllocSize * sizeof(uint8);
 412  E :    ASSERT_TRUE(proxy_.IsUnderflowAccess(heap_underflow_address, header));
 413  E :    ASSERT_TRUE(proxy_.IsOverflowAccess(heap_overflow_address, header));
 414  E :    ASSERT_TRUE(proxy_.Free(0, mem));
 415  E :    ASSERT_TRUE(proxy_.IsQuarantined(header));
 416  E :    ASSERT_TRUE(proxy_.IsUseAfterAccess(mem, header));
 417  E :  }
 418    :  
 419  E :  TEST_F(HeapTest, GetTimeSinceFree) {
 420  E :    const size_t kAllocSize = 100;
 421  E :    const size_t kSleepTime = 25;
 422    :  
 423    :    // Ensure that the quarantine is large enough to keep this block.
 424  E :    proxy_.SetQuarantineMaxSize(TestHeapProxy::GetAllocSize(kAllocSize));
 425  E :    uint8* mem = static_cast<uint8*>(proxy_.Alloc(0, kAllocSize));
 426    :    TestHeapProxy::BlockHeader* header =
 427  E :        const_cast<TestHeapProxy::BlockHeader*>(proxy_.ToBlockHeader(mem));
 428    :  
 429  E :    base::TimeTicks time_before_free = base::TimeTicks::HighResNow();
 430  E :    ASSERT_EQ(0U, proxy_.GetTimeSinceFree(header));
 431  E :    ASSERT_TRUE(proxy_.Free(0, mem));
 432  E :    ASSERT_TRUE(proxy_.IsQuarantined(header));
 433  E :    ::Sleep(kSleepTime);
 434  E :    uint64 time_since_free = proxy_.GetTimeSinceFree(header);
 435  E :    ASSERT_NE(0U, time_since_free);
 436    :  
 437  E :    base::TimeDelta time_delta = base::TimeTicks::HighResNow() - time_before_free;
 438  E :    ASSERT_GT(time_delta.ToInternalValue(), 0U);
 439  E :    uint64 time_delta_us = static_cast<uint64>(time_delta.ToInternalValue());
 440  E :    trace::common::ClockInfo clock_info = {};
 441  E :    trace::common::GetClockInfo(&clock_info);
 442  E :    if (clock_info.tsc_info.frequency == 0)
 443  i :      time_delta_us += HeapProxy::kSleepTimeForApproximatingCPUFrequency;
 444    :  
 445  E :    ASSERT_GE(time_delta_us, time_since_free);
 446  E :  }
 447    :  
 448  E :  TEST_F(HeapTest, CaptureTID) {
 449  E :    const size_t kAllocSize = 13;
 450    :    // Ensure that the quarantine is large enough to keep this block.
 451  E :    proxy_.SetQuarantineMaxSize(TestHeapProxy::GetAllocSize(kAllocSize));
 452  E :    uint8* mem = static_cast<uint8*>(proxy_.Alloc(0, kAllocSize));
 453  E :    ASSERT_TRUE(proxy_.Free(0, mem));
 454  E :    ASSERT_TRUE(proxy_.IsQuarantined(proxy_.ToBlockHeader(mem)));
 455    :  
 456    :    TestHeapProxy::BlockHeader* header =
 457  E :        const_cast<TestHeapProxy::BlockHeader*>(proxy_.ToBlockHeader(mem));
 458  E :    ASSERT_TRUE(header != NULL);
 459    :    TestHeapProxy::BlockTrailer* trailer =
 460  E :        const_cast<TestHeapProxy::BlockTrailer*>(proxy_.GetBlockTrailer(header));
 461  E :    ASSERT_TRUE(trailer != NULL);
 462    :  
 463  E :    ASSERT_EQ(header->alloc_tid, ::GetCurrentThreadId());
 464  E :    ASSERT_EQ(trailer->free_tid, ::GetCurrentThreadId());
 465  E :  }
 466    :  
 467  E :  TEST_F(HeapTest, QuarantineDoesntAlterBlockContents) {
 468  E :    const size_t kAllocSize = 13;
 469    :    // Ensure that the quarantine is large enough to keep this block..
 470  E :    proxy_.SetQuarantineMaxSize(TestHeapProxy::GetAllocSize(kAllocSize));
 471  E :    void* mem = proxy_.Alloc(0, kAllocSize);
 472  E :    ASSERT_TRUE(mem != NULL);
 473  E :    RandomSetMemory(mem, kAllocSize);
 474    :  
 475  E :    unsigned char sha1_before[base::kSHA1Length] = {};
 476    :    base::SHA1HashBytes(reinterpret_cast<unsigned char*>(mem),
 477    :                        kAllocSize,
 478  E :                        sha1_before);
 479    :  
 480    :    TestHeapProxy::BlockHeader* header =
 481  E :        const_cast<TestHeapProxy::BlockHeader*>(proxy_.ToBlockHeader(mem));
 482    :  
 483  E :    ASSERT_TRUE(proxy_.Free(0, mem));
 484  E :    ASSERT_TRUE(proxy_.IsQuarantined(header));
 485    :  
 486  E :    unsigned char sha1_after[base::kSHA1Length] = {};
 487    :    base::SHA1HashBytes(reinterpret_cast<unsigned char*>(mem),
 488    :                        kAllocSize,
 489  E :                        sha1_after);
 490    :  
 491  E :    ASSERT_EQ(0, memcmp(sha1_before, sha1_after, base::kSHA1Length));
 492  E :  }
 493    :  
 494  E :  TEST_F(HeapTest, InternalStructureArePoisoned) {
 495    :    EXPECT_EQ(Shadow::kAsanMemoryByte,
 496  E :              Shadow::GetShadowMarkerForAddress(TestShadow::shadow_));
 497    :  
 498  E :    const size_t kAllocSize = 13;
 499    :    // Ensure that the quarantine is large enough to keep this block..
 500  E :    proxy_.SetQuarantineMaxSize(TestHeapProxy::GetAllocSize(kAllocSize));
 501  E :    uint8* mem = static_cast<uint8*>(proxy_.Alloc(0, kAllocSize));
 502    :    TestHeapProxy::BlockHeader* header =
 503  E :        const_cast<TestHeapProxy::BlockHeader*>(proxy_.ToBlockHeader(mem));
 504    :  
 505  E :    ASSERT_TRUE(header != NULL);
 506    :    const void* alloc_stack_cache_addr =
 507  E :        reinterpret_cast<const void*>(header->alloc_stack);
 508    :    EXPECT_EQ(Shadow::kAsanMemoryByte,
 509  E :              Shadow::GetShadowMarkerForAddress(alloc_stack_cache_addr));
 510    :  
 511  E :    ASSERT_TRUE(proxy_.Free(0, mem));
 512  E :  }
 513    :  
 514    :  }  // namespace asan
 515    :  }  // namespace agent

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