This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* write missing information to the event pipe file (pointer size to make it work fo x86) * define where the events start, not only where they end * include process Id in the event pipe file, bump the version so old consumers get clear error message * write the missing EndObject tag to close the header * include expected CPU sampling rate in the event pipe header file * include keywords in V3 of EventPipe metadata, fixes #11934 * remove forward references * entry object comes after the header and ends after it's data, before the event block objects * introduce event block * fix the GC contracts * generate metadata ids * end the file with null reference tag * getting it work * 4 byte alignment of serialized event data * Revert "include keywords in V3 of EventPipe metadata, fixes #11934" This reverts commit 98ef2f5. * remove event Id and event version from metadata buffer (it was duplicated with native code) * increase the block size to be the same as buffer size * Write the last event block to the file after disabling the event pipe, right after last events * include the sife in itself * the native part was supposed to not duplicate the event id and version, not manged * ensure 4 byte alignment * build metadata when it's not provided, so payload is never empty (no need to serialize length) * this todo is no longer valid * don't align everything, just the content of event block as suggested by @vancem * improvements after code review * update TraceEvent dependency, make the test verify new feature * InterlockedIncrement(Int32) is not available for non-Windows OSes * code improvements after Skype code review from @jorive
- Loading branch information
1 parent
70bf6a4
commit f6ba335
Showing
18 changed files
with
601 additions
and
348 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
#include "common.h" | ||
#include "eventpipeblock.h" | ||
#include "eventpipeeventinstance.h" | ||
#include "fastserializableobject.h" | ||
#include "fastserializer.h" | ||
|
||
#ifdef FEATURE_PERFTRACING | ||
|
||
EventPipeBlock::EventPipeBlock(unsigned int maxBlockSize) | ||
{ | ||
CONTRACTL | ||
{ | ||
NOTHROW; | ||
GC_NOTRIGGER; | ||
MODE_ANY; | ||
} | ||
CONTRACTL_END; | ||
|
||
m_pBlock = new (nothrow) BYTE[maxBlockSize]; | ||
if (m_pBlock == NULL) | ||
{ | ||
return; | ||
} | ||
|
||
memset(m_pBlock, 0, maxBlockSize); | ||
m_pWritePointer = m_pBlock; | ||
m_pEndOfTheBuffer = m_pBlock + maxBlockSize; | ||
} | ||
|
||
EventPipeBlock::~EventPipeBlock() | ||
{ | ||
CONTRACTL | ||
{ | ||
NOTHROW; | ||
GC_NOTRIGGER; | ||
MODE_ANY; | ||
} | ||
CONTRACTL_END; | ||
|
||
if(m_pBlock != NULL) | ||
{ | ||
m_pEndOfTheBuffer = NULL; | ||
m_pWritePointer = NULL; | ||
delete[] m_pBlock; | ||
m_pBlock = NULL; | ||
} | ||
} | ||
|
||
bool EventPipeBlock::WriteEvent(EventPipeEventInstance &instance) | ||
{ | ||
CONTRACTL | ||
{ | ||
NOTHROW; | ||
GC_NOTRIGGER; | ||
MODE_ANY; | ||
} | ||
CONTRACTL_END; | ||
|
||
if (m_pBlock == NULL) | ||
{ | ||
return false; | ||
} | ||
|
||
unsigned int totalSize = instance.GetAlignedTotalSize(); | ||
if (m_pWritePointer + totalSize >= m_pEndOfTheBuffer) | ||
{ | ||
return false; | ||
} | ||
|
||
BYTE* alignedEnd = m_pWritePointer + totalSize + sizeof(totalSize); | ||
|
||
memcpy(m_pWritePointer, &totalSize, sizeof(totalSize)); | ||
m_pWritePointer += sizeof(totalSize); | ||
|
||
unsigned int metadataId = instance.GetMetadataId(); | ||
memcpy(m_pWritePointer, &metadataId, sizeof(metadataId)); | ||
m_pWritePointer += sizeof(metadataId); | ||
|
||
DWORD threadId = instance.GetThreadId(); | ||
memcpy(m_pWritePointer, &threadId, sizeof(threadId)); | ||
m_pWritePointer += sizeof(threadId); | ||
|
||
const LARGE_INTEGER* timeStamp = instance.GetTimeStamp(); | ||
memcpy(m_pWritePointer, timeStamp, sizeof(*timeStamp)); | ||
m_pWritePointer += sizeof(*timeStamp); | ||
|
||
const GUID* activityId = instance.GetActivityId(); | ||
memcpy(m_pWritePointer, activityId, sizeof(*activityId)); | ||
m_pWritePointer += sizeof(*activityId); | ||
|
||
const GUID* relatedActivityId = instance.GetRelatedActivityId(); | ||
memcpy(m_pWritePointer, relatedActivityId, sizeof(*relatedActivityId)); | ||
m_pWritePointer += sizeof(*relatedActivityId); | ||
|
||
unsigned int dataLength = instance.GetDataLength(); | ||
memcpy(m_pWritePointer, &dataLength, sizeof(dataLength)); | ||
m_pWritePointer += sizeof(dataLength); | ||
|
||
if (dataLength > 0) | ||
{ | ||
memcpy(m_pWritePointer, instance.GetData(), dataLength); | ||
m_pWritePointer += dataLength; | ||
} | ||
|
||
unsigned int stackSize = instance.GetStackSize(); | ||
memcpy(m_pWritePointer, &stackSize, sizeof(stackSize)); | ||
m_pWritePointer += sizeof(stackSize); | ||
|
||
if (stackSize > 0) | ||
{ | ||
memcpy(m_pWritePointer, instance.GetStack(), stackSize); | ||
m_pWritePointer += stackSize; | ||
} | ||
|
||
while (m_pWritePointer < alignedEnd) | ||
{ | ||
*m_pWritePointer++ = (BYTE)0; // put padding at the end to get 4 bytes alignment of the payload | ||
} | ||
|
||
return true; | ||
} | ||
|
||
void EventPipeBlock::Clear() | ||
{ | ||
CONTRACTL | ||
{ | ||
NOTHROW; | ||
GC_NOTRIGGER; | ||
MODE_ANY; | ||
} | ||
CONTRACTL_END; | ||
|
||
if (m_pBlock == NULL) | ||
{ | ||
return; | ||
} | ||
|
||
memset(m_pBlock, 0, GetSize()); | ||
m_pWritePointer = m_pBlock; | ||
} | ||
|
||
#endif // FEATURE_PERFTRACING |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
#ifndef __EVENTPIPE_BLOCK_H__ | ||
#define __EVENTPIPE_BLOCK_H__ | ||
|
||
#ifdef FEATURE_PERFTRACING | ||
|
||
#include "eventpipeeventinstance.h" | ||
#include "fastserializableobject.h" | ||
#include "fastserializer.h" | ||
|
||
class EventPipeBlock : public FastSerializableObject | ||
{ | ||
public: | ||
EventPipeBlock(unsigned int maxBlockSize); | ||
|
||
~EventPipeBlock(); | ||
|
||
// Write an event to the block. | ||
// Returns: | ||
// - true: The write succeeded. | ||
// - false: The write failed. In this case, the block should be considered full. | ||
bool WriteEvent(EventPipeEventInstance &instance); | ||
|
||
void Clear(); | ||
|
||
const char* GetTypeName() | ||
{ | ||
LIMITED_METHOD_CONTRACT; | ||
return "EventBlock"; | ||
} | ||
|
||
void FastSerialize(FastSerializer *pSerializer) | ||
{ | ||
CONTRACTL | ||
{ | ||
NOTHROW; | ||
GC_NOTRIGGER; | ||
MODE_PREEMPTIVE; | ||
PRECONDITION(pSerializer != NULL); | ||
} | ||
CONTRACTL_END; | ||
|
||
if (m_pBlock == NULL) | ||
{ | ||
return; | ||
} | ||
|
||
unsigned int eventsSize = (unsigned int)(m_pWritePointer - m_pBlock); | ||
pSerializer->WriteBuffer((BYTE*)&eventsSize, sizeof(eventsSize)); | ||
|
||
if (eventsSize == 0) | ||
{ | ||
return; | ||
} | ||
|
||
size_t currentPosition = pSerializer->GetCurrentPosition(); | ||
if (currentPosition % ALIGNMENT_SIZE != 0) | ||
{ | ||
BYTE maxPadding[ALIGNMENT_SIZE - 1] = {}; // it's longest possible padding, we are going to use only part of it | ||
unsigned int paddingLength = ALIGNMENT_SIZE - (currentPosition % ALIGNMENT_SIZE); | ||
pSerializer->WriteBuffer(maxPadding, paddingLength); // we write zeros here, the reader is going to always read from the first aligned address of the serialized content | ||
|
||
_ASSERTE(pSerializer->GetCurrentPosition() % ALIGNMENT_SIZE == 0); | ||
} | ||
|
||
pSerializer->WriteBuffer(m_pBlock, eventsSize); | ||
} | ||
|
||
private: | ||
BYTE *m_pBlock; | ||
BYTE *m_pWritePointer; | ||
BYTE *m_pEndOfTheBuffer; | ||
|
||
unsigned int GetSize() const | ||
{ | ||
LIMITED_METHOD_CONTRACT; | ||
|
||
if (m_pBlock == NULL) | ||
{ | ||
return 0; | ||
} | ||
|
||
return (unsigned int)(m_pEndOfTheBuffer - m_pBlock); | ||
} | ||
}; | ||
|
||
#endif // FEATURE_PERFTRACING | ||
|
||
#endif // __EVENTPIPE_BLOCK_H__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.