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

Coverage information generated Thu Mar 26 16:15:41 2015.