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

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%13130.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    :  
  36    :  // Store the information about a bad memory access.
  37    :  struct AsanErrorInfo {
  38    :    // The address where the bad access happened.
  39    :    void* location;
  40    :    // The context prior to the crash.
  41    :    CONTEXT context;
  42    :    // The allocation stack trace.
  43    :    void* alloc_stack[agent::asan::StackCapture::kMaxNumFrames];
  44    :    // The size of the allocation stack trace.
  45    :    uint8 alloc_stack_size;
  46    :    // The ID of the allocation thread.
  47    :    DWORD alloc_tid;
  48    :    // The free stack trace.
  49    :    void* free_stack[agent::asan::StackCapture::kMaxNumFrames];
  50    :    // The size of the free stack trace.
  51    :    uint8 free_stack_size;
  52    :    // The ID of the free thread.
  53    :    DWORD free_tid;
  54    :    // The ID of the crash stack, this is needed to be able to blacklist some
  55    :    // known bugs.
  56    :    StackCapture::StackId crash_stack_id;
  57    :    // The error type.
  58    :    HeapProxy::BadAccessKind error_type;
  59    :    // The access mode.
  60    :    HeapProxy::AccessMode access_mode;
  61    :    // The access size.
  62    :    size_t access_size;
  63    :    // The information about the shadow memory for this address, this would be
  64    :    // something like: "0x12345678 is located 8 bytes inside of 10-bytes region
  65    :    // [0x12345670,0x1234567A)."
  66    :    char shadow_info[128];
  67    :    // A textual description of the shadow memory around |location|.
  68    :    char shadow_memory[512];
  69    :    // The time since the memory block containing this address has been freed.
  70    :    // This would be equal to zero if the block is still allocated.
  71    :    uint64 microseconds_since_free;
  72    :  };
  73    :  
  74    :  // An Asan Runtime manager.
  75    :  // This class takes care of initializing the different modules (stack cache,
  76    :  // logger...) and provide the functions to report an error.
  77    :  // Basic usage:
  78    :  //     AsanRuntime* asan_runtime = new AsanRuntime();
  79    :  //     std::wstring asan_flags_str;
  80    :  //     AsanRuntime::GetAsanFlagsEnvVar(&asan_flags_str);
  81    :  //     asan_runtime->SetUp(asan_flags_str);  // Initialize the modules.
  82    :  //     ...
  83    :  //     AsanErrorInfo bad_access_info = {};
  84    :  //     ::RtlCaptureContext(&bad_access_info.context);
  85    :  //     StackCapture stack;
  86    :  //     stack.InitFromStack();
  87    :  //     stack.set_stack_id(stack.ComputeRelativeStackId());
  88    :  //     bad_access_info.crash_stack_id = stack.stack_id();
  89    :  //     asan_runtime->OnError(&bad_access_info);
  90    :  //     asan_runtime->TearDown();  // Release the modules.
  91    :  //     delete asan_runtime;
  92    :  class AsanRuntime {
  93    :   public:
  94    :    typedef std::set<StackCapture::StackId> StackIdSet;
  95    :  
  96    :    // The type of callback used by the OnError function.
  97    :    typedef base::Callback<void(AsanErrorInfo*)> AsanOnErrorCallBack;
  98    :  
  99    :    AsanRuntime();
 100    :    ~AsanRuntime();
 101    :  
 102    :    // @name Accessors.
 103    :    // @{
 104    :    AsanLogger* logger() {
 105    :      DCHECK(logger_.get() != NULL);
 106    :      return logger_.get();
 107    :    }
 108  E :    StackCaptureCache* stack_cache() {
 109  E :      DCHECK(stack_cache_.get() != NULL);
 110  E :      return stack_cache_.get();
 111  E :    }
 112  E :    static const wchar_t* SyzyAsanDll() {
 113  E :      return kSyzyAsanDll;
 114  E :    }
 115    :    // @}
 116    :  
 117    :    // Initialize asan runtime library.
 118    :    // @param flags_command_line The parameters string.
 119    :    void SetUp(const std::wstring& flags_command_line);
 120    :  
 121    :    // Release asan runtime library.
 122    :    void TearDown();
 123    :  
 124    :    // The error handler.
 125    :    // @param error_info The information about this error.
 126    :    void OnError(AsanErrorInfo* error_info);
 127    :  
 128    :    // Set the callback called on error.
 129    :    // TODO(sebmarchand): Move the signature of this callback to an header file
 130    :    //     so it'll be easier to update it.
 131    :    void SetErrorCallBack(const AsanOnErrorCallBack& callback);
 132    :  
 133    :    // Try to read the Asan environment variable.
 134    :    // @param env_var_wstr The wstring where to store the environment variable.
 135    :    // returns true on success, false otherwise.
 136    :    static bool GetAsanFlagsEnvVar(std::wstring* env_var_wstr);
 137    :  
 138    :    // Add an heap proxy to the heap proxies list.
 139    :    void AddHeap(HeapProxy* heap);
 140    :  
 141    :    // Remove an heap proxy from the heap proxies list.
 142    :    void RemoveHeap(HeapProxy* heap);
 143    :  
 144    :    // Returns true if we should ignore the given @p stack_id, false
 145    :    // otherwise.
 146  E :    bool ShouldIgnoreError(size_t stack_id) const {
 147    :      // TODO(sebmarchand): Keep a list of the stack ids that have already been
 148    :      //     reported so we can avoid reporting the same error multiple times.
 149    :      return flags_.ignored_stack_ids.find(stack_id) !=
 150  E :          flags_.ignored_stack_ids.end();
 151  E :    }
 152    :  
 153    :    // Get information about a bad access.
 154    :    // @param bad_access_info Will receive the information about this access.
 155    :    void GetBadAccessInformation(AsanErrorInfo* error_info);
 156    :  
 157    :    // The name of the environment variable holding the experiment opt-in coin
 158    :    // toss value.
 159    :    static const char kSyzygyAsanCoinTossEnvVar[];
 160    :  
 161    :    // The name of the environment variable containing the command-line.
 162    :    static const char kSyzygyAsanOptionsEnvVar[];
 163    :  
 164    :   protected:
 165    :    // A structure to track the values of the flags.
 166    :    struct AsanFlags {
 167    :      AsanFlags()
 168    :          : quarantine_size(0U),
 169    :            reporting_period(0U),
 170    :            bottom_frames_to_skip(0U),
 171    :            max_num_frames(0U),
 172    :            trailer_padding_size(0U),
 173    :            exit_on_failure(false),
 174    :            minidump_on_failure(false),
 175    :            log_as_text(true),
 176    :            opted_in(false),
 177  E :            coin_toss(0) {
 178  E :      }
 179    :  
 180    :      // The default size of the quarantine of the HeapProxy, in bytes.
 181    :      size_t quarantine_size;
 182    :  
 183    :      // The number of allocations between reports of the stack trace cache
 184    :      // compression ratio.
 185    :      size_t reporting_period;
 186    :  
 187    :      // The number of bottom frames to skip on a stack trace.
 188    :      size_t bottom_frames_to_skip;
 189    :  
 190    :      // The max number of frames for a stack trace.
 191    :      size_t max_num_frames;
 192    :  
 193    :      // The size of the padding added to every memory block trailer.
 194    :      size_t trailer_padding_size;
 195    :  
 196    :      // The stack ids we ignore.
 197    :      StackIdSet ignored_stack_ids;
 198    :  
 199    :      // If true, we should generate a minidump whenever an error is detected.
 200    :      // Defaults to false.
 201    :      bool minidump_on_failure;
 202    :  
 203    :      // If we should stop the logger (and the running program) after reporting
 204    :      // an error. Defaults to false.
 205    :      bool exit_on_failure;
 206    :  
 207    :      // If true, we should generate a textual log describing any errors.
 208    :      // Defaults to true;
 209    :      bool log_as_text;
 210    :  
 211    :      // Experiment configuration.
 212    :      bool opted_in;
 213    :      uint64 coin_toss;
 214    :    };
 215    :  
 216    :    // @name Flag strings.
 217    :    // @{
 218    :    static const char kBottomFramesToSkip[];
 219    :    static const char kCompressionReportingPeriod[];
 220    :    static const char kExitOnFailure[];
 221    :    static const char kIgnoredStackIds[];
 222    :    static const char kMaxNumberOfFrames[];
 223    :    static const char kMiniDumpOnFailure[];
 224    :    static const char kNoLogAsText[];
 225    :    static const char kQuarantineSize[];
 226    :    static const wchar_t kSyzyAsanDll[];
 227    :    static const char kTrailerPaddingSize[];
 228    :    // @}
 229    :  
 230    :    // @name Accessors.
 231    :    // @{
 232  E :    const AsanFlags* const flags() { return &flags_; }
 233    :    // @}
 234    :  
 235    :    // @name Mutators.
 236    :    // @{
 237    :    void set_flags(const AsanFlags* flags);
 238    :    // @}
 239    :  
 240    :    // Propagate the values of the flags to the target modules.
 241    :    void PropagateFlagsValues() const;
 242    :  
 243    :   private:
 244    :    // Set up the logger.
 245    :    void SetUpLogger();
 246    :  
 247    :    // Tear down the logger.
 248    :    void TearDownLogger();
 249    :  
 250    :    // Set up the stack cache.
 251    :    void SetUpStackCache();
 252    :  
 253    :    // Tear down the stack cache.
 254    :    void TearDownStackCache();
 255    :  
 256    :    // Parse and set the flags from the wide string @p str.
 257    :    bool ParseFlagsFromString(std::wstring str);
 258    :  
 259    :    // The shared logger instance that will be used by all heap proxies.
 260    :    scoped_ptr<AsanLogger> logger_;
 261    :  
 262    :    // The shared stack cache instance that will be used by all heap proxies.
 263    :    scoped_ptr<StackCaptureCache> stack_cache_;
 264    :  
 265    :    // The asan error callback functor.
 266    :    AsanOnErrorCallBack asan_error_callback_;
 267    :  
 268    :    // The values of the flags.
 269    :    AsanFlags flags_;
 270    :  
 271    :    // The heap proxies list lock.
 272    :    base::Lock heap_proxy_dlist_lock_;
 273    :  
 274    :    // The heap proxies list.
 275    :    LIST_ENTRY heap_proxy_dlist_;  // Under heap_proxy_dlist_lock.
 276    :  
 277    :    DISALLOW_COPY_AND_ASSIGN(AsanRuntime);
 278    :  };
 279    :  
 280    :  }  // namespace asan
 281    :  }  // namespace agent
 282    :  
 283    :  #endif  // SYZYGY_AGENT_ASAN_ASAN_RUNTIME_H_

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