Coverage for /Syzygy/trace/agent_logger/agent_logger_rpc_impl.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
76.1%831090.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    :  // This file implements the RPC stubs which bind the LoggerService RPC
  16    :  // handlers to a Logger instance.
  17    :  
  18    :  #include "syzygy/trace/agent_logger/agent_logger_rpc_impl.h"
  19    :  
  20    :  #include <windows.h>
  21    :  #include <winnt.h>
  22    :  
  23    :  #include "base/process/process.h"
  24    :  #include "base/win/scoped_handle.h"
  25    :  #include "syzygy/common/com_utils.h"
  26    :  #include "syzygy/common/rpc/helpers.h"
  27    :  #include "syzygy/trace/agent_logger/agent_logger.h"
  28    :  #include "syzygy/trace/rpc/logger_rpc.h"
  29    :  
  30    :  namespace {
  31    :  
  32    :  using base::ProcessId;
  33    :  using base::win::ScopedHandle;
  34    :  using trace::agent_logger::RpcLoggerInstanceManager;
  35    :  using trace::agent_logger::AgentLogger;
  36    :  
  37    :  bool GetClientInfo(handle_t binding,
  38    :                     base::ProcessId* pid,
  39  E :                     base::win::ScopedHandle* handle) {
  40  E :    DCHECK(pid);
  41  E :    DCHECK(handle);
  42    :  
  43  E :    base::ProcessId the_pid = ::common::rpc::GetClientProcessID(binding);
  44  E :    if (!the_pid)
  45  i :      return false;
  46    :  
  47    :    // Open and return the handle to the process.
  48    :    static const DWORD kFlags =
  49    :        PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ;
  50  E :    handle->Set(::OpenProcess(kFlags, FALSE, the_pid));
  51  E :    if (!handle->IsValid()) {
  52  i :      DWORD error = ::GetLastError();
  53  i :      LOG(ERROR) << "Failed to open PID=" << the_pid << ": "
  54    :                 << ::common::LogWe(error) << ".";
  55  i :      return false;
  56    :    }
  57    :  
  58    :    // And we're done.
  59  E :    *pid = the_pid;
  60  E :    return true;
  61  E :  }
  62    :  
  63  E :  void InitContext(const ExecutionContext* ext_ctx, CONTEXT* ctx) {
  64  E :    DCHECK(ext_ctx != NULL);
  65  E :    DCHECK(ctx != NULL);
  66    :  
  67  E :    ::memset(ctx, 0, sizeof(*ctx));
  68  E :    ctx->ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
  69    :  
  70    :    // Populate the integer registers.
  71  E :    ctx->Edi = ext_ctx->edi;
  72  E :    ctx->Esi = ext_ctx->esi;
  73  E :    ctx->Ebx = ext_ctx->ebx;
  74  E :    ctx->Edx = ext_ctx->edx;
  75  E :    ctx->Ecx = ext_ctx->ecx;
  76  E :    ctx->Eax = ext_ctx->eax;
  77    :  
  78    :    // Populate the control registers.
  79  E :    ctx->Ebp = ext_ctx->ebp;
  80  E :    ctx->Eip = ext_ctx->eip;
  81  E :    ctx->SegCs = ext_ctx->seg_cs;
  82  E :    ctx->EFlags = ext_ctx->eflags;
  83  E :    ctx->Esp = ext_ctx->esp;
  84  E :    ctx->SegSs = ext_ctx->seg_ss;
  85  E :  }
  86    :  
  87    :  }  // namespace
  88    :  
  89    :  // The instance to which the RPC callbacks are bound.
  90    :  AgentLogger* RpcLoggerInstanceManager::instance_ = NULL;
  91    :  
  92    :  // RPC entrypoint for AgentLogger::Write().
  93    :  boolean LoggerService_Write(
  94    :      /* [in] */ handle_t binding,
  95  E :      /* [string][in] */ const unsigned char *text) {
  96  E :    if (binding == NULL || text == NULL) {
  97  i :      LOG(ERROR) << "Invalid input parameter(s).";
  98  i :      return false;
  99    :    }
 100    :  
 101    :    // Get the logger instance.
 102  E :    AgentLogger* instance = RpcLoggerInstanceManager::GetInstance();
 103    :  
 104    :    // Write the log message.
 105  E :    std::string message(reinterpret_cast<const char*>(text));
 106  E :    if (!instance->Write(message))
 107  i :      return false;
 108    :  
 109    :    // And we're done.
 110  E :    return true;
 111  E :  }
 112    :  
 113    :  boolean LoggerService_WriteWithContext(
 114    :      /* [in] */ handle_t binding,
 115    :      /* [in, string] */ const unsigned char* text,
 116  E :      /* [in */ const ExecutionContext* exc_context ) {
 117  E :    if (binding == NULL || text == NULL || exc_context == NULL) {
 118  i :      LOG(ERROR) << "Invalid input parameter(s).";
 119  i :      return false;
 120    :    }
 121    :  
 122    :    // Get the caller's process info.
 123  E :    ProcessId pid = 0;
 124  E :    ScopedHandle handle;
 125  E :    if (!GetClientInfo(binding, &pid, &handle))
 126  i :      return false;
 127    :  
 128    :    // Get the logger instance.
 129  E :    AgentLogger* instance = RpcLoggerInstanceManager::GetInstance();
 130    :  
 131    :    // Capture the stack trace for the caller's context.
 132  E :    CONTEXT context = {};
 133  E :    InitContext(exc_context, &context);
 134  E :    std::vector<DWORD> trace_data;
 135  E :    if (!instance->CaptureRemoteTrace(handle.Get(), &context, &trace_data)) {
 136  i :      return false;
 137    :    }
 138    :  
 139    :    // Create the log message.
 140  E :    std::string message(reinterpret_cast<const char*>(text));
 141  E :    if (!instance->AppendTrace(handle.Get(), trace_data.data(), trace_data.size(),
 142    :                               &message)) {
 143  i :      return false;
 144    :    }
 145    :  
 146    :    // Write the log message.
 147  E :    if (!instance->Write(message))
 148  i :      return false;
 149    :  
 150    :    // And we're done.
 151  E :    return true;
 152  E :  }
 153    :  
 154    :  boolean LoggerService_WriteWithTrace(
 155    :      /* [in] */ handle_t binding,
 156    :      /* [in, string] */ const unsigned char* text,
 157    :      /* [in, size_is(trace_length)] */ const unsigned long* trace_data,
 158  E :      /* [in] */ LONG trace_length) {
 159  E :    if (binding == NULL || text == NULL || trace_data == NULL) {
 160  i :      LOG(ERROR) << "Invalid input parameter(s).";
 161  i :      return false;
 162    :    }
 163    :  
 164    :    // Get the caller's process info.
 165  E :    ProcessId pid = 0;
 166  E :    ScopedHandle handle;
 167  E :    if (!GetClientInfo(binding, &pid, &handle))
 168  i :      return false;
 169    :  
 170    :    // Get the logger instance.
 171  E :    AgentLogger* instance = RpcLoggerInstanceManager::GetInstance();
 172    :  
 173    :    // Create the log message.
 174  E :    std::string message(reinterpret_cast<const char*>(text));
 175  E :    if (!instance->AppendTrace(handle.Get(), trace_data, trace_length, &message))
 176  i :      return false;
 177    :  
 178    :    // Write the log message.
 179  E :    if (!instance->Write(message))
 180  i :      return false;
 181    :  
 182    :    // And we're done.
 183  E :    return true;
 184  E :  }
 185    :  
 186    :  // RPC entrypoint for AgentLogger::SaveMinidumpWithProtobufAndMemoryRanges().
 187    :  boolean LoggerService_SaveMinidumpWithProtobufAndMemoryRanges(
 188    :      /* [in] */ handle_t binding,
 189    :      /* [in] */ unsigned long thread_id,
 190    :      /* [in] */ unsigned long exception,
 191    :      /* [size_is][in] */ const byte protobuf[],
 192    :      /* [in] */ unsigned long protobuf_length,
 193    :      /* [size_is][in] */ const unsigned long memory_ranges_base_addresses[],
 194    :      /* [size_is][in] */ const unsigned long memory_ranges_lengths[],
 195  E :      /* [in] */ unsigned long memory_ranges_count) {
 196  E :    if (binding == NULL) {
 197  i :      LOG(ERROR) << "Invalid input parameter(s).";
 198  i :      return false;
 199    :    }
 200    :  
 201    :    // Get the caller's process info.
 202  E :    ProcessId pid = 0;
 203  E :    ScopedHandle handle;
 204  E :    if (!GetClientInfo(binding, &pid, &handle))
 205  i :      return false;
 206    :  
 207  E :    std::string protobuf_data(reinterpret_cast<const char*>(protobuf));
 208  E :    AgentLogger* instance = RpcLoggerInstanceManager::GetInstance();
 209  E :    if (!instance->SaveMinidumpWithProtobufAndMemoryRanges(
 210    :            handle.Get(), pid, thread_id, exception, protobuf, protobuf_length,
 211    :            reinterpret_cast<const void* const*>(memory_ranges_base_addresses),
 212    :            reinterpret_cast<const size_t*>(memory_ranges_lengths),
 213    :            memory_ranges_count)) {
 214  i :      return false;
 215    :    }
 216    :  
 217  E :    return true;
 218  E :  }
 219    :  
 220    :  // RPC endpoint.
 221  E :  unsigned long LoggerService_GetProcessId(/* [in] */ handle_t binding) {
 222  E :    return ::GetCurrentProcessId();
 223  E :  }
 224    :  
 225    :  // RPC entrypoint for AgentLogger::Stop().
 226  E :  boolean LoggerService_Stop(/* [in] */ handle_t binding) {
 227  E :    if (binding == NULL) {
 228  i :      LOG(ERROR) << "Invalid input parameter(s).";
 229  i :      return false;
 230    :    }
 231    :  
 232    :    // Get the caller's process info.
 233  E :    ProcessId pid = 0;
 234  E :    ScopedHandle handle;
 235  E :    if (!GetClientInfo(binding, &pid, &handle))
 236  i :      return false;
 237    :  
 238  E :    AgentLogger* instance = RpcLoggerInstanceManager::GetInstance();
 239  E :    if (!instance->Stop())
 240  i :      return false;
 241    :  
 242  E :    return true;
 243  E :  }

Coverage information generated Fri Jul 29 11:00:21 2016.