Coverage for /Syzygy/agent/asan/asan_runtime.h

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

Line-by-line coverage:

   1    :  // Copyright 2012 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    :  // A class that take care of initializing asan run-time library.
  16    :  
  17    :  #ifndef SYZYGY_AGENT_ASAN_ASAN_RUNTIME_H_
  18    :  #define SYZYGY_AGENT_ASAN_ASAN_RUNTIME_H_
  19    :  
  20    :  #include <set>
  21    :  #include <string>
  22    :  
  23    :  #include "base/callback.h"
  24    :  #include "base/logging.h"
  25    :  #include "base/memory/scoped_ptr.h"
  26    :  #include "base/synchronization/lock.h"
  27    :  #include "syzygy/agent/asan/asan_heap.h"
  28    :  #include "syzygy/agent/asan/stack_capture.h"
  29    :  #include "syzygy/agent/common/dlist.h"
  30    :  
  31    :  namespace agent {
  32    :  namespace asan {
  33    :  
  34    :  class AsanLogger;
  35    :  class StackCaptureCache;
  36    :  
  37    :  // Store the information about a bad memory access.
  38    :  // TODO(sebmarchand): Add an array with the copy of the shadow memory around
  39    :  //     this bad access.
  40    :  struct AsanErrorInfo {
  41    :    void* alloc_stack[agent::asan::StackCapture::kMaxNumFrames];
  42    :    uint8 alloc_stack_size;
  43    :    DWORD alloc_tid;
  44    :    void* free_stack[agent::asan::StackCapture::kMaxNumFrames];
  45    :    uint8 free_stack_size;
  46    :    DWORD free_tid;
  47    :    HeapProxy::BadAccessKind error_type;
  48    :    HeapProxy::AccessMode access_mode;
  49    :    size_t access_size;
  50    :    char shadow_info[128];
  51    :    uint64 microseconds_since_free;
  52    :  };
  53    :  
  54    :  // An Asan Runtime manager.
  55    :  // This class take care of initializing the different modules (stack cache,
  56    :  // logger...) and provide the functions to report an error.
  57    :  // Basic usage:
  58    :  //     AsanRuntime* asan_runtime = new AsanRuntime();
  59    :  //     std::wstring asan_flags_str;
  60    :  //     AsanRuntime::GetAsanFlagsEnvVar(&asan_flags_str);
  61    :  //     asan_runtime->SetUp(asan_flags_str);  // Initialize the modules.
  62    :  //     ...
  63    :  //     CONTEXT context;
  64    :  //     ::RtlCaptureContext(&context);
  65    :  //     StackCapture stack;
  66    :  //     stack.InitFromStack();
  67    :  //     stack.set_stack_id(stack.ComputeRelativeStackId());
  68    :  //     asan_runtime->OnError((&context, stack.stack_id());
  69    :  //     asan_runtime->TearDown();  // Release the modules.
  70    :  //     delete asan_runtime;
  71    :  class AsanRuntime {
  72    :   public:
  73    :    typedef std::set<StackCapture::StackId> StackIdSet;
  74    :  
  75    :    // The type of callback used by the OnError function.
  76    :    typedef base::Callback<void(CONTEXT*, AsanErrorInfo*)> AsanOnErrorCallBack;
  77    :  
  78    :    AsanRuntime();
  79    :    ~AsanRuntime();
  80    :  
  81    :    // @name Accessors.
  82    :    // @{
  83  E :    AsanLogger* logger() {
  84  E :      DCHECK(logger_.get() != NULL);
  85  E :      return logger_.get();
  86  E :    }
  87  E :    StackCaptureCache* stack_cache() {
  88  E :      DCHECK(stack_cache_.get() != NULL);
  89  E :      return stack_cache_.get();
  90  E :    }
  91  E :    static const wchar_t* SyzyAsanDll() {
  92  E :      return kSyzyAsanDll;
  93  E :    }
  94    :    // @}
  95    :  
  96    :    // Initialize asan runtime library.
  97    :    // @param flags_command_line The parameters string.
  98    :    void SetUp(const std::wstring& flags_command_line);
  99    :  
 100    :    // Release asan runtime library.
 101    :    void TearDown();
 102    :  
 103    :    // The error handler.
 104    :    // @param context The context when the error has been reported.
 105    :    // @param error_info The information about this error.
 106    :    void OnError(CONTEXT* context, AsanErrorInfo* error_info);
 107    :  
 108    :    // Set the callback called on error.
 109    :    // TODO(sebmarchand): Move the signature of this callback to an header file
 110    :    //     so it'll be easier to update it.
 111    :    void SetErrorCallBack(const AsanOnErrorCallBack& callback);
 112    :  
 113    :    // Try to read the Asan environment variable.
 114    :    // @param env_var_wstr The wstring where to store the environment variable.
 115    :    // returns true on success, false otherwise.
 116    :    static bool GetAsanFlagsEnvVar(std::wstring* env_var_wstr);
 117    :  
 118    :    // Add an heap proxy to the heap proxies list.
 119    :    void AddHeap(HeapProxy* heap);
 120    :  
 121    :    // Remove an heap proxy from the heap proxies list.
 122    :    void RemoveHeap(HeapProxy* heap);
 123    :  
 124    :    // Report the details of an Asan error by walking the heap proxies list.
 125    :    // @param addr The red-zoned address causing a bad access.
 126    :    // @param context The context at which the access occurred.
 127    :    // @param stack The stack capture at the point of error.
 128    :    // @param access_mode The kind of the access (read or write).
 129    :    // @param access_size The size of the access (in bytes).
 130    :    // @param bad_access_info Will receive the information about this access.
 131    :    void ReportAsanErrorDetails(const void* addr,
 132    :                                const CONTEXT& context,
 133    :                                const StackCapture& stack,
 134    :                                HeapProxy::AccessMode access_mode,
 135    :                                size_t access_size,
 136    :                                AsanErrorInfo* bad_access_info);
 137    :  
 138    :    // Returns true if we should ignore the given @p stack_id, false
 139    :    // otherwise.
 140  E :    bool ShouldIgnoreError(size_t stack_id) const {
 141    :      // TODO(sebmarchand): Keep a list of the stack ids that have already been
 142    :      //     reported so we can avoid reporting the same error multiple times.
 143    :      return flags_.ignored_stack_ids.find(stack_id) !=
 144  E :          flags_.ignored_stack_ids.end();
 145  E :    }
 146    :  
 147    :   protected:
 148    :    // A structure to track the values of the flags.
 149    :    struct AsanFlags {
 150    :      AsanFlags()
 151    :          : quarantine_size(0U),
 152    :            reporting_period(0U),
 153    :            bottom_frames_to_skip(0U),
 154    :            max_num_frames(0U),
 155    :            exit_on_failure(false),
 156    :            minidump_on_failure(false),
 157  E :            log_as_text(true) {
 158  E :      }
 159    :  
 160    :      // The default size of the quarantine of the HeapProxy, in bytes.
 161    :      size_t quarantine_size;
 162    :  
 163    :      // The number of allocations between reports of the stack trace cache
 164    :      // compression ratio.
 165    :      size_t reporting_period;
 166    :  
 167    :      // The number of bottom frames to skip on a stack trace.
 168    :      size_t bottom_frames_to_skip;
 169    :  
 170    :      // The max number of frames for a stack trace.
 171    :      size_t max_num_frames;
 172    :  
 173    :      // The stack ids we ignore.
 174    :      StackIdSet ignored_stack_ids;
 175    :  
 176    :      // If true, we should generate a minidump whenever an error is detected.
 177    :      // Defaults to false.
 178    :      bool minidump_on_failure;
 179    :  
 180    :      // If we should stop the logger (and the running program) after reporting
 181    :      // an error. Defaults to false.
 182    :      bool exit_on_failure;
 183    :  
 184    :      // If true, we should generate a textual log describing any errors.
 185    :      // Defaults to true;
 186    :      bool log_as_text;
 187    :    };
 188    :  
 189    :    // The name of the environment variable containing the command-line.
 190    :    static const char kSyzyAsanEnvVar[];
 191    :  
 192    :    // @name Flag strings.
 193    :    // @{
 194    :    static const char kBottomFramesToSkip[];
 195    :    static const char kCompressionReportingPeriod[];
 196    :    static const char kExitOnFailure[];
 197    :    static const char kIgnoredStackIds[];
 198    :    static const char kMaxNumberOfFrames[];
 199    :    static const char kMiniDumpOnFailure[];
 200    :    static const char kNoLogAsText[];
 201    :    static const char kQuarantineSize[];
 202    :    static const wchar_t kSyzyAsanDll[];
 203    :    // @}
 204    :  
 205    :    // @name Accessors.
 206    :    // @{
 207  E :    const AsanFlags* const flags() { return &flags_; }
 208    :    // @}
 209    :  
 210    :    // @name Mutators.
 211    :    // @{
 212    :    void set_flags(const AsanFlags* flags);
 213    :    // @}
 214    :  
 215    :    // Propagate the values of the flags to the target modules.
 216    :    void PropagateFlagsValues() const;
 217    :  
 218    :   private:
 219    :    // Set up the logger.
 220    :    void SetUpLogger();
 221    :  
 222    :    // Tear down the logger.
 223    :    void TearDownLogger();
 224    :  
 225    :    // Set up the stack cache.
 226    :    void SetUpStackCache();
 227    :  
 228    :    // Tear down the stack cache.
 229    :    void TearDownStackCache();
 230    :  
 231    :    // Parse and set the flags from the wide string @p str.
 232    :    bool ParseFlagsFromString(std::wstring str);
 233    :  
 234    :    // The shared logger instance that will be used by all heap proxies.
 235    :    scoped_ptr<AsanLogger> logger_;
 236    :  
 237    :    // The shared stack cache instance that will be used by all heap proxies.
 238    :    scoped_ptr<StackCaptureCache> stack_cache_;
 239    :  
 240    :    // The asan error callback functor.
 241    :    AsanOnErrorCallBack asan_error_callback_;
 242    :  
 243    :    // The values of the flags.
 244    :    AsanFlags flags_;
 245    :  
 246    :    // The heap proxies list lock.
 247    :    base::Lock heap_proxy_dlist_lock_;
 248    :  
 249    :    // The heap proxies list.
 250    :    LIST_ENTRY heap_proxy_dlist_;  // Under heap_proxy_dlist_lock.
 251    :  
 252    :    DISALLOW_COPY_AND_ASSIGN(AsanRuntime);
 253    :  };
 254    :  
 255    :  }  // namespace asan
 256    :  }  // namespace agent
 257    :  
 258    :  #endif  // SYZYGY_AGENT_ASAN_ASAN_RUNTIME_H_

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