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.
5 #ifndef __EVENTPIPE_H__
6 #define __EVENTPIPE_H__
8 #ifdef FEATURE_PERFTRACING
13 class EventPipeConfiguration;
16 class EventPipeJsonFile;
17 class EventPipeBuffer;
18 class EventPipeBufferManager;
19 class EventPipeProvider;
21 class SampleProfilerEventInstance;
22 struct EventPipeProviderConfiguration;
24 // Define the event pipe callback to match the ETW callback signature.
25 typedef void (*EventPipeCallback)(
29 ULONGLONG MatchAnyKeywords,
30 ULONGLONG MatchAllKeywords,
32 void *CallbackContext);
39 unsigned int Reserved;
42 class EventPipeEventPayload
46 EventData **m_pEventData;
47 unsigned int m_eventDataCount;
51 // If the data is stored only as an array of EventData objects, create a flat buffer and copy into it
55 // Build this payload with a flat buffer inside
56 EventPipeEventPayload(BYTE *pData, unsigned int length);
58 // Build this payload to contain an array of EventData objects
59 EventPipeEventPayload(EventData **pEventData, unsigned int eventDataCount);
61 // If a buffer was allocated internally, delete it
62 ~EventPipeEventPayload();
64 // Copy the data (whether flat or array of objects) into a flat buffer at pDst
65 // Assumes that pDst points to an appropriatly sized buffer
66 void CopyData(BYTE *pDst);
68 // Get the flat formatted data in this payload
69 // This method will allocate a buffer if it does not already contain flattened data
70 // This method will return NULL on OOM if a buffer needed to be allocated
73 // Return true is the data is stored in a flat buffer
74 bool IsFlattened() const
76 LIMITED_METHOD_CONTRACT;
78 return m_pData != NULL;
81 // The the size of buffer needed to contain the stored data
82 unsigned int GetSize() const
84 LIMITED_METHOD_CONTRACT;
89 EventData** GetEventDataArray() const
91 LIMITED_METHOD_CONTRACT;
101 const static unsigned int MAX_STACK_DEPTH = 100;
103 // Array of IP values from a stack crawl.
104 // Top of stack is at index 0.
105 UINT_PTR m_stackFrames[MAX_STACK_DEPTH];
108 // Parallel array of MethodDesc pointers.
109 // Used for debug-only stack printing.
110 MethodDesc* m_methods[MAX_STACK_DEPTH];
113 // The next available slot in StackFrames.
114 unsigned int m_nextAvailableFrame;
120 LIMITED_METHOD_CONTRACT;
125 void CopyTo(StackContents *pDest)
127 LIMITED_METHOD_CONTRACT;
128 _ASSERTE(pDest != NULL);
130 memcpy_s(pDest->m_stackFrames, MAX_STACK_DEPTH * sizeof(UINT_PTR), m_stackFrames, sizeof(UINT_PTR) * m_nextAvailableFrame);
132 memcpy_s(pDest->m_methods, MAX_STACK_DEPTH * sizeof(MethodDesc*), m_methods, sizeof(MethodDesc*) * m_nextAvailableFrame);
134 pDest->m_nextAvailableFrame = m_nextAvailableFrame;
139 LIMITED_METHOD_CONTRACT;
141 m_nextAvailableFrame = 0;
146 LIMITED_METHOD_CONTRACT;
148 return (m_nextAvailableFrame == 0);
151 unsigned int GetLength()
153 LIMITED_METHOD_CONTRACT;
155 return m_nextAvailableFrame;
158 UINT_PTR GetIP(unsigned int frameIndex)
160 LIMITED_METHOD_CONTRACT;
161 _ASSERTE(frameIndex < MAX_STACK_DEPTH);
163 if (frameIndex >= MAX_STACK_DEPTH)
168 return m_stackFrames[frameIndex];
172 MethodDesc* GetMethod(unsigned int frameIndex)
174 LIMITED_METHOD_CONTRACT;
175 _ASSERTE(frameIndex < MAX_STACK_DEPTH);
177 if (frameIndex >= MAX_STACK_DEPTH)
182 return m_methods[frameIndex];
186 void Append(UINT_PTR controlPC, MethodDesc *pMethod)
188 LIMITED_METHOD_CONTRACT;
190 if(m_nextAvailableFrame < MAX_STACK_DEPTH)
192 m_stackFrames[m_nextAvailableFrame] = controlPC;
194 m_methods[m_nextAvailableFrame] = pMethod;
196 m_nextAvailableFrame++;
200 BYTE* GetPointer() const
202 LIMITED_METHOD_CONTRACT;
204 return (BYTE*)m_stackFrames;
207 unsigned int GetSize() const
209 LIMITED_METHOD_CONTRACT;
211 return (m_nextAvailableFrame * sizeof(UINT_PTR));
218 friend class EventPipeConfiguration;
219 friend class EventPipeFile;
220 friend class EventPipeProvider;
221 friend class EventPipeBufferManager;
222 friend class SampleProfiler;
226 // Initialize the event pipe.
227 static void Initialize();
229 // Shutdown the event pipe.
230 static void Shutdown();
232 // Enable tracing from the start-up path based on COMPLUS variable.
233 static void EnableOnStartup();
235 // Enable tracing via the event pipe.
237 LPCWSTR strOutputPath,
238 unsigned int circularBufferSizeInMB,
239 EventPipeProviderConfiguration *pProviders,
242 // Disable tracing via the event pipe.
243 static void Disable();
245 // Specifies whether or not the event pipe is enabled.
246 static bool Enabled();
248 // Create a provider.
249 static EventPipeProvider* CreateProvider(const SString &providerName, EventPipeCallback pCallbackFunction = NULL, void *pCallbackData = NULL);
251 // Delete a provider.
252 static void DeleteProvider(EventPipeProvider *pProvider);
254 // Write out an event from a flat buffer.
255 // Data is written as a serialized blob matching the ETW serialization conventions.
256 static void WriteEvent(EventPipeEvent &event, BYTE *pData, unsigned int length, LPCGUID pActivityId = NULL, LPCGUID pRelatedActivityId = NULL);
258 // Write out an event from an EventData array.
259 // Data is written as a serialized blob matching the ETW serialization conventions.
260 static void WriteEvent(EventPipeEvent &event, EventData **pEventData, unsigned int eventDataCount, LPCGUID pActivityId = NULL, LPCGUID pRelatedActivityId = NULL);
262 // Write out a sample profile event.
263 static void WriteSampleProfileEvent(Thread *pSamplingThread, EventPipeEvent *pEvent, Thread *pTargetThread, StackContents &stackContents, BYTE *pData = NULL, unsigned int length = 0);
265 // Get the managed call stack for the current thread.
266 static bool WalkManagedStackForCurrentThread(StackContents &stackContents);
268 // Get the managed call stack for the specified thread.
269 static bool WalkManagedStackForThread(Thread *pThread, StackContents &stackContents);
273 // The counterpart to WriteEvent which after the payload is constructed
274 static void WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload &payload, LPCGUID pActivityId = NULL, LPCGUID pRelatedActivityId = NULL);
278 // Callback function for the stack walker. For each frame walked, this callback is invoked.
279 static StackWalkAction StackWalkCallback(CrawlFrame *pCf, StackContents *pData);
281 // Get the configuration object.
282 // This is called directly by the EventPipeProvider constructor to register the new provider.
283 static EventPipeConfiguration* GetConfiguration();
285 // Get the event pipe configuration lock.
286 static CrstStatic* GetLock();
288 static CrstStatic s_configCrst;
289 static bool s_tracingInitialized;
290 static EventPipeConfiguration *s_pConfig;
291 static EventPipeBufferManager *s_pBufferManager;
292 static EventPipeFile *s_pFile;
294 static EventPipeFile *s_pSyncFile;
295 static EventPipeJsonFile *s_pJsonFile;
299 struct EventPipeProviderConfiguration
304 LPCWSTR m_pProviderName;
306 UINT32 m_loggingLevel;
310 EventPipeProviderConfiguration()
312 LIMITED_METHOD_CONTRACT;
313 m_pProviderName = NULL;
318 EventPipeProviderConfiguration(
319 LPCWSTR pProviderName,
323 LIMITED_METHOD_CONTRACT;
324 m_pProviderName = pProviderName;
325 m_keywords = keywords;
326 m_loggingLevel = loggingLevel;
329 LPCWSTR GetProviderName() const
331 LIMITED_METHOD_CONTRACT;
332 return m_pProviderName;
335 UINT64 GetKeywords() const
337 LIMITED_METHOD_CONTRACT;
341 UINT32 GetLevel() const
343 LIMITED_METHOD_CONTRACT;
344 return m_loggingLevel;
348 class EventPipeInternal
353 static void QCALLTYPE Enable(
354 __in_z LPCWSTR outputFile,
355 UINT32 circularBufferSizeInMB,
356 INT64 profilerSamplingRateInNanoseconds,
357 EventPipeProviderConfiguration *pProviders,
360 static void QCALLTYPE Disable();
362 static INT_PTR QCALLTYPE CreateProvider(
363 __in_z LPCWSTR providerName,
364 EventPipeCallback pCallbackFunc);
366 static INT_PTR QCALLTYPE DefineEvent(
373 UINT32 metadataLength);
375 static void QCALLTYPE DeleteProvider(
378 static void QCALLTYPE WriteEvent(
383 LPCGUID pActivityId, LPCGUID pRelatedActivityId);
385 static void QCALLTYPE WriteEventData(
388 EventData **pEventData,
389 UINT32 eventDataCount,
390 LPCGUID pActivityId, LPCGUID pRelatedActivityId);
393 #endif // FEATURE_PERFTRACING
395 #endif // __EVENTPIPE_H__