15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_DEBUG_PROFILER_H 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_DEBUG_PROFILER_H 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_export.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The Profiler functions allow usage of the underlying sampling based 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// profiler. If the application has not been built with the necessary 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// flags (-DENABLE_PROFILING and not -DNO_TCMALLOC) then these functions 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are noops. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace debug { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Start profiling with the supplied name. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// {pid} will be replaced by the process' pid and {count} will be replaced 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// by the count of the profile run (starts at 1 with each process). 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void StartProfiling(const std::string& name); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Stop profiling and write out data. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void StopProfiling(); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Force data to be written to file. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void FlushProfiling(); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if process is being profiled. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT bool BeingProfiled(); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Reset profiling after a fork, which disables timers. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void RestartProfilingAfterFork(); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true iff this executable is instrumented with the Syzygy profiler. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT bool IsBinaryInstrumented(); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There's a class of profilers that use "return address swizzling" to get a 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// hook on function exits. This class of profilers uses some form of entry hook, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// like e.g. binary instrumentation, or a compiler flag, that calls a hook each 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// time a function is invoked. The hook then switches the return address on the 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stack for the address of an exit hook function, and pushes the original 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// return address to a shadow stack of some type. When in due course the CPU 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// executes a return to the exit hook, the exit hook will do whatever work it 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// does on function exit, then arrange to return to the original return address. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class of profiler does not play well with programs that look at the 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// return address, as does e.g. V8. V8 uses the return address to certain 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// runtime functions to find the JIT code that called it, and from there finds 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the V8 data structures associated to the JS function involved. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A return address resolution function is used to fix this. It allows such 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// programs to resolve a location on stack where a return address originally 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// resided, to the shadow stack location where the profiler stashed it. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef uintptr_t (*ReturnAddressLocationResolver)( 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uintptr_t return_addr_location); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// This type declaration must match V8's FunctionEntryHook. 597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochtypedef void (*DynamicFunctionEntryHook)(uintptr_t function, 607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch uintptr_t return_addr_location); 617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// The functions below here are to support profiling V8-generated code. 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// V8 has provisions for generating a call to an entry hook for newly generated 647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// JIT code, and it can push symbol information on code generation and advise 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// when the garbage collector moves code. The functions declarations below here 667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// make glue between V8's facilities and a profiler. 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// This type declaration must match V8's FunctionEntryHook. 697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochtypedef void (*DynamicFunctionEntryHook)(uintptr_t function, 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch uintptr_t return_addr_location); 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochtypedef void (*AddDynamicSymbol)(const void* address, 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size_t length, 747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const char* name, 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size_t name_len); 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochtypedef void (*MoveDynamicSymbol)(const void* address, const void* new_address); 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// If this binary is instrumented and the instrumentation supplies a function 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// for each of those purposes, find and return the function in question. 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Otherwise returns NULL. 827dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochBASE_EXPORT ReturnAddressLocationResolver GetProfilerReturnAddrResolutionFunc(); 837dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochBASE_EXPORT DynamicFunctionEntryHook GetProfilerDynamicFunctionEntryHookFunc(); 847dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochBASE_EXPORT AddDynamicSymbol GetProfilerAddDynamicSymbolFunc(); 857dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochBASE_EXPORT MoveDynamicSymbol GetProfilerMoveDynamicSymbolFunc(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace debug 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // BASE_DEBUG_DEBUGGER_H 91