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

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
98.3%58590.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    :  #include "syzygy/agent/asan/asan_logger.h"
  16    :  
  17    :  #include "base/command_line.h"
  18    :  #include "base/environment.h"
  19    :  #include "base/logging.h"
  20    :  #include "base/process_util.h"
  21    :  #include "base/stringprintf.h"
  22    :  #include "base/utf_string_conversions.h"
  23    :  #include "base/debug/stack_trace.h"
  24    :  #include "base/memory/scoped_ptr.h"
  25    :  #include "syzygy/trace/rpc/logger_rpc.h"
  26    :  #include "syzygy/trace/rpc/rpc_helpers.h"
  27    :  
  28    :  namespace agent {
  29    :  namespace asan {
  30    :  
  31    :  namespace {
  32    :  
  33    :  using trace::client::GetInstanceString;
  34    :  
  35    :  AsanLogger* logger_instance = NULL;
  36    :  
  37    :  void InitExecutionContext(const CONTEXT& rtl_context,
  38  E :                            ExecutionContext* exc_context) {
  39  E :    DCHECK(exc_context != NULL);
  40    :  
  41  E :    exc_context->edi = rtl_context.Edi;
  42  E :    exc_context->esi = rtl_context.Esi;
  43  E :    exc_context->ebx = rtl_context.Ebx;
  44  E :    exc_context->edx = rtl_context.Edx;
  45  E :    exc_context->ecx = rtl_context.Ecx;
  46  E :    exc_context->eax = rtl_context.Eax;
  47  E :    exc_context->ebp = rtl_context.Ebp;
  48  E :    exc_context->eip = rtl_context.Eip;
  49  E :    exc_context->seg_cs = rtl_context.SegCs;
  50  E :    exc_context->eflags = rtl_context.EFlags;
  51  E :    exc_context->esp = rtl_context.Esp;
  52  E :    exc_context->seg_ss = rtl_context.SegSs;
  53  E :  }
  54    :  
  55    :  }  // namespace
  56    :  
  57  E :  AsanLogger::AsanLogger() : log_as_text_(true), minidump_on_failure_(false) {
  58  E :  }
  59    :  
  60  E :  void AsanLogger::Init() {
  61    :    bool success = rpc_binding_.Open(
  62    :        kLoggerRpcProtocol,
  63  E :        GetInstanceString(kLoggerRpcEndpointRoot, instance_id_));
  64    :  
  65    :    // TODO(rogerm): Add a notion of a session to the logger interface. Opening
  66    :    //     a session (either here, or on first use) allows for better management
  67    :    //     of symbol context across trace log messages for a given process.
  68  E :    if (success) {
  69  E :      const CommandLine* command_line = CommandLine::ForCurrentProcess();
  70    :      std::string message = base::StringPrintf(
  71    :          "PID=%d; cmd-line='%ls'\n",
  72    :          ::GetCurrentProcessId(),
  73  E :          command_line->GetCommandLineString().c_str());
  74    :      success = trace::client::InvokeRpc(
  75    :          &LoggerClient_Write,
  76    :          rpc_binding_.Get(),
  77  E :          reinterpret_cast<const unsigned char*>(message.c_str())).succeeded();
  78  E :      if (!success)
  79  E :        rpc_binding_.Close();
  80  E :    }
  81  E :  }
  82    :  
  83  E :  void AsanLogger::Stop() {
  84  E :    if (rpc_binding_.Get() != NULL) {
  85    :      trace::client::InvokeRpc(
  86    :          &LoggerClient_Stop,
  87  E :          rpc_binding_.Get());
  88    :    }
  89  E :  }
  90    :  
  91  E :  void AsanLogger::Write(const std::string& message) {
  92    :    // If we're bound to a logging endpoint, log the message there.
  93  E :    if (rpc_binding_.Get() != NULL) {
  94    :      trace::client::InvokeRpc(
  95    :          &LoggerClient_Write,
  96    :          rpc_binding_.Get(),
  97  E :          reinterpret_cast<const unsigned char*>(message.c_str()));
  98    :    }
  99  E :  }
 100    :  
 101    :  void AsanLogger::WriteWithContext(const std::string& message,
 102  E :                                    const CONTEXT& context) {
 103    :    // If we're bound to a logging endpoint, log the message there.
 104  E :    if (rpc_binding_.Get() != NULL) {
 105  E :      ExecutionContext exec_context = {};
 106  E :      InitExecutionContext(context, &exec_context);
 107    :      trace::client::InvokeRpc(
 108    :          &LoggerClient_WriteWithContext,
 109    :          rpc_binding_.Get(),
 110    :          reinterpret_cast<const unsigned char*>(message.c_str()),
 111  E :          &exec_context);
 112    :    }
 113  E :  }
 114    :  
 115    :  void AsanLogger::WriteWithStackTrace(const std::string& message,
 116    :                                       const void * const * trace_data,
 117  E :                                       size_t trace_length) {
 118    :    // If we're bound to a logging endpoint, log the message there.
 119  E :    if (rpc_binding_.Get() != NULL) {
 120    :      trace::client::InvokeRpc(
 121    :          &LoggerClient_WriteWithTrace,
 122    :          rpc_binding_.Get(),
 123    :          reinterpret_cast<const unsigned char*>(message.c_str()),
 124    :          reinterpret_cast<const DWORD*>(trace_data),
 125  E :          trace_length);
 126    :    }
 127  E :  }
 128    :  
 129  E :  void AsanLogger::SaveMiniDump(CONTEXT* context, AsanErrorInfo* error_info) {
 130  E :    DCHECK(context != NULL);
 131  E :    DCHECK(error_info != NULL);
 132    :  
 133  E :    if (rpc_binding_.Get() == NULL)
 134  i :      return;
 135    :  
 136  E :    EXCEPTION_RECORD exception = {};
 137  E :    exception.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
 138  E :    exception.ExceptionAddress = reinterpret_cast<PVOID>(context->Eip);
 139  E :    exception.NumberParameters = 2;
 140  E :    exception.ExceptionInformation[0] = reinterpret_cast<ULONG_PTR>(context);
 141  E :    exception.ExceptionInformation[1] = reinterpret_cast<ULONG_PTR>(error_info);
 142    :  
 143  E :    const EXCEPTION_POINTERS pointers = { &exception, context };
 144    :    trace::client::InvokeRpc(&LoggerClient_SaveMiniDump,
 145    :                             rpc_binding_.Get(),
 146    :                             ::GetCurrentThreadId(),
 147    :                             reinterpret_cast<unsigned long>(&pointers),
 148  E :                             0);
 149  E :  }
 150    :  
 151    :  }  // namespace asan
 152    :  }  // namespace agent

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