1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | // |
5 | // ProfilingHelper.h |
6 | // |
7 | |
8 | // |
9 | // Declaration of helper classes used for miscellaneous purposes within the |
10 | // profiling API |
11 | // |
12 | |
13 | // ====================================================================================== |
14 | |
15 | #ifndef __PROFILING_HELPER_H__ |
16 | #define __PROFILING_HELPER_H__ |
17 | |
18 | #ifndef PROFILING_SUPPORTED |
19 | #error PROFILING_SUPPORTED is not set. Do not include ProfilingHelper.h. |
20 | #endif |
21 | |
22 | #include <windows.h> |
23 | |
24 | #include "corprof.h" |
25 | #include "eeprofinterfaces.h" |
26 | |
27 | #define COM_METHOD HRESULT STDMETHODCALLTYPE |
28 | |
29 | #ifdef _DEBUG |
30 | // On DEBUG builds, setting the COMPlus_ProfAPIFault to a bitmask of the flags |
31 | // below forces the Profiling API to return failures at various points. |
32 | // Useful for event log testing. Also see code:ProfilingAPIUtility.ShouldInjectProfAPIFault |
33 | enum ProfAPIFaultFlags |
34 | { |
35 | // Forces the startup path to log an IDS_E_PROF_INTERNAL_INIT error |
36 | kProfAPIFault_StartupInternal = 0x00001, |
37 | }; |
38 | #endif // _DEBUG |
39 | |
40 | class SidBuffer; |
41 | |
42 | //--------------------------------------------------------------------------------------- |
43 | // Static-only class to coordinate initialization of the various profiling API |
44 | // structures, plus other utility stuff. |
45 | // |
46 | class ProfilingAPIUtility |
47 | { |
48 | public: |
49 | static HRESULT InitializeProfiling(); |
50 | static HRESULT LoadProfilerForAttach( |
51 | const CLSID * pClsid, |
52 | LPCWSTR wszProfilerDLL, |
53 | LPVOID pvClientData, |
54 | UINT cbClientData, |
55 | DWORD dwConcurrentGCWaitTimeoutInMs); |
56 | |
57 | static void TerminateProfiling(); |
58 | static void LogProfError(int iStringResourceID, ...); |
59 | static void LogProfInfo(int iStringResourceID, ...); |
60 | static void LogNoInterfaceError(REFIID iidRequested, LPCWSTR wszClsid); |
61 | INDEBUG(static BOOL ShouldInjectProfAPIFault(ProfAPIFaultFlags faultFlag);) |
62 | #ifndef FEATURE_PAL |
63 | static HRESULT GetCurrentProcessUserSid(PSID * ppsid); |
64 | #endif // !FEATURE_PAL |
65 | |
66 | // helper functions for profiler evacuation counter holder |
67 | static void IncEvacuationCounter(Thread * pThread); |
68 | static void DecEvacuationCounter(Thread * pThread); |
69 | |
70 | // See code:ProfilingAPIUtility::InitializeProfiling#LoadUnloadCallbackSynchronization |
71 | static CRITSEC_COOKIE GetStatusCrst(); |
72 | |
73 | private: |
74 | // --------------------------------------------------------------------------------------- |
75 | // Enum used in LoadProfiler() to differentiate whether we're loading the profiler |
76 | // for startup or for attach |
77 | enum LoadType |
78 | { |
79 | kStartupLoad, |
80 | kAttachLoad, |
81 | }; |
82 | |
83 | // Allocated lazily the first time it's needed, and then remains allocated until the |
84 | // process exits. |
85 | static SidBuffer * s_pSidBuffer; |
86 | |
87 | // See code:ProfilingAPIUtility::InitializeProfiling#LoadUnloadCallbackSynchronization |
88 | static CRITSEC_COOKIE s_csStatus; |
89 | |
90 | // Static-only class. Private constructor enforces you don't try to make an instance |
91 | ProfilingAPIUtility() {} |
92 | |
93 | static HRESULT PerformDeferredInit(); |
94 | static HRESULT LoadProfiler( |
95 | LoadType loadType, |
96 | const CLSID * pClsid, |
97 | LPCWSTR wszClsid, |
98 | LPCWSTR wszProfilerDLL, |
99 | LPVOID pvClientData, |
100 | UINT cbClientData, |
101 | DWORD dwConcurrentGCWaitTimeoutInMs = INFINITE); |
102 | static HRESULT ProfilerCLSIDFromString(__inout_z LPWSTR wszClsid, CLSID * pClsid); |
103 | static HRESULT AttemptLoadProfilerForStartup(); |
104 | |
105 | static void AppendSupplementaryInformation(int iStringResource, SString * pString); |
106 | |
107 | static void LogProfEventVA( |
108 | int iStringResourceID, |
109 | WORD wEventType, |
110 | va_list insertionArgs); |
111 | }; |
112 | |
113 | |
114 | //--------------------------------------------------------------------------------------- |
115 | // When we call into profiler code, we push one of these babies onto the stack to |
116 | // remember on the Thread how the profiler was called. If the profiler calls back into us, |
117 | // we use the flags that this set to authorize. |
118 | // |
119 | class SetCallbackStateFlagsHolder |
120 | { |
121 | public: |
122 | SetCallbackStateFlagsHolder(DWORD dwFlags); |
123 | ~SetCallbackStateFlagsHolder(); |
124 | |
125 | private: |
126 | Thread * m_pThread; |
127 | DWORD m_dwOriginalFullState; |
128 | }; |
129 | |
130 | #endif //__PROFILING_HELPER_H__ |
131 | |