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

Coverage information generated Wed Dec 11 11:34:16 2013.