// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // // ProfilingHelper.h // // // Declaration of helper classes used for miscellaneous purposes within the // profiling API // // ====================================================================================== #ifndef __PROFILING_HELPER_H__ #define __PROFILING_HELPER_H__ #ifndef PROFILING_SUPPORTED #error PROFILING_SUPPORTED is not set. Do not include ProfilingHelper.h. #endif #include #include "corprof.h" #include "eeprofinterfaces.h" #define COM_METHOD HRESULT STDMETHODCALLTYPE #ifdef _DEBUG // On DEBUG builds, setting the COMPlus_ProfAPIFault to a bitmask of the flags // below forces the Profiling API to return failures at various points. // Useful for event log testing. Also see code:ProfilingAPIUtility.ShouldInjectProfAPIFault enum ProfAPIFaultFlags { // Forces the startup path to log an IDS_E_PROF_INTERNAL_INIT error kProfAPIFault_StartupInternal = 0x00001, }; #endif // _DEBUG //--------------------------------------------------------------------------------------- // Static-only class to coordinate initialization of the various profiling API // structures, plus other utility stuff. // class ProfilingAPIUtility { private: enum ProfilerCompatibilityFlag { // Default: disable V2 profiler kDisableV2Profiler = 0x0, // Enable V2 profilers kEnableV2Profiler = 0x1, // Disable Profiling kPreventLoad = 0x2, }; public: static HRESULT InitializeProfiling(); static HRESULT LoadProfilerForAttach( const CLSID * pClsid, LPCWSTR wszProfilerDLL, LPVOID pvClientData, UINT cbClientData, DWORD dwConcurrentGCWaitTimeoutInMs); static BOOL IsProfilerEvacuated(ProfilerInfo *pDetachInfo); static void TerminateProfiling(ProfilerInfo *pProfilerInfo); static void LogProfError(int iStringResourceID, ...); static void LogProfInfo(int iStringResourceID, ...); static void LogNoInterfaceError(REFIID iidRequested, LPCWSTR wszClsid); INDEBUG(static BOOL ShouldInjectProfAPIFault(ProfAPIFaultFlags faultFlag);) // See code:ProfilingAPIUtility::InitializeProfiling#LoadUnloadCallbackSynchronization static CRITSEC_COOKIE GetStatusCrst(); private: // --------------------------------------------------------------------------------------- // Enum used in LoadProfiler() to differentiate whether we're loading the profiler // for startup or for attach enum LoadType { kStartupLoad, kAttachLoad, }; // See code:ProfilingAPIUtility::InitializeProfiling#LoadUnloadCallbackSynchronization static CRITSEC_COOKIE s_csStatus; // Static-only class. Private constructor enforces you don't try to make an instance ProfilingAPIUtility() {} static HRESULT PerformDeferredInit(); static HRESULT DoPreInitialization( EEToProfInterfaceImpl *pEEProf, const CLSID *pClsid, LPCWSTR wszClsid, LPCWSTR wszProfilerDLL, LoadType loadType, DWORD dwConcurrentGCWaitTimeoutInMs); static HRESULT LoadProfiler( LoadType loadType, const CLSID * pClsid, LPCWSTR wszClsid, LPCWSTR wszProfilerDLL, LPVOID pvClientData, UINT cbClientData, DWORD dwConcurrentGCWaitTimeoutInMs = INFINITE); static HRESULT ProfilerCLSIDFromString(__inout_z LPWSTR wszClsid, CLSID * pClsid); static HRESULT AttemptLoadProfilerForStartup(); static HRESULT AttemptLoadDelayedStartupProfilers(); static HRESULT AttemptLoadProfilerList(); static void AppendSupplementaryInformation(int iStringResource, SString * pString); static void LogProfEventVA( int iStringResourceID, WORD wEventType, va_list insertionArgs); }; //--------------------------------------------------------------------------------------- // When we call into profiler code, we push one of these babies onto the stack to // remember on the Thread how the profiler was called. If the profiler calls back into us, // we use the flags that this set to authorize. // class SetCallbackStateFlagsHolder { public: SetCallbackStateFlagsHolder(DWORD dwFlags); ~SetCallbackStateFlagsHolder(); private: Thread * m_pThread; DWORD m_dwOriginalFullState; }; FORCEINLINE void DeregisterProfilerIfNotificationOnly(ProfilerInfo *pProfilerInfo) { g_profControlBlock.DeRegisterProfilerInfo(pProfilerInfo); } typedef Wrapper ProfilerInfoHolder; #endif //__PROFILING_HELPER_H__