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 DllMainEntryHook(EntryFrame* entry_frame,
  67    :                                        FuncAddr function,
  68    :                                        uint64 cycles);
  69    :  
  70    :    static void WINAPI FunctionEntryHook(EntryFrame* entry_frame,
  71    :                                         FuncAddr function,
  72    :                                         uint64 cycles);
  73    :  
  74    :    static void WINAPI OnV8FunctionEntry(FuncAddr function,
  75    :                                         RetAddr* return_addr_location,
  76    :                                         uint64 cycles);
  77    :  
  78    :    // Adds a symbol to the dynamic symbol store.
  79    :    // @param address the start address of the new symbol.
  80    :    // @param length the length of the new symbol.
  81    :    // @param name the name of the new symbol, this string is not necessarily
  82    :    //     zero terminated.
  83    :    // @paran name_len the length of @p name.
  84    :    void AddSymbol(const void* address, size_t length,
  85    :                   const char* name, size_t name_len);
  86    :  
  87    :    // Moves a symbol in the dynamic symbol store.
  88    :    // @param old_address the previous start address of the moved symbol.
  89    :    // @param new_address the new start address of the moved symbol.
  90    :    void MoveSymbol(const void* old_address, const void* new_address);
  91    :  
  92    :    // Resolves a return address location to a thunk's stashed original
  93    :    // location if a thunk is involved.
  94    :    // @param pc_location an address on stack where a return address is stored.
  95    :    // @returns the address where the profiler stashed the original return address
  96    :    //     if *(@p pc_location) refers to a thunk, otherwise @p pc_location.
  97    :    // @note this function must be able to resolve through thunks that belong
  98    :    //     to other threads, as e.g. V8 will traverse all stacks that are using
  99    :    //     V8 during garbage collection.
 100    :    RetAddr* ResolveReturnAddressLocation(RetAddr* pc_location);
 101    :  
 102    :    // Called when a thread is terminating.
 103    :    void OnThreadDetach();
 104    :  
 105    :    // Retrieves the profiler singleton instance.
 106  E :    static Profiler& instance() { return instance_; }
 107    :  
 108    :   private:
 109    :    Profiler();
 110    :    ~Profiler();
 111    :  
 112    :    // Called form DllMainEntryHook.
 113    :    void OnModuleEntry(EntryFrame* entry_frame,
 114    :                       FuncAddr function,
 115    :                       uint64 cycles);
 116    :  
 117    :    // Callbacks from ThreadState.
 118    :    void OnPageAdded(const void* page);
 119    :    void OnPageRemoved(const void* page);
 120    :  
 121    :    // Called on a first chance exception declaring thread name.
 122    :    void OnThreadName(const base::StringPiece& thread_name);
 123    :  
 124    :    // Our vectored exception handler that takes care
 125    :    // of capturing thread name debug exceptions.
 126    :    static LONG CALLBACK ExceptionHandler(EXCEPTION_POINTERS* ex_info);
 127    :  
 128    :    class ThreadState;
 129    :  
 130    :    // Sink for DLL load/unload event notifications.
 131    :    void OnDllEvent(agent::common::DllNotificationWatcher::EventType type,
 132    :                    HMODULE module,
 133    :                    size_t module_size,
 134    :                    const base::StringPiece16& dll_path,
 135    :                    const base::StringPiece16& dll_base_name);
 136    :  
 137    :    ThreadState* CreateFirstThreadStateAndSession();
 138    :    ThreadState* GetOrAllocateThreadState();
 139    :    ThreadState* GetOrAllocateThreadStateImpl();
 140    :    ThreadState* GetThreadState() const;
 141    :    void FreeThreadState();
 142    :  
 143    :    // The RPC session we're logging to/through.
 144    :    trace::client::RpcSession session_;
 145    :  
 146    :    // Protects pages_ and logged_modules_.
 147    :    base::Lock lock_;
 148    :  
 149    :    // The dynamic symbol map.
 150    :    SymbolMap symbol_map_;
 151    :  
 152    :    // Contains the thunk pages in lexical order.
 153    :    typedef std::vector<const void*> PageVector;
 154    :    PageVector pages_;  // Under lock_.
 155    :  
 156    :    // Contains the set of modules we've seen and logged.
 157    :    typedef base::hash_set<HMODULE> ModuleSet;
 158    :    ModuleSet logged_modules_;  // Under lock_.
 159    :  
 160    :    // A helper to manage the life-cycle of the ThreadState instances allocated
 161    :    // by this agent.
 162    :    agent::common::ThreadStateManager thread_state_manager_;
 163    :  
 164    :    // Stores our vectored exception handler registration handle.
 165    :    void* handler_registration_;
 166    :  
 167    :    // To keep track of modules added after initialization.
 168    :    agent::common::DllNotificationWatcher dll_watcher_;
 169    :  
 170    :    // This points to our per-thread state.
 171    :    mutable base::ThreadLocalPointer<ThreadState> tls_;
 172    :  
 173    :    // The instance all profiling goes through.
 174    :    static Profiler instance_;
 175    :  };
 176    :  
 177    :  }  // namespace profiler
 178    :  }  // namespace agent
 179    :  
 180    :  #endif  // SYZYGY_AGENT_PROFILER_PROFILER_H_

Coverage information generated Thu Jan 14 17:40:38 2016.