Coverage for /Syzygy/kasko/service_bridge.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
0.0%00117.C++source

Line-by-line coverage:

   1    :  // Copyright 2014 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/kasko/service_bridge.h"
  16    :  
  17    :  #include <windows.h>  // NOLINT
  18    :  #include <rpc.h>
  19    :  #include <stdint.h>
  20    :  
  21    :  #include "base/logging.h"
  22    :  #include "base/process/process_handle.h"
  23    :  #include "syzygy/common/com_utils.h"
  24    :  #include "syzygy/common/rpc/helpers.h"
  25    :  #include "syzygy/kasko/minidump_request.h"
  26    :  #include "syzygy/kasko/service.h"
  27    :  
  28  m :  namespace kasko {
  29  m :  namespace {
  30  m :  ServiceBridge* g_service_bridge = NULL;
  31  m :  }  // namespace
  32  m :  }  // namespace kasko
  33    :  
  34    :  // RPC calls all come through this single free function. We use the singleton
  35    :  // g_service_bridge to forward the call to the running Service.
  36  m :  boolean KaskoService_SendDiagnosticReport(handle_t IDL_handle,
  37  m :                                            MinidumpRequest request) {
  38  m :    DCHECK(kasko::g_service_bridge);
  39    :  
  40  m :    base::ProcessId client_process_id =
  41  m :        ::common::rpc::GetClientProcessID(IDL_handle);
  42  m :    if (!client_process_id)
  43  m :      return false;
  44    :  
  45  m :    kasko::MinidumpRequest internal_request;
  46    :  
  47  m :    internal_request.client_exception_pointers = true;
  48  m :    internal_request.exception_info_address = request.exception_info_address;
  49    :  
  50  m :    switch (request.type) {
  51  m :      case SMALL_DUMP:
  52  m :        internal_request.type = kasko::MinidumpRequest::SMALL_DUMP_TYPE;
  53  m :        break;
  54  m :      case LARGER_DUMP:
  55  m :        internal_request.type = kasko::MinidumpRequest::LARGER_DUMP_TYPE;
  56  m :        break;
  57  m :      case FULL_DUMP:
  58  m :        internal_request.type = kasko::MinidumpRequest::FULL_DUMP_TYPE;
  59  m :        break;
  60  m :      default:
  61  m :        NOTREACHED();
  62  m :        break;
  63  m :    }
  64    :  
  65  m :    for (unsigned long i = 0; i < request.user_selected_memory_ranges_size; ++i) {
  66  m :      kasko::MinidumpRequest::MemoryRange internal_memory_range = {
  67  m :          static_cast<uint32_t>(
  68  m :              request.user_selected_memory_ranges[i].base_address),
  69  m :          static_cast<uint32_t>(request.user_selected_memory_ranges[i].length)};
  70  m :      internal_request.user_selected_memory_ranges.push_back(
  71  m :          internal_memory_range);
  72  m :    }
  73    :  
  74  m :    for (unsigned long i = 0; i < request.crash_keys_size; ++i) {
  75  m :      if (!request.crash_keys[i].name || !request.crash_keys[i].value)
  76  m :        continue;
  77    :  
  78  m :      internal_request.crash_keys.push_back(kasko::MinidumpRequest::CrashKey(
  79  m :          request.crash_keys[i].name, request.crash_keys[i].value));
  80  m :    }
  81    :  
  82  m :    for (unsigned long i = 0; i < request.custom_streams_size; ++i) {
  83  m :      if (!request.custom_streams[i].size)
  84  m :        continue;
  85  m :      kasko::MinidumpRequest::CustomStream internal_custom_stream = {
  86  m :          request.custom_streams[i].type,
  87  m :          reinterpret_cast<const void*>(request.custom_streams[i].data),
  88  m :          request.custom_streams[i].size};
  89  m :      internal_request.custom_streams.push_back(internal_custom_stream);
  90  m :    }
  91    :  
  92  m :    kasko::g_service_bridge->service_->SendDiagnosticReport(
  93  m :        client_process_id, request.thread_id, internal_request);
  94    :  
  95  m :    return true;
  96  m :  }
  97    :  
  98  m :  namespace kasko {
  99    :  
 100  m :  ServiceBridge::ServiceBridge(const base::string16& protocol,
 101  m :                               const base::string16& endpoint,
 102  m :                               std::unique_ptr<Service> service)
 103  m :      : protocol_(protocol),
 104  m :        endpoint_(endpoint),
 105  m :        service_(std::move(service)),
 106  m :        running_(false) {
 107    :    // It's a bad idea to have two instances stepping on each other's toes.
 108  m :    CHECK(!g_service_bridge);
 109    :  
 110  m :    DCHECK(!protocol_.empty());
 111  m :    DCHECK(!endpoint_.empty());
 112  m :    DCHECK(service_);
 113  m :    g_service_bridge = this;
 114  m :  }
 115    :  
 116  m :  ServiceBridge::~ServiceBridge() {
 117    :    // It's a bad idea to shut down without stopping the service. It's also a bad
 118    :    // idea to block unexpectedly in our destructor.
 119  m :    CHECK(!running_);
 120    :  
 121  m :    DCHECK_EQ(this, g_service_bridge);
 122  m :    g_service_bridge = NULL;
 123  m :  }
 124    :  
 125  m :  bool ServiceBridge::Run() {
 126  m :    if (running_) return true;
 127    :  
 128  m :    RPC_STATUS status = ::RpcServerUseProtseqEp(
 129  m :        common::rpc::AsRpcWstr(&protocol_[0]), RPC_C_LISTEN_MAX_CALLS_DEFAULT,
 130  m :        common::rpc::AsRpcWstr(&endpoint_[0]), NULL /* Security descriptor. */);
 131    :  
 132    :    // RPC_S_DUPLICATE_ENDPOINT seems to be possible if a previous instance has
 133    :    // already registered this protocol and endpoint. The end result is still that
 134    :    // the endpoint is properly configured for this protocol.
 135  m :    if (status != RPC_S_OK && status != RPC_S_DUPLICATE_ENDPOINT) {
 136  m :      LOG(ERROR) << "Failed to init RPC protocol: " << ::common::LogWe(status)
 137  m :                 << ".";
 138  m :    } else {
 139  m :      std::unique_ptr<common::rpc::ScopedRpcInterfaceRegistration>
 140  m :          interface_registration(new common::rpc::ScopedRpcInterfaceRegistration(
 141  m :              KaskoService_Kasko_v1_0_s_ifspec));
 142    :  
 143  m :      if (interface_registration->status() == RPC_S_OK) {
 144  m :        status = ::RpcServerListen(1,  // Minimum number of handler threads.
 145  m :                                   RPC_C_LISTEN_MAX_CALLS_DEFAULT, TRUE);
 146    :  
 147  m :        if (status != RPC_S_OK) {
 148  m :          LOG(ERROR) << "Failed to run RPC server: " << ::common::LogWe(status)
 149  m :                     << ".";
 150  m :        } else {
 151  m :          running_ = true;
 152  m :          interface_registration_ = std::move(interface_registration);
 153  m :        }
 154  m :      }
 155  m :    }
 156    :  
 157  m :    return running_;
 158  m :  }
 159    :  
 160  m :  void ServiceBridge::Stop() {
 161  m :    if (!running_) return;
 162    :  
 163    :    // This call prevents new requests from being accepted.
 164  m :    RPC_STATUS status = ::RpcMgmtStopServerListening(NULL);
 165  m :    if (status != RPC_S_OK) {
 166    :      // If this fails, we could end up servicing calls in a bad state.
 167  m :      LOG(FATAL) << "Failed to stop the RPC server: " << ::common::LogWe(status)
 168  m :                 << ".";
 169  m :    }
 170    :  
 171    :    // This call will block until all active requests are completed.
 172  m :    status = ::RpcMgmtWaitServerListen();
 173  m :    if (status != RPC_S_OK) {
 174    :      // If this fails, we could end up servicing calls in a bad state.
 175  m :      LOG(FATAL) << "Failed to wait for RPC server shutdown: "
 176  m :                 << ::common::LogWe(status) << ".";
 177  m :    }
 178    :  
 179  m :    interface_registration_.reset();
 180  m :    running_ = false;
 181  m :  }
 182    :  
 183  m :  }  // namespace kasko

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