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

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
83.6%51610.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    :  void LogToFile(FILE* dest,
  56    :                 const std::string& message,
  57  E :                 const base::debug::StackTrace* trace) {
  58  E :    const char* format_str =  "%s%s";
  59  E :    if (!message.empty() && message.back() != '\n')
  60  i :      format_str = "%s\n%s";
  61    :    ::fprintf(dest,
  62    :              format_str,
  63    :              message.c_str(),
  64  E :              trace == NULL ? "" : trace->ToString().c_str());
  65  E :  }
  66    :  
  67    :  }  // namespace
  68    :  
  69  E :  AsanLogger::AsanLogger() {
  70  E :  }
  71    :  
  72  E :  void AsanLogger::Init() {
  73  E :    base::RouteStdioToConsole();
  74    :    bool success = rpc_binding_.Open(
  75    :        kLoggerRpcProtocol,
  76  E :        GetInstanceString(kLoggerRpcEndpointRoot, instance_id_));
  77    :  
  78    :    // TODO(rogerm): Add a notion of a session to the logger interface. Opening
  79    :    //     a session (either here, or on first use) allows for better management
  80    :    //     of symbol context across trace log messages for a given process.
  81  E :    if (success) {
  82  E :      const CommandLine* command_line = CommandLine::ForCurrentProcess();
  83    :      std::string message = base::StringPrintf(
  84    :          "PID=%d; cmd-line='%ls'\n",
  85    :          ::GetCurrentProcessId(),
  86  E :          command_line->GetCommandLineString().c_str());
  87    :      success = trace::client::InvokeRpc(
  88    :          &LoggerClient_Write,
  89    :          rpc_binding_.Get(),
  90  E :          reinterpret_cast<const unsigned char*>(message.c_str())).succeeded();
  91  E :      if (!success)
  92  E :        rpc_binding_.Close();
  93  E :    }
  94  E :  }
  95    :  
  96  E :  void AsanLogger::Write(const std::string& message) {
  97    :    // If we're bound to a logging endpoint, log the message there.
  98  E :    if (rpc_binding_.Get() != NULL) {
  99    :      trace::client::InvokeRpc(
 100    :          &LoggerClient_Write,
 101    :          rpc_binding_.Get(),
 102  E :          reinterpret_cast<const unsigned char*>(message.c_str()));
 103  E :    } else {
 104  E :      LogToFile(stderr, message, NULL);
 105    :    }
 106  E :  }
 107    :  
 108    :  void AsanLogger::WriteWithContext(const std::string& message,
 109  E :                                    const CONTEXT& context) {
 110    :    // If we're bound to a logging endpoint, log the message there.
 111  E :    if (rpc_binding_.Get() != NULL) {
 112  E :      ExecutionContext exec_context = {};
 113  E :      InitExecutionContext(context, &exec_context);
 114    :      trace::client::InvokeRpc(
 115    :          &LoggerClient_WriteWithContext,
 116    :          rpc_binding_.Get(),
 117    :          reinterpret_cast<const unsigned char*>(message.c_str()),
 118  E :          &exec_context);
 119  E :    } else {
 120    :      // Otherwise, log to stderr.
 121  i :      EXCEPTION_RECORD dummy_exc_record = {};
 122  i :      CONTEXT context_copy = context;
 123  i :      EXCEPTION_POINTERS pointers = { &dummy_exc_record, &context_copy };
 124  i :      base::debug::StackTrace trace(&pointers);
 125  i :      LogToFile(stderr, message, &trace);
 126  i :    }
 127  E :  }
 128    :  
 129    :  void AsanLogger::WriteWithStackTrace(const std::string& message,
 130    :                                       const void * const * trace_data,
 131  E :                                       size_t trace_length) {
 132    :    // If we're bound to a logging endpoint, log the message there.
 133  E :    if (rpc_binding_.Get() != NULL) {
 134    :      trace::client::InvokeRpc(
 135    :          &LoggerClient_WriteWithTrace,
 136    :          rpc_binding_.Get(),
 137    :          reinterpret_cast<const unsigned char*>(message.c_str()),
 138    :          reinterpret_cast<const DWORD*>(trace_data),
 139  E :          trace_length);
 140  E :    } else {
 141    :      // Otherwise, log to stderr.
 142  i :      base::debug::StackTrace trace(trace_data, trace_length);
 143  i :      LogToFile(stderr, message, &trace);
 144  i :    }
 145  E :  }
 146    :  
 147    :  }  // namespace asan
 148    :  }  // namespace agent

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