-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Conversation
…e it work fo x86)
…nsumers get clear error message
…the event block objects
This reverts commit 98ef2f5.
…ated with native code)
…, right after last events
…need to serialize length)
# Conflicts: # src/vm/eventpipeeventinstance.h
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making these changes. Looks good - some comments as well.
src/vm/eventpipe.cpp
Outdated
@@ -393,6 +393,8 @@ void EventPipe::Disable() | |||
s_pConfig->DeleteSession(s_pSession); | |||
s_pSession = NULL; | |||
|
|||
s_pFile->WriteEnd(); // write the rest of the events and end tag to the file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If possible, it would be nice to have this occur as part of the destructor of the EventPipeFile. This ensures that no matter how the file is used the end gets properly written. Note that there is at least one more EventPipeFile - the synchronously written file that would also need a call to WriteEnd to be functionally correct, though I'm not 100% sure that it still works today.
src/vm/eventpipeblock.h
Outdated
|
||
void FastSerialize(FastSerializer *pSerializer) | ||
{ | ||
unsigned int eventsSize = (unsigned int)(m_pWritePointer - m_pBlock); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should use size_t as the size here since it is guaranteed to allow you to represent all memory addresses (and sizes) for a given bitness machine.
class EventPipeBlock : public FastSerializableObject | ||
{ | ||
public: | ||
EventPipeBlock(unsigned int maxBlockSize); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
size_t here as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same sizes of blocks can be 32 bit.
src/vm/eventpipeblock.cpp
Outdated
} | ||
CONTRACTL_END; | ||
|
||
m_pBlock = new BYTE[maxBlockSize]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a philosophical statement, we say that we don't want failures in tracing to affect program correctness. Thus, one of the things we do is to try to make sure that we don't throw in places that will leak out to the program. The only exception that EventPipe has (or should have) currently is that we will throw if you try to enable tracing in-proc and it fails for some reason. Other than that, we'd rather lose data than affect program correctness.
Thus, here, you should use the nothrow flavor of new:
m_pBlock = new (nothrow) BYTE[maxBlockSize];
if(m_pBlock == NULL)
{
return;
}
You will of course also need to handle a NULL m_pBlock inside the other functions of EventPipeBlock.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! I had no idea about new (nothrow)
m_pWritePointer += stackSize; | ||
} | ||
|
||
while (m_pWritePointer < alignedEnd) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Please put { } around this loop.
src/vm/eventpipefile.h
Outdated
MapSHashWithRemove<EventPipeEvent*, StreamLabel> *m_pMetadataLabels; | ||
MapSHashWithRemove<EventPipeEvent*, unsigned int> *m_pMetadataIds; | ||
|
||
volatile unsigned int m_metadataIdCounter; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you change the type to Volatile I don't think you'll need the casts when you call InterlockedIncrement.
|
||
m_pBlock->Clear(); | ||
|
||
// "After the last EventBlock is emitted, the stream is ended by emitting a NullReference Tag which indicates that there are no more objects in the stream to read." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accidental quotes on the comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was a quote from the docs, I should have added link
|
||
instance.SetMetadataId(metadataId); | ||
|
||
if (m_pBlock->WriteEvent(instance)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: { }
src/vm/eventpipefile.h
Outdated
{ | ||
LIMITED_METHOD_CONTRACT; | ||
return "Microsoft.DotNet.Runtime.EventPipeFile"; | ||
pSerializer->WriteBuffer((BYTE*)&m_fileOpenSystemTime, sizeof(m_fileOpenSystemTime)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this! Much better that the file itself is represented in FastSerialization instead of being special cased.
} | ||
|
||
// Get the type name of this object. | ||
const char* GetTypeName() | ||
void FastSerialize(FastSerializer *pSerializer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know that you got rid of the support for forward references as part of this change to make it easier to support streaming. How do you make sure that this block of information is extensible since the forward references are now gone?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One other thing that we should look at is what the right default block size is so that we don't thrash too much but also don't allocate huge blocks. |
I have updated http://nuget.org with version 2.0.4 of the TraceEvent library which has the EventPipe V3 format in it. @adamsitnik you can update your test code to point at it so it does not fail. Note that I am assuming you know about the fact that you can create a Nuget.Config file at the base of your project and add additional locations to find nuget packages (see https://github.com/Microsoft/perfview/blob/master/Nuget.config) you can thus make your private version of the TraceEvent package and put it there and your test code will find it. This allows you to test everything without needing to update nuget.org.
Note that my belief is that any number between 10K to 1Meg will work well enough for write perf. We currently use 100K and that is a fine number. |
One of the Ubuntu builds fails with How can I increment a value in atomic, cross-platform way here? I understand that I have ofc search for that on the web, but I can't see anybody using |
It looks like the PAL only implements InterlockedIncrement for LONG and LONGLONG (via InterlockedIncrement64). See https://github.com/dotnet/coreclr/blob/master/src/pal/inc/pal.h#L4159 for details. You just happen to be picking up the int version on Windows most likely. Probably the best thing to do is to change the data type of the metadata ID counter to |
@adamsitnik - Try FastInterlockIncrement. (although I must admit I am surprised that InterlockedIncrement did not work). |
@brianrob @vancem thanks for help and the review! Brian, I just pushed last minor improvements after additional review from @jorive Could you check the PR? If you accept it, and all tests except the unstable HardwareInstrincts pass, who can merge it then? I have this right on GitHub but I don't know the rules. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
@adamsitnik, once the CI runs complete and pass (or just have the hardware intrinsic failures) you can go ahead and merge. The default option (Squash and merge) is what you should use since you don't need to maintain distinct commits for this change. Requirements for merge are clean CI, MS employee review sign-off. |
* 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 dotnet/coreclr#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 dotnet/coreclr#11934" This reverts commit dotnet/coreclr@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 Commit migrated from dotnet/coreclr@f6ba335
This PR is ready for review, but not ready to be merged yet.
Today all non-Windows build are going to fail because I have bumped the version of Event Pipe file, which is not supported by the referenced EventTrace library.
We need to release new version of TraceEvent lib and updated the references to it in CoreCLR, so all tests are going to pass. This + review and then it can be merge.
Changes:
I am a newbie when it comes to C++, please make sure that the review is very detailed.
/cc @jorive