Coverage for /Syzygy/agent/profiler/profiler.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%110.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    :  // A hierarchical profiler, indended for use with the Syzygy function level
  16    :  // instrumenter. The Syzygy instrumented provides a function entry hook, and
  17    :  // this implementation uses a shadow stack with return address swizzling to
  18    :  // get an exit hook.
  19    :  // The profiler uses RDTSC as wall clock, which makes it unsuitable for
  20    :  // profiling on systems with CPUs prior to AMD Barcelona/Phenom, or older
  21    :  // Intel processors, see e.g. http://en.wikipedia.org/wiki/Time_Stamp_Counter
  22    :  // for the low down details.
  23    :  
  24    :  #ifndef SYZYGY_AGENT_PROFILER_PROFILER_H_
  25    :  #define SYZYGY_AGENT_PROFILER_PROFILER_H_
  26    :  
  27    :  #include <windows.h>
  28    :  #include <winnt.h>
  29    :  #include <vector>
  30    :  
  31    :  #include "base/synchronization/lock.h"
  32    :  #include "base/threading/thread_local.h"
  33    :  #include "syzygy/agent/common/dll_notifications.h"
  34    :  #include "syzygy/agent/common/entry_frame.h"
  35    :  #include "syzygy/agent/common/thread_state.h"
  36    :  #include "syzygy/agent/profiler/symbol_map.h"
  37    :  #include "syzygy/trace/client/rpc_session.h"
  38    :  
  39    :  // Assembly instrumentation stubs to handle function entry and exit.
  40    :  extern "C" void _cdecl _indirect_penter();
  41    :  extern "C" void _cdecl _indirect_penter_dllmain();
  42    :  extern "C" void _cdecl _indirect_penter_inside_function();
  43    :  extern void pexit();
  44    :  
  45    :  // Add a symbol to the dynamic symbol store.
  46    :  // @param address the start address of the new symbol.
  47    :  // @param length the length of the new symbol.
  48    :  // @param name the name of the new symbol, this string is not necessarily
  49    :  //     zero terminated.
  50    :  // @paran name_len the length of @p name.
  51    :  extern "C" void WINAPI AddSymbol(const void* address, size_t length,
  52    :                                   const char* name, size_t name_len);
  53    :  
  54    :  // Moves a symbol in the dynamic symbol store.
  55    :  // @param old_address the previous start address of the moved symbol.
  56    :  // @param new_address the new start address of the moved symbol.
  57    :  extern "C" void WINAPI MoveSymbol(const void* old_address,
  58    :                                    const void* new_address);
  59    :  
  60    :  namespace agent {
  61    :  namespace profiler {
  62    :  
  63    :  // There's a single instance of this class.
  64    :  class Profiler {
  65    :   public:
  66    :    static void WINAPI
  67    :    DllMainEntryHook(EntryFrame* entry_frame, FuncAddr function, uint64_t cycles);
  68    :  
  69    :    static void WINAPI FunctionEntryHook(EntryFrame* entry_frame,
  70    :                                         FuncAddr function,
  71    :                                         uint64_t cycles);
  72    :  
  73    :    static void WINAPI OnV8FunctionEntry(FuncAddr function,
  74    :                                         RetAddr* return_addr_location,
  75    :                                         uint64_t cycles);
  76    :  
  77    :    // Adds a symbol to the dynamic symbol store.
  78    :    // @param address the start address of the new symbol.
  79    :    // @param length the length of the new symbol.
  80    :    // @param name the name of the new symbol, this string is not necessarily
  81    :    //     zero terminated.
  82    :    // @paran name_len the length of @p name.
  83    :    void AddSymbol(const void* address, size_t length,
  84    :                   const char* name, size_t name_len);
  85    :  
  86    :    // Moves a symbol in the dynamic symbol store.
  87    :    // @param old_address the previous start address of the moved symbol.
  88    :    // @param new_address the new start address of the moved symbol.
  89    :    void MoveSymbol(const void* old_address, const void* new_address);
  90    :  
  91    :    // Resolves a return address location to a thunk's stashed original
  92    :    // location if a thunk is involved.
  93    :    // @param pc_location an address on stack where a return address is stored.
  94    :    // @returns the address where the profiler stashed the original return address
  95    :    //     if *(@p pc_location) refers to a thunk, otherwise @p pc_location.
  96    :    // @note this function must be able to resolve through thunks that belong
  97    :    //     to other threads, as e.g. V8 will traverse all stacks that are using
  98    :    //     V8 during garbage collection.
  99    :    RetAddr* ResolveReturnAddressLocation(RetAddr* pc_location);
 100    :  
 101    :    // Called when a thread is terminating.
 102    :    void OnThreadDetach();
 103    :  
 104    :    // Retrieves the profiler singleton instance.
 105  E :    static Profiler& instance() { return instance_; }
 106    :  
 107    :   private:
 108    :    Profiler();
 109    :    ~Profiler();
 110    :  
 111    :    // Called form DllMainEntryHook.
 112    :    void OnModuleEntry(EntryFrame* entry_frame,
 113    :                       FuncAddr function,
 114    :                       uint64_t cycles);
 115    :  
 116    :    // Callbacks from ThreadState.
 117    :    void OnPageAdded(const void* page);
 118    :    void OnPageRemoved(const void* page);
 119    :  
 120    :    // Called on a first chance exception declaring thread name.
 121    :    void OnThreadName(const base::StringPiece& thread_name);
 122    :  
 123    :    // Our vectored exception handler that takes care
 124    :    // of capturing thread name debug exceptions.
 125    :    static LONG CALLBACK ExceptionHandler(EXCEPTION_POINTERS* ex_info);
 126    :  
 127    :    class ThreadState;
 128    :  
 129    :    // Sink for DLL load/unload event notifications.
 130    :    void OnDllEvent(agent::common::DllNotificationWatcher::EventType type,
 131    :                    HMODULE module,
 132    :                    size_t module_size,
 133    :                    const base::StringPiece16& dll_path,
 134    :                    const base::StringPiece16& dll_base_name);
 135    :  
 136    :    ThreadState* CreateFirstThreadStateAndSession();
 137    :    ThreadState* GetOrAllocateThreadState();
 138    :    ThreadState* GetOrAllocateThreadStateImpl();
 139    :    ThreadState* GetThreadState() const;
 140    :    void FreeThreadState();
 141    :  
 142    :    // The RPC session we're logging to/through.
 143    :    trace::client::RpcSession session_;
 144    :  
 145    :    // Protects pages_ and logged_modules_.
 146    :    base::Lock lock_;
 147    :  
 148    :    // The dynamic symbol map.
 149    :    SymbolMap symbol_map_;
 150    :  
 151    :    // Contains the thunk pages in lexical order.
 152    :    typedef std::vector<const void*> PageVector;
 153    :    PageVector pages_;  // Under lock_.
 154    :  
 155    :    // Contains the set of modules we've seen and logged.
 156    :    typedef base::hash_set<HMODULE> ModuleSet;
 157    :    ModuleSet logged_modules_;  // Under lock_.
 158    :  
 159    :    // A helper to manage the life-cycle of the ThreadState instances allocated
 160    :    // by this agent.
 161    :    agent::common::ThreadStateManager thread_state_manager_;
 162    :  
 163    :    // Stores our vectored exception handler registration handle.
 164    :    void* handler_registration_;
 165    :  
 166    :    // To keep track of modules added after initialization.
 167    :    agent::common::DllNotificationWatcher dll_watcher_;
 168    :  
 169    :    // This points to our per-thread state.
 170    :    mutable base::ThreadLocalPointer<ThreadState> tls_;
 171    :  
 172    :    // The instance all profiling goes through.
 173    :    static Profiler instance_;
 174    :  };
 175    :  
 176    :  }  // namespace profiler
 177    :  }  // namespace agent
 178    :  
 179    :  #endif  // SYZYGY_AGENT_PROFILER_PROFILER_H_

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