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

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%34340.C++source

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/heap_checker.h"
  16    :  
  17    :  #include "syzygy/agent/asan/asan_runtime.h"
  18    :  #include "syzygy/agent/asan/page_protection_helpers.h"
  19    :  #include "syzygy/agent/asan/shadow.h"
  20    :  
  21    :  namespace agent {
  22    :  namespace asan {
  23    :  
  24  E :  bool HeapChecker::IsHeapCorrupt(CorruptRangesVector* corrupt_ranges) {
  25  E :    DCHECK_NE(reinterpret_cast<CorruptRangesVector*>(NULL), corrupt_ranges);
  26    :  
  27  E :    corrupt_ranges->clear();
  28    :  
  29    :    // Grab the page protection lock. This prevents multiple heap checkers from
  30    :    // running simultaneously, and also prevents page protections from being
  31    :    // modified from underneath us.
  32  E :    ::common::AutoRecursiveLock scoped_lock(block_protect_lock);
  33    :  
  34    :    // Walk over all of the addressable memory to find the corrupt blocks.
  35    :    // TODO(sebmarchand): Iterates over the heap slabs once we have switched to
  36    :    //     a new memory allocator.
  37    :    GetCorruptRangesInSlab(
  38    :        reinterpret_cast<const uint8*>(Shadow::kAddressLowerBound),
  39    :        Shadow::kAddressUpperBound - Shadow::kAddressLowerBound - 1,
  40  E :        corrupt_ranges);
  41    :  
  42  E :    return !corrupt_ranges->empty();
  43  E :  }
  44    :  
  45    :  void HeapChecker::GetCorruptRangesInSlab(const uint8* lower_bound,
  46    :                                           size_t length,
  47  E :                                           CorruptRangesVector* corrupt_ranges) {
  48  E :    DCHECK_NE(reinterpret_cast<const uint8*>(NULL), lower_bound);
  49  E :    DCHECK_NE(0U, length);
  50  E :    DCHECK_NE(reinterpret_cast<CorruptRangesVector*>(NULL), corrupt_ranges);
  51    :  
  52  E :    ShadowWalker shadow_walker(false, lower_bound, lower_bound + length);
  53    :  
  54  E :    AsanCorruptBlockRange* current_corrupt_range = NULL;
  55    :  
  56    :    // Iterates over the blocks.
  57  E :    BlockInfo block_info = {};
  58  E :    while (shadow_walker.Next(&block_info)) {
  59    :      // Remove the protections on this block so its checksum can be safely
  60    :      // validated. We leave the protections permanently removed so that the
  61    :      // minidump generation has free access to block contents.
  62  E :      BlockProtectNone(block_info);
  63    :  
  64  E :      bool current_block_is_corrupt = IsBlockCorrupt(block_info.block, NULL);
  65    :      // If the current block is corrupt and |current_corrupt_range| is NULL
  66    :      // then this means that the current block is at the beginning of a corrupt
  67    :      // range.
  68  E :      if (current_block_is_corrupt && current_corrupt_range == NULL) {
  69    :        AsanCorruptBlockRange corrupt_range;
  70  E :        corrupt_range.address = block_info.block;
  71  E :        corrupt_range.length = 0;
  72  E :        corrupt_range.block_count = 0;
  73  E :        corrupt_range.block_info = NULL;
  74  E :        corrupt_range.block_info_count = 0;
  75  E :        corrupt_ranges->push_back(corrupt_range);
  76  E :        current_corrupt_range = &corrupt_ranges->back();
  77  E :      } else if (!current_block_is_corrupt && current_corrupt_range != NULL) {
  78  E :        current_corrupt_range = NULL;
  79    :      }
  80    :  
  81  E :      if (current_block_is_corrupt) {
  82    :        // If the current block is corrupt then we need to update the size of the
  83    :        // current range.
  84    :        DCHECK_NE(reinterpret_cast<AsanCorruptBlockRange*>(NULL),
  85  E :                  current_corrupt_range);
  86  E :        current_corrupt_range->block_count++;
  87  E :        const uint8* current_block_end = block_info.block + block_info.block_size;
  88    :        current_corrupt_range->length = current_block_end -
  89  E :            reinterpret_cast<const uint8*>(current_corrupt_range->address);
  90    :      }
  91  E :    }
  92  E :  }
  93    :  
  94    :  }  // namespace asan
  95    :  }  // namespace agent

Coverage information generated Thu Mar 26 16:15:41 2015.