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

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%40400.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 biggest gain observed on stack cache compression is when we skip the 5
  35    :  // bottom frames of the stack traces. To measure this gain we've run an
  36    :  // instrumented version of base_unittests and observed the cache compression.
  37    :  // With a value between 0 and 4 the compression ratio was around 28.9%, and with
  38    :  // a value of 5 it was 92.19%.
  39    :  // NOTE: This is mostly for Chrome's unittests, the side effect is that the
  40    :  //     bottom frames of the allocation and free stack traces of any instrumented
  41    :  //     image will be elided, but from what we've seen they're rarely precise and
  42    :  //     useful (they refer to the entry point of the image).
  43    :  size_t StackCapture::bottom_frames_to_skip_ = 5;
  44    :  
  45  E :  size_t StackCapture::GetSize(size_t max_num_frames) {
  46  E :    DCHECK_LT(0u, max_num_frames);
  47  E :    max_num_frames = std::min(max_num_frames, kMaxNumFrames);
  48  E :    return offsetof(StackCapture, frames_) + max_num_frames * sizeof(void*);
  49  E :  }
  50    :  
  51    :  void StackCapture::InitFromBuffer(StackId stack_id,
  52    :                                    const void* const* frames,
  53  E :                                    size_t num_frames) {
  54  E :    DCHECK(frames != NULL);
  55  E :    DCHECK_LT(0U, num_frames);
  56  E :    stack_id_ = stack_id;
  57  E :    num_frames_ = std::min<uint8>(num_frames, max_num_frames_);
  58  E :    ::memcpy(frames_, frames, num_frames_ * sizeof(void*));
  59  E :  }
  60    :  
  61  E :  StackCapture::StackId StackCapture::ComputeRelativeStackId() {
  62    :    // We want to ignore the frames relative to our module to be able to get the
  63    :    // same trace id even if we update our runtime.
  64  E :    HANDLE asan_handle = reinterpret_cast<HANDLE>(&__ImageBase);
  65  E :    DCHECK(asan_handle != NULL);
  66    :  
  67  E :    StackId stack_id = 0;
  68  E :    for (size_t i = 0; i < num_frames_; ++i) {
  69  E :      HMODULE module = base::GetModuleFromAddress(frames_[i]);
  70  E :      if (module == NULL || module == asan_handle)
  71  E :        continue;
  72    :      stack_id += reinterpret_cast<size_t>(frames_[i]) -
  73  E :        reinterpret_cast<size_t>(module);
  74  E :    }
  75    :  
  76  E :    return stack_id;
  77  E :  }
  78    :  
  79    :  size_t StackCapture::HashCompare::operator()(
  80  E :      const StackCapture* stack_capture) const {
  81  E :    DCHECK(stack_capture != NULL);
  82    :    // We're assuming that the StackId and size_t have the same size, so let's
  83    :    // make sure that's the case.
  84    :    COMPILE_ASSERT(sizeof(StackId) == sizeof(size_t),
  85    :                   stack_id_and_size_t_not_same_size);
  86  E :    return stack_capture->stack_id_;
  87  E :  }
  88    :  
  89    :  bool StackCapture::HashCompare::operator()(
  90    :      const StackCapture* stack_capture1,
  91  E :      const StackCapture* stack_capture2) const {
  92  E :    DCHECK(stack_capture1 != NULL);
  93  E :    DCHECK(stack_capture2 != NULL);
  94  E :    return stack_capture1->stack_id_ < stack_capture2->stack_id_;
  95  E :  }
  96    :  
  97    :  }  // namespace asan
  98    :  }  // namespace agent

Coverage information generated Thu Mar 14 11:53:36 2013.