Coverage for /Syzygy/trace/client/client_utils.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%770.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    :  // Declares utility functions used by the call trace client and its unit
  16    :  // tests.
  17    :  
  18    :  #ifndef SYZYGY_TRACE_CLIENT_CLIENT_UTILS_H_
  19    :  #define SYZYGY_TRACE_CLIENT_CLIENT_UTILS_H_
  20    :  
  21    :  #include "base/files/file_path.h"
  22    :  #include "syzygy/trace/protocol/call_trace_defs.h"
  23    :  #include "syzygy/trace/rpc/call_trace_rpc.h"
  24    :  
  25    :  namespace trace {
  26    :  namespace client {
  27    :  
  28    :  // Forward declaration.
  29    :  class RpcSession;
  30    :  
  31    :  // This structure captures everything that a thread needs to know about
  32    :  // its current call trace buffer, which corresponds to a call trace segment
  33    :  // on disk. It holds the buffer information given by the call trace service,
  34    :  // the memory locations this buffer refers to in the client process, and a
  35    :  // pointer to the segment header within the buffer so that the segment can
  36    :  // be consistently maintained.
  37    :  class TraceFileSegment {
  38    :   public:
  39    :    TraceFileSegment();
  40    :  
  41    :    // @returns true if there's enough space left in the given segment to write
  42    :    // num_bytes of raw data.
  43    :    bool CanAllocateRaw(size_t num_bytes) const;
  44    :  
  45    :    // @returns true if there's enough space left in the given segment to write
  46    :    // a prefixed record of length num_bytes.
  47    :    bool CanAllocate(size_t num_bytes) const;
  48    :  
  49    :    // Writes the segment header at the top of a segment, updating the bytes
  50    :    // consumed and initializing the segment header structures.
  51    :    void WriteSegmentHeader(SessionHandle session_handle);
  52    :  
  53    :    // Allocate a variable length trace record. Typically this is used when
  54    :    // the record has a fixed set of fields followed by some variable size
  55    :    // blob or string.  The size given must exceed the size of the records
  56    :    // fixed fields.
  57    :    //
  58    :    // @returns a pointer to the allocated record, such that you can populate
  59    :    //     its values.
  60    :    template<typename RecordType>
  61  E :    inline RecordType* AllocateTraceRecord(size_t size) {
  62  E :      DCHECK(size >= sizeof(RecordType));
  63    :      return reinterpret_cast<RecordType*>(
  64  E :          AllocateTraceRecordImpl(RecordType::kTypeId, size));
  65  E :    }
  66    :  
  67    :    // Allocate a fixed length trace record.
  68    :    //
  69    :    // @returns a pointer to the allocated record, such that you can populate
  70    :    //     its values.
  71    :    template<typename RecordType>
  72  E :    inline RecordType* AllocateTraceRecord() {
  73  E :      return AllocateTraceRecord<RecordType>(sizeof(RecordType));
  74  E :    }
  75    :  
  76    :   // TODO(siggi): Make this private.
  77    :   public:
  78    :    // Internal implementation of the trace record allocation function.
  79    :    void* AllocateTraceRecordImpl(int record_type,
  80    :                                  size_t record_size);
  81    :  
  82    :    // The structure used to communicate buffer information between the
  83    :    // client and call trace service.
  84    :    CallTraceBuffer buffer_info;
  85    :  
  86    :    // Points to the segment header within the call trace buffer. This
  87    :    // can  be used to update the segment_length after appending new
  88    :    // data to the buffer.
  89    :    TraceFileSegmentHeader* header;
  90    :  
  91    :    // The lower bound of the call trace buffer in the client process.
  92    :    uint8* base_ptr;
  93    :  
  94    :    // The next memory location at which the client should write call
  95    :    // trace data.
  96    :    uint8* write_ptr;
  97    :  
  98    :    // The upper bound of the call trace buffer in the client process.
  99    :    uint8* end_ptr;
 100    :  };
 101    :  
 102    :  // Helper function to transform a DllMain reason to a call trace event type.
 103    :  int ReasonToEventType(DWORD reason);
 104    :  
 105    :  // Helper function to get pointer to the prefix for any record
 106    :  // in a trace file segment.
 107    :  RecordPrefix* GetRecordPrefix(void *record);
 108    :  
 109    :  // Given an address in memory returns a pointer to the base address of the
 110    :  // loaded module in which it lies. Logs verbosely on failure.
 111    :  // @param address_in_module an address in the image.
 112    :  // @param module_base will receive a pointer to the base address of the image.
 113    :  // @returns true on success, false otherwise.
 114    :  bool GetModuleBaseAddress(void* address_in_module, void** module_base);
 115    :  
 116    :  // Determines the full path associated with a given module in memory. This is
 117    :  // replicating functionality from base::PathService, but it uses
 118    :  // GetModuleFileName which grabs the loader lock. This can cause us issues
 119    :  // thus we use GetMappedFileName instead.
 120    :  // @param module_base the base address of the module to be queried.
 121    :  // @param module_path will receive the path of the module, upon success.
 122    :  // @returns true on success, false otherwise.
 123    :  bool GetModulePath(void* module_base, base::FilePath* module_path);
 124    :  
 125    :  // Given the path to a module, determines the RPC instance ID to be used for
 126    :  // it. This works by looking at the SYZYGY_RPC_INSTANCE_ID environment variable.
 127    :  // This environment variable contains a semi-colon separated list of instance
 128    :  // IDs, where each entry may consist of a comma separated module path and
 129    :  // instance ID pair. The first semi-colon delimited entry that is a singleton
 130    :  // is used as the instance ID if no path matches are found. Exact path matches
 131    :  // have higher priority over basename-only path matches. If no match is found
 132    :  // and no default ID exists (or the environment variable is not specified), then
 133    :  // the returned instance ID is empty.
 134    :  //
 135    :  // For example, consider the following environment variable:
 136    :  //
 137    :  //   SYZYGY_RPC_INSTANCE_ID="1;foo.dll,2;C:\dll\foo.dll,3"
 138    :  //
 139    :  // If called with the path "C:\src\foo.dll" then the returned instance ID will
 140    :  // be "2". If called with the path "C:\dll\foo.dll" the returned instance ID
 141    :  // will be "3". If called with "C:\bar.dll" the returned instance ID will be
 142    :  // "1".
 143    :  //
 144    :  // @param module_path the path to the module for which we wish to find an
 145    :  //     instance ID. If it is not absolute it will be made so using the current
 146    :  //     working directory.
 147    :  // @returns the instance ID.
 148    :  std::string GetInstanceIdForModule(const base::FilePath& module_path);
 149    :  
 150    :  // Encapsulates calls to GetModuleBaseAddress, GetModulePath and
 151    :  // GetInstanceIdForModule.
 152    :  // @returns the instance ID for the module in which this function is found.
 153    :  std::string GetInstanceIdForThisModule();
 154    :  
 155    :  // Given the path to a module, determines whether or not an RPC connection
 156    :  // is mandatory for it. This works by looking at the
 157    :  // SYZYGY_RPC_SESSION_MANDATORY environment variable. This consists of a
 158    :  // semi-colon separated list of paths and values, similar to
 159    :  // SYZYGY_RPC_INSTANCE_ID as described in GetInstanceIdForModule. Rather than
 160    :  // an ID, the value is an integer where 0 = False and non-zero = True.
 161    :  // If the path matching process returns a non-zero value then failure to create
 162    :  // an RPC session will cause the instrumented process to terminate with an
 163    :  // error.
 164    :  //
 165    :  // @param module_path the path to the module for which we wish to determine if
 166    :  //     and RPC session is mandatory.
 167    :  // @returns true if the session is mandatory, false otherwise.
 168    :  bool IsRpcSessionMandatory(const base::FilePath& module_path);
 169    :  
 170    :  // Encapsulates calls to GetModuleBaseAddress, GetModulePath and
 171    :  // IsRpcSessionMandatory.
 172    :  // @returns true if an RPC session is mandatory for the module in which this
 173    :  //     function is found.
 174    :  bool IsRpcSessionMandatoryForThisModule();
 175    :  
 176    :  // Initializes an RPC session, automatically getting the instance ID and
 177    :  // determining if the session is mandatory. If the session is mandatory and it
 178    :  // is unable to be connected this will raise an exception and cause the process
 179    :  // to abort.
 180    :  // @param rpc_session the session to initialize.
 181    :  // @param segment will receive the first allocated segment upon successful
 182    :  //     initialization.
 183    :  // @returns true if everything went well, false if anything went wrong and the
 184    :  //     session is not mandatory.
 185    :  bool InitializeRpcSession(RpcSession* rpc_session, TraceFileSegment* segment);
 186    :  
 187    :  }  // namespace trace::client
 188    :  }  // namespace trace
 189    :  
 190    :  #endif  // SYZYGY_TRACE_CLIENT_CLIENT_UTILS_H_

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