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

Coverage information generated Wed Dec 11 11:34:16 2013.