Coverage for /Syzygy/agent/memprof/heap_interceptors.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
0.0%00133.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    :  // Implementations of the Asan heap interceptors. These functions are
  16    :  // instrumented and log detailed function call information to the call-trace
  17    :  // service.
  18    :  
  19    :  #include <windows.h>
  20    :  
  21    :  #include "base/hash.h"
  22    :  #include "base/synchronization/lock.h"
  23    :  #include "syzygy/agent/memprof/memprof.h"
  24    :  
  25    :  // A wrapper to EMIT_DETAILED_FUNCTION_CALL that provides the MemoryProfiler
  26    :  // FunctionCallLogger instance.
  27    :  #define EMIT_DETAILED_HEAP_FUNCTION_CALL(...)  \
  28  m :      DCHECK_NE(static_cast<agent::memprof::MemoryProfiler*>(nullptr),  \
  29  m :                agent::memprof::memory_profiler.get());  \
  30  m :      EMIT_DETAILED_FUNCTION_CALL(  \
  31  m :          &agent::memprof::memory_profiler->function_call_logger(),  \
  32  m :          agent::memprof::memory_profiler->GetOrAllocateThreadState()->  \
  33  m :              segment(),  \
  34  m :          __VA_ARGS__);
  35    :  
  36    :  // A conditional scoped lock, based on timestamp serialization. Used to
  37    :  // completely serialize heap access when enabled.
  38  m :  struct ConditionalScopedLock {
  39  m :   public:
  40  m :    ConditionalScopedLock() : locked_(
  41  m :        agent::memprof::memory_profiler->parameters().serialize_timestamps) {
  42  m :      if (locked_)
  43  m :        conditional_lock_.Acquire();
  44  m :    }
  45    :  
  46  m :    ~ConditionalScopedLock() {
  47  m :      if (locked_)
  48  m :        conditional_lock_.Release();
  49  m :    }
  50    :  
  51  m :   private:
  52  m :    static base::Lock conditional_lock_;
  53  m :    bool locked_;
  54  m :  };
  55  m :  base::Lock ConditionalScopedLock::conditional_lock_;
  56    :  
  57  m :  extern "C" {
  58    :  
  59  m :  HANDLE WINAPI asan_GetProcessHeap() {
  60    :    // This function doesn't need to be logged, but does need to be implemented
  61    :    // for compatibility with old ASAN implementations.
  62  m :    return ::GetProcessHeap();
  63  m :  }
  64    :  
  65  m :  HANDLE WINAPI asan_HeapCreate(DWORD options,
  66  m :                                SIZE_T initial_size,
  67  m :                                SIZE_T maximum_size) {
  68    :    // This ensures that all heap access is synchronous if 'serialize_timestamps'
  69    :    // is enabled.
  70  m :    ConditionalScopedLock conditional_scoped_lock;
  71  m :    HANDLE ret = ::HeapCreate(options, initial_size, maximum_size);
  72  m :    EMIT_DETAILED_HEAP_FUNCTION_CALL(options, initial_size, maximum_size, ret);
  73  m :    return ret;
  74  m :  }
  75    :  
  76  m :  BOOL WINAPI asan_HeapDestroy(HANDLE heap) {
  77    :    // This ensures that all heap access is synchronous if 'serialize_timestamps'
  78    :    // is enabled.
  79  m :    ConditionalScopedLock conditional_scoped_lock;
  80  m :    BOOL ret = ::HeapDestroy(heap);
  81  m :    EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, ret);
  82  m :    return ret;
  83  m :  }
  84    :  
  85  m :  LPVOID WINAPI asan_HeapAlloc(HANDLE heap,
  86  m :                               DWORD flags,
  87  m :                               SIZE_T bytes) {
  88    :    // This ensures that all heap access is synchronous if 'serialize_timestamps'
  89    :    // is enabled.
  90  m :    ConditionalScopedLock conditional_scoped_lock;
  91  m :    LPVOID ret = ::HeapAlloc(heap, flags, bytes);
  92  m :    EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, flags, bytes, ret);
  93  m :    return ret;
  94  m :  }
  95    :  
  96  m :  LPVOID WINAPI asan_HeapReAlloc(HANDLE heap,
  97  m :                                 DWORD flags,
  98  m :                                 LPVOID mem,
  99  m :                                 SIZE_T bytes) {
 100    :    // This ensures that all heap access is synchronous if 'serialize_timestamps'
 101    :    // is enabled.
 102  m :    ConditionalScopedLock conditional_scoped_lock;
 103  m :    LPVOID ret = ::HeapReAlloc(heap, flags, mem, bytes);
 104  m :    EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, flags, mem, bytes, ret);
 105  m :    return ret;
 106  m :  }
 107    :  
 108  m :  BOOL WINAPI asan_HeapFree(HANDLE heap,
 109  m :                            DWORD flags,
 110  m :                            LPVOID mem) {
 111    :    // Calculate a hash value of the contents if necessary.
 112  m :    uint32_t hash = 0;
 113  m :    if (mem != nullptr &&
 114  m :        agent::memprof::memory_profiler->parameters().hash_contents_at_free) {
 115  m :      size_t size = ::HeapSize(heap, 0, mem);
 116  m :      hash = base::SuperFastHash(reinterpret_cast<const char*>(mem), size);
 117  m :    }
 118    :  
 119    :    // This ensures that all heap access is synchronous if 'serialize_timestamps'
 120    :    // is enabled.
 121  m :    ConditionalScopedLock conditional_scoped_lock;
 122  m :    BOOL ret = ::HeapFree(heap, flags, mem);
 123  m :    EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, flags, mem, ret, hash);
 124  m :    return ret;
 125  m :  }
 126    :  
 127  m :  SIZE_T WINAPI asan_HeapSize(HANDLE heap,
 128  m :                              DWORD flags,
 129  m :                              LPCVOID mem) {
 130    :    // This ensures that all heap access is synchronous if 'serialize_timestamps'
 131    :    // is enabled.
 132  m :    ConditionalScopedLock conditional_scoped_lock;
 133  m :    SIZE_T ret = ::HeapSize(heap, flags, mem);
 134  m :    EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, flags, mem, ret);
 135  m :    return ret;
 136  m :  }
 137    :  
 138  m :  BOOL WINAPI asan_HeapValidate(HANDLE heap,
 139  m :                                DWORD flags,
 140  m :                                LPCVOID mem) {
 141    :    // This ensures that all heap access is synchronous if 'serialize_timestamps'
 142    :    // is enabled.
 143  m :    ConditionalScopedLock conditional_scoped_lock;
 144  m :    BOOL ret = ::HeapValidate(heap, flags, mem);
 145  m :    EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, flags, mem, ret);
 146  m :    return ret;
 147  m :  }
 148    :  
 149  m :  SIZE_T WINAPI asan_HeapCompact(HANDLE heap,
 150  m :                                 DWORD flags) {
 151    :    // This ensures that all heap access is synchronous if 'serialize_timestamps'
 152    :    // is enabled.
 153  m :    ConditionalScopedLock conditional_scoped_lock;
 154  m :    SIZE_T ret = ::HeapCompact(heap, flags);
 155  m :    EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, flags, ret);
 156  m :    return ret;
 157  m :  }
 158    :  
 159  m :  BOOL WINAPI asan_HeapLock(HANDLE heap) {
 160    :    // This ensures that all heap access is synchronous if 'serialize_timestamps'
 161    :    // is enabled.
 162  m :    ConditionalScopedLock conditional_scoped_lock;
 163  m :    BOOL ret = ::HeapLock(heap);
 164  m :    EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, ret);
 165  m :    return ret;
 166  m :  }
 167    :  
 168  m :  BOOL WINAPI asan_HeapUnlock(HANDLE heap) {
 169    :    // This ensures that all heap access is synchronous if 'serialize_timestamps'
 170    :    // is enabled.
 171  m :    ConditionalScopedLock conditional_scoped_lock;
 172  m :    BOOL ret = ::HeapUnlock(heap);
 173  m :    EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, ret);
 174  m :    return ret;
 175  m :  }
 176    :  
 177  m :  BOOL WINAPI asan_HeapWalk(HANDLE heap,
 178  m :                            LPPROCESS_HEAP_ENTRY entry) {
 179    :    // This ensures that all heap access is synchronous if 'serialize_timestamps'
 180    :    // is enabled.
 181  m :    ConditionalScopedLock conditional_scoped_lock;
 182  m :    BOOL ret = ::HeapWalk(heap, entry);
 183  m :    EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, entry, ret);
 184  m :    return ret;
 185  m :  }
 186    :  
 187  m :  BOOL WINAPI asan_HeapSetInformation(
 188  m :      HANDLE heap, HEAP_INFORMATION_CLASS info_class,
 189  m :      PVOID info, SIZE_T info_length) {
 190    :    // This ensures that all heap access is synchronous if 'serialize_timestamps'
 191    :    // is enabled.
 192  m :    ConditionalScopedLock conditional_scoped_lock;
 193  m :    BOOL ret = ::HeapSetInformation(heap, info_class, info, info_length);
 194  m :    EMIT_DETAILED_HEAP_FUNCTION_CALL(heap, info_class, info, info_length, ret);
 195  m :    return ret;
 196  m :  }
 197    :  
 198  m :  BOOL WINAPI asan_HeapQueryInformation(
 199  m :      HANDLE heap, HEAP_INFORMATION_CLASS info_class,
 200  m :      PVOID info, SIZE_T info_length, PSIZE_T return_length) {
 201    :    // This ensures that all heap access is synchronous if 'serialize_timestamps'
 202    :    // is enabled.
 203  m :    ConditionalScopedLock conditional_scoped_lock;
 204  m :    BOOL ret = ::HeapQueryInformation(
 205  m :        heap, info_class, info, info_length, return_length);
 206  m :    EMIT_DETAILED_HEAP_FUNCTION_CALL(
 207  m :        heap, info_class, info, info_length, return_length, ret);
 208  m :    return ret;
 209  m :  }
 210    :  
 211  m :  }  // extern "C"

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