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

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
87.1%54620.C++source

Line-by-line coverage:

   1    :  // Copyright 2013 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/stack_capture.h"
  16    :  
  17    :  #include "base/logging.h"
  18    :  #include "base/process_util.h"
  19    :  
  20    :  // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
  21    :  extern "C" IMAGE_DOS_HEADER __ImageBase;
  22    :  
  23    :  namespace agent {
  24    :  namespace asan {
  25    :  
  26  E :  uint32 ComputeStackTraceHash(void** stack_trace, uint8 stack_depth) {
  27  E :    uint32 hash_value = 0;
  28  E :    for (uint8 i = 0; i < stack_depth; ++i) {
  29  E :      hash_value += reinterpret_cast<uint32>(stack_trace[i]);
  30  E :    }
  31  E :    return hash_value;
  32  E :  }
  33    :  
  34    :  // The number of bottom frames to skip per stack trace.
  35    :  size_t StackCapture::bottom_frames_to_skip_ = kDefaultBottomFramesToSkip_;
  36    :  
  37  E :  size_t StackCapture::GetSize(size_t max_num_frames) {
  38  E :    DCHECK_LT(0u, max_num_frames);
  39  E :    max_num_frames = std::min(max_num_frames, kMaxNumFrames);
  40  E :    return offsetof(StackCapture, frames_) + max_num_frames * sizeof(void*);
  41  E :  }
  42    :  
  43  i :  size_t StackCapture::GetMaxNumFrames(size_t bytes) {
  44  i :    if (bytes < offsetof(StackCapture, frames_))
  45  i :      return 0;
  46  i :    bytes -= offsetof(StackCapture, frames_);
  47  i :    bytes /= sizeof(void*);
  48  i :    return bytes;
  49  i :  }
  50    :  
  51  E :  void StackCapture::AddRef() {
  52  E :    if (RefCountIsSaturated())
  53  i :      return;
  54  E :    DCHECK_GT(kMaxRefCount, ref_count_);
  55  E :    ++ref_count_;
  56  E :  }
  57    :  
  58  E :  void StackCapture::RemoveRef() {
  59  E :    DCHECK_LT(0u, ref_count_);
  60  E :    if (RefCountIsSaturated())
  61  E :      return;
  62  E :    --ref_count_;
  63  E :  }
  64    :  
  65  E :  void StackCapture::Init() {
  66  E :    bottom_frames_to_skip_ = kDefaultBottomFramesToSkip_;
  67  E :  }
  68    :  
  69    :  void StackCapture::InitFromBuffer(StackId stack_id,
  70    :                                    const void* const* frames,
  71  E :                                    size_t num_frames) {
  72  E :    DCHECK(frames != NULL);
  73  E :    DCHECK_LT(0U, num_frames);
  74  E :    stack_id_ = stack_id;
  75  E :    num_frames_ = std::min<uint8>(num_frames, max_num_frames_);
  76  E :    ::memcpy(frames_, frames, num_frames_ * sizeof(void*));
  77  E :  }
  78    :  
  79  E :  StackCapture::StackId StackCapture::ComputeRelativeStackId() {
  80    :    // We want to ignore the frames relative to our module to be able to get the
  81    :    // same trace id even if we update our runtime.
  82  E :    HANDLE asan_handle = reinterpret_cast<HANDLE>(&__ImageBase);
  83  E :    DCHECK(asan_handle != NULL);
  84    :  
  85  E :    StackId stack_id = 0;
  86  E :    for (size_t i = 0; i < num_frames_; ++i) {
  87  E :      HMODULE module = base::GetModuleFromAddress(frames_[i]);
  88  E :      if (module == NULL || module == asan_handle)
  89  E :        continue;
  90    :      stack_id += reinterpret_cast<size_t>(frames_[i]) -
  91  E :        reinterpret_cast<size_t>(module);
  92  E :    }
  93    :  
  94  E :    return stack_id;
  95  E :  }
  96    :  
  97    :  size_t StackCapture::HashCompare::operator()(
  98  E :      const StackCapture* stack_capture) const {
  99  E :    DCHECK(stack_capture != NULL);
 100    :    // We're assuming that the StackId and size_t have the same size, so let's
 101    :    // make sure that's the case.
 102    :    COMPILE_ASSERT(sizeof(StackId) == sizeof(size_t),
 103    :                   stack_id_and_size_t_not_same_size);
 104  E :    return stack_capture->stack_id_;
 105  E :  }
 106    :  
 107    :  bool StackCapture::HashCompare::operator()(
 108    :      const StackCapture* stack_capture1,
 109  E :      const StackCapture* stack_capture2) const {
 110  E :    DCHECK(stack_capture1 != NULL);
 111  E :    DCHECK(stack_capture2 != NULL);
 112  E :    return stack_capture1->stack_id_ < stack_capture2->stack_id_;
 113  E :  }
 114    :  
 115    :  }  // namespace asan
 116    :  }  // namespace agent

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