Ejemplo n.º 1
0
        private void ReadAndDispatchTraceEvent(StreamLabel eventStart, uint eventSize)
        {
            // Read the metadata label.
            StreamLabel metadataLabel = (StreamLabel)_deserializer.ReadInt();

            // 0 is the label for metadata.
            if (metadataLabel == 0)
            {
                ReadAndUpdateEventMetadataDictionary(eventStart);
            }
            else
            {
                EventMetadata eventMetadata;
                if (_eventMetadataDictionary.TryGetValue(metadataLabel, out eventMetadata))
                {
                    ReadAndDispatchTraceEvent(eventMetadata);
                }
                else
                {
                    Debug.Fail($"Unable to find metadata for {metadataLabel}.");

                    // Skip the event
                    _deserializer.Goto(eventStart + eventSize);
                }
            }
        }
Ejemplo n.º 2
0
        void IFastSerializable.FromStream(Deserializer deserializer)
        {
            BeforeValue = deserializer.ReadInt();
            StreamLabel label = deserializer.Reader.ReadLabel();

            Assert.Equal((ulong)0x7EADBEEF, (ulong)label);
            AfterValue = deserializer.ReadInt();
        }
Ejemplo n.º 3
0
        internal TraceEventNativeMethods.EVENT_RECORD *ReadEvent(PinnedStreamReader reader)
        {
            EventPipeEventHeader *eventData = (EventPipeEventHeader *)reader.GetPointer(EventPipeEventHeader.HeaderSize);

            eventData = (EventPipeEventHeader *)reader.GetPointer(eventData->TotalEventSize); // now we now the real size and get read entire event

            // Basic sanity checks.  Are the timestamps and sizes sane.
            Debug.Assert(sessionEndTimeQPC <= eventData->TimeStamp);
            Debug.Assert(sessionEndTimeQPC == 0 || eventData->TimeStamp - sessionEndTimeQPC < _QPCFreq * 24 * 3600);
            Debug.Assert(0 <= eventData->PayloadSize && eventData->PayloadSize <= eventData->TotalEventSize);
            Debug.Assert(0 < eventData->TotalEventSize && eventData->TotalEventSize < 0x20000);                               // TODO really should be 64K but BulkSurvivingObjectRanges needs fixing.
            Debug.Assert(_fileFormatVersionNumber < 3 ||
                         ((int)EventPipeEventHeader.PayloadBytes(eventData) % 4 == 0 && eventData->TotalEventSize % 4 == 0)); // ensure 4 byte alignment

            StreamLabel eventDataEnd = reader.Current.Add(eventData->TotalEventSize);

            Debug.Assert(0 <= EventPipeEventHeader.StackBytesSize(eventData) && EventPipeEventHeader.StackBytesSize(eventData) <= eventData->TotalEventSize);

            TraceEventNativeMethods.EVENT_RECORD *ret = null;
            if (eventData->IsMetadata())
            {
                int totalEventSize = eventData->TotalEventSize;
                int payloadSize    = eventData->PayloadSize;

                // Note that this skip invalidates the eventData pointer, so it is important to pull any fields out we need first.
                reader.Skip(EventPipeEventHeader.HeaderSize);

                StreamLabel metaDataEnd = reader.Current.Add(payloadSize);

                // Read in the header (The header does not include payload parameter information)
                var metaDataHeader = new EventPipeEventMetaDataHeader(reader, payloadSize, _fileFormatVersionNumber, PointerSize, _processId);
                _eventMetadataDictionary.Add(metaDataHeader.MetaDataId, metaDataHeader);

                // Tell the parser about this new event
                _eventParser.OnNewEventPipeEventDefinition(metaDataHeader, reader);
                Debug.Assert(reader.Current == metaDataEnd);    // We should have read all the meta-data.

                int stackBytes = reader.ReadInt32();
                Debug.Assert(stackBytes == 0, "Meta-data events should always have a empty stack");
            }
            else
            {
                if (_eventMetadataDictionary.TryGetValue(eventData->MetaDataId, out var metaData))
                {
                    ret = metaData.GetEventRecordForEventData(eventData);
                }
                else
                {
                    Debug.Assert(false, "Warning can't find metaData for ID " + eventData->MetaDataId.ToString("x"));
                }
            }

            reader.Goto(eventDataEnd);

            return(ret);
        }
Ejemplo n.º 4
0
        private TraceEventNativeMethods.EVENT_RECORD *ReadEvent(PinnedStreamReader reader)
        {
            // Guess that the event is < 1000 bytes or whatever is left in the stream.
            int eventSizeGuess = Math.Min(1000, _endOfEventStream.Sub(reader.Current));
            EventPipeEventHeader *eventData = (EventPipeEventHeader *)reader.GetPointer(eventSizeGuess);

            // Basic sanity checks.  Are the timestamps and sizes sane.
            Debug.Assert(sessionEndTimeQPC <= eventData->TimeStamp);
            Debug.Assert(sessionEndTimeQPC == 0 || eventData->TimeStamp - sessionEndTimeQPC < _QPCFreq * 24 * 3600);
            Debug.Assert(0 <= eventData->PayloadSize && eventData->PayloadSize <= eventData->TotalEventSize);
            Debug.Assert(eventData->MetaDataId <= reader.Current);                              // IDs are the location in the of of the data, so it comes before
            Debug.Assert(0 < eventData->TotalEventSize && eventData->TotalEventSize < 0x20000); // TODO really should be 64K but BulkSurvivingObjectRanges needs fixing.

            if (eventSizeGuess < eventData->TotalEventSize)
            {
                eventData = (EventPipeEventHeader *)reader.GetPointer(eventData->TotalEventSize);
            }

            Debug.Assert(0 <= EventPipeEventHeader.StackBytesSize(eventData) && EventPipeEventHeader.StackBytesSize(eventData) <= eventData->TotalEventSize);
            // This asserts that the header size + payload + stackSize field + StackSize == TotalEventSize;
            Debug.Assert(eventData->PayloadSize + EventPipeEventHeader.HeaderSize + sizeof(int) + EventPipeEventHeader.StackBytesSize(eventData) == eventData->TotalEventSize);

            TraceEventNativeMethods.EVENT_RECORD *ret = null;
            EventPipeEventMetaData metaData;

            if (eventData->MetaDataId == 0)     // Is this a Meta-data event?
            {
                int         totalEventSize       = eventData->TotalEventSize;
                int         payloadSize          = eventData->PayloadSize;
                StreamLabel metaDataStreamOffset = reader.Current;  // Used as the 'id' for the meta-data
                // Note that this skip invalidates the eventData pointer, so it is important to pull any fields out we need first.
                reader.Skip(EventPipeEventHeader.HeaderSize);
                metaData = new EventPipeEventMetaData(reader, payloadSize, _fileFormatVersionNumber, PointerSize, _processId);
                _eventMetadataDictionary.Add(metaDataStreamOffset, metaData);
                _eventParser.AddTemplate(metaData);
                int stackBytes = reader.ReadInt32();        // Meta-data events should always have a empty stack.
                Debug.Assert(stackBytes == 0);

                // We have read all the bytes in the event
                Debug.Assert(reader.Current == metaDataStreamOffset.Add(totalEventSize));
            }
            else
            {
                if (_eventMetadataDictionary.TryGetValue(eventData->MetaDataId, out metaData))
                {
                    ret = metaData.GetEventRecordForEventData(eventData);
                }
                else
                {
                    Debug.Assert(false, "Warning can't find metaData for ID " + eventData->MetaDataId.ToString("x"));
                }
                reader.Skip(eventData->TotalEventSize);
            }

            return(ret);
        }
Ejemplo n.º 5
0
 public override void Goto(StreamLabel label)
 {
     uint offset = (uint)label - positionInStream;
     if (offset > (uint)endPosition)
     {
         positionInStream = (uint)label;
         position = endPosition = 0;
     }
     else
         position = (int)offset;
 }
Ejemplo n.º 6
0
        internal TraceEventNativeMethods.EVENT_RECORD *ReadEvent(PinnedStreamReader reader)
        {
            EventPipeEventHeader *eventData = (EventPipeEventHeader *)reader.GetPointer(EventPipeEventHeader.HeaderSize);

            eventData = (EventPipeEventHeader *)reader.GetPointer(eventData->TotalEventSize); // now we now the real size and get read entire event

            // Basic sanity checks.  Are the timestamps and sizes sane.
            Debug.Assert(sessionEndTimeQPC <= eventData->TimeStamp);
            Debug.Assert(sessionEndTimeQPC == 0 || eventData->TimeStamp - sessionEndTimeQPC < _QPCFreq * 24 * 3600);
            Debug.Assert(0 <= eventData->PayloadSize && eventData->PayloadSize <= eventData->TotalEventSize);
            Debug.Assert(0 < eventData->TotalEventSize && eventData->TotalEventSize < 0x20000);                               // TODO really should be 64K but BulkSurvivingObjectRanges needs fixing.
            Debug.Assert(_fileFormatVersionNumber < 3 ||
                         ((int)EventPipeEventHeader.PayloadBytes(eventData) % 4 == 0 && eventData->TotalEventSize % 4 == 0)); // ensure 4 byte alignment

            StreamLabel eventDataEnd = reader.Current.Add(eventData->TotalEventSize);

            Debug.Assert(0 <= EventPipeEventHeader.StackBytesSize(eventData) && EventPipeEventHeader.StackBytesSize(eventData) <= eventData->TotalEventSize);

            TraceEventNativeMethods.EVENT_RECORD *ret = null;;
            if (eventData->IsMetadata())
            {
                int totalEventSize = eventData->TotalEventSize;
                int payloadSize    = eventData->PayloadSize;

                // Note that this skip invalidates the eventData pointer, so it is important to pull any fields out we need first.
                reader.Skip(EventPipeEventHeader.HeaderSize);

                var metaData = new EventPipeEventMetaData(reader, payloadSize, _fileFormatVersionNumber, PointerSize, _processId);
                _eventMetadataDictionary.Add(metaData.MetaDataId, metaData);

                _eventParser.AddTemplate(metaData); // if we don't add the templates to this parse, we are going to have unhadled events (see https://github.com/Microsoft/perfview/issues/461)

                int stackBytes = reader.ReadInt32();
                Debug.Assert(stackBytes == 0, "Meta-data events should always have a empty stack");
            }
            else
            {
                if (_eventMetadataDictionary.TryGetValue(eventData->MetaDataId, out var metaData))
                {
                    ret = metaData.GetEventRecordForEventData(eventData);
                }
                else
                {
                    Debug.Assert(false, "Warning can't find metaData for ID " + eventData->MetaDataId.ToString("x"));
                }
            }

            reader.Goto(eventDataEnd);

            return(ret);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Implementation of IStreamReader
        /// </summary>
        public virtual void Goto(StreamLabel label)
        {
            Debug.Assert(label != StreamLabel.Invalid);

            if (SerializationConfiguration.StreamLabelWidth == StreamLabelWidth.FourBytes)
            {
                Debug.Assert((long)label <= int.MaxValue);
                position = (uint)label;
            }
            else
            {
                position = (long)label;
            }
        }
Ejemplo n.º 8
0
        public override void Goto(StreamLabel label)
        {
            uint offset = (uint)label - positionInStream;

            if (offset > (uint)endPosition)
            {
                positionInStream = (uint)label;
                position         = endPosition = 0;
            }
            else
            {
                position = (int)offset;
            }
        }
Ejemplo n.º 9
0
        public override bool Process()
        {
            while (_deserializer.Current < _endOfEventStream)
            {
                StreamLabel eventStart = _deserializer.Current;

                // Read the size of the next event.
                uint eventSize = (uint)_deserializer.ReadInt();

                ReadAndDispatchTraceEvent(eventStart, eventSize);
            }

            sessionEndTimeQPC = (long)_lastTimestamp;

            return(true);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Implementation of IStreamReader
        /// </summary>
        public override void Goto(StreamLabel label)
        {
            uint offset = unchecked ((uint)label - positionInStream);

            if (offset > (uint)endPosition)
            {
                if (!inputStream.CanSeek)
                {
                    if ((uint)label < positionInStream + endPosition)
                    {
                        throw new Exception("Stream does not support seeking backwards");
                    }
                }
                positionInStream = (uint)label;
                position         = endPosition = 0;
            }
            else
            {
                position = (int)offset;
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Implementation of IStreamReader
        /// </summary>
        public override void Goto(StreamLabel label)
        {
            long offset = (long)label - positionInStream;

            if (offset > endPosition || offset < 0)
            {
                if (!inputStream.CanSeek)
                {
                    if ((long)label < positionInStream + endPosition)
                    {
                        throw new Exception("Stream does not support seeking backwards");
                    }
                }
                positionInStream = (long)label & ~(align - 1);
                position         = (int)((long)label & (align - 1));
                endPosition      = 0;
            }
            else
            {
                position = (int)offset;
            }
        }
Ejemplo n.º 12
0
 public virtual void Goto(StreamLabel label)
 {
     Debug.Assert(label != StreamLabel.Invalid);
     position = (int)label;
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Get a byte* pointer to the input buffer at 'Position' in the IReadStream that is at least 'length' bytes long.
 /// (thus ptr to ptr+len is valid).   Note that length cannot be larger than the buffer size passed to the reader
 /// when it was constructed.
 /// </summary>
 public unsafe byte *GetPointer(StreamLabel Position, int length)
 {
     Goto(Position);
     return(GetPointer(length));
 }
Ejemplo n.º 14
0
 /// <summary>
 /// Implementation of IStreamReader
 /// </summary>
 public virtual void Goto(StreamLabel label)
 {
     Debug.Assert(label != StreamLabel.Invalid);
     position = (int)label;
 }
Ejemplo n.º 15
0
 public void WriteSuffixLabel(StreamLabel value)
 {
     // This is guarenteed to be uncompressed, but since we are not compressing anything, we can
     // simply write the value.  
     Write(value);
 }
Ejemplo n.º 16
0
 public void Write(StreamLabel value)
 {
     Write((int)value);
 }
Ejemplo n.º 17
0
 public virtual void Goto(StreamLabel label)
 {
     position = (int)label;
 }
Ejemplo n.º 18
0
        /// <summary>
        /// Creates a new MetaData instance from the serialized data at the current position of 'reader'
        /// of length 'length'.   This typically points at the PAYLOAD AREA of a meta-data events)
        /// 'fileFormatVersionNumber' is the version number of the file as a whole
        /// (since that affects the parsing of this data) and 'processID' is the process ID for the
        /// whole stream (since it needs to be put into the EVENT_RECORD.
        ///
        /// When this constructor returns the reader has read all data given to it (thus it has
        /// move the read pointer by 'length')
        /// </summary>
        public EventPipeEventMetaData(PinnedStreamReader reader, int length, int fileFormatVersionNumber, int pointerSize, int processId)
        {
            StreamLabel eventDataEnd = reader.Current.Add(length);

            _eventRecord = (TraceEventNativeMethods.EVENT_RECORD *)Marshal.AllocHGlobal(sizeof(TraceEventNativeMethods.EVENT_RECORD));
            ClearMemory(_eventRecord, sizeof(TraceEventNativeMethods.EVENT_RECORD));

            if (pointerSize == 4)
            {
                _eventRecord->EventHeader.Flags = TraceEventNativeMethods.EVENT_HEADER_FLAG_32_BIT_HEADER;
            }
            else
            {
                _eventRecord->EventHeader.Flags = TraceEventNativeMethods.EVENT_HEADER_FLAG_64_BIT_HEADER;
            }

            _eventRecord->EventHeader.ProcessId = processId;

            StreamLabel metaDataStart = reader.Current;

            if (fileFormatVersionNumber == 1)
            {
                _eventRecord->EventHeader.ProviderId = reader.ReadGuid();
            }
            else
            {
                ProviderName = reader.ReadNullTerminatedUnicodeString();
                _eventRecord->EventHeader.ProviderId = GetProviderGuidFromProviderName(ProviderName);
            }

            var eventId = (ushort)reader.ReadInt32();

            _eventRecord->EventHeader.Id = eventId;
            Debug.Assert(_eventRecord->EventHeader.Id == eventId);  // No truncation

            var version = reader.ReadInt32();

            _eventRecord->EventHeader.Version = (byte)version;
            Debug.Assert(_eventRecord->EventHeader.Version == version);  // No truncation

            if (fileFormatVersionNumber >= 3)
            {
                long keywords = reader.ReadInt64();
                _eventRecord->EventHeader.Keyword = (ulong)keywords;
            }

            int metadataLength = reader.ReadInt32();

            Debug.Assert(0 <= metadataLength && metadataLength < length);
            if (0 < metadataLength)
            {
                // TODO why do we repeat the event number it is redundant.
                eventId = (ushort)reader.ReadInt32();
                Debug.Assert(_eventRecord->EventHeader.Id == eventId);  // No truncation
                EventName = reader.ReadNullTerminatedUnicodeString();
                Debug.Assert(EventName.Length < length / 2);

                // Deduce the opcode from the name.
                if (EventName.EndsWith("Start", StringComparison.OrdinalIgnoreCase))
                {
                    _eventRecord->EventHeader.Opcode = (byte)TraceEventOpcode.Start;
                }
                else if (EventName.EndsWith("Stop", StringComparison.OrdinalIgnoreCase))
                {
                    _eventRecord->EventHeader.Opcode = (byte)TraceEventOpcode.Stop;
                }

                _eventRecord->EventHeader.Keyword = (ulong)reader.ReadInt64();

                // TODO why do we repeat the event number it is redundant.
                version = reader.ReadInt32();
                Debug.Assert(_eventRecord->EventHeader.Version == version);     // No truncation

                _eventRecord->EventHeader.Level = (byte)reader.ReadInt32();
                Debug.Assert(_eventRecord->EventHeader.Level <= 5);

                // Fetch the parameter information
                int parameterCount = reader.ReadInt32();
                Debug.Assert(0 <= parameterCount && parameterCount < length / 8); // Each parameter takes at least 8 bytes.
                if (parameterCount > 0)
                {
                    ParameterDefinitions = new Tuple <TypeCode, string> [parameterCount];
                    for (int i = 0; i < parameterCount; i++)
                    {
                        var type = (TypeCode)reader.ReadInt32();
                        Debug.Assert((uint)type < 24);      // There only a handful of type codes.
                        var name = reader.ReadNullTerminatedUnicodeString();
                        ParameterDefinitions[i] = new Tuple <TypeCode, string>(type, name);
                        Debug.Assert(reader.Current <= eventDataEnd);
                    }
                }
            }
            Debug.Assert(reader.Current == eventDataEnd);
        }
Ejemplo n.º 19
0
 public void Write(StreamLabel value)
 {
     Write((int)value);
 }
Ejemplo n.º 20
0
        private void ReadAndUpdateEventMetadataDictionary(StreamLabel eventStart)
        {
            var eventMetadata = new EventMetadata();

            // Skip the EventPipeEvent common fields which are not related to metedata
            int commonFieldSize = sizeof(int)     // ThreadId
                                  + sizeof(Int64) // Timestamp
                                  + sizeof(Guid)  // ActivityId
                                  + sizeof(Guid); // RelatedActivityId

            _deserializer.Goto(_deserializer.Current + (uint)commonFieldSize);

            // Read the event payload size.
            var payloadSize = _deserializer.ReadInt();

            Debug.Assert(payloadSize >= 0, "Payload size should not be negative.");

            if (_version == 1)
            {
                var providerId = Guid.Empty;
                _deserializer.Read(out providerId);
                eventMetadata.ProviderId = providerId;
            }
            else
            {
                eventMetadata.ProviderName = _deserializer.ReadNullTerminatedUnicodeString();
            }

            eventMetadata.EventId = (uint)_deserializer.ReadInt();
            eventMetadata.Version = (uint)_deserializer.ReadInt();
            var metadataPayloadLength = (uint)_deserializer.ReadInt();

            if (metadataPayloadLength > 0)
            {
                var payloadIdentifierLength = 0;
                if (_version == 1)
                {
                    payloadIdentifierLength = sizeof(Guid);
                }
                else
                {
                    payloadIdentifierLength = (eventMetadata.ProviderName.Length + 1) * sizeof(Char); // +1 for null-terminator
                }
                var actualPayloadSize = payloadIdentifierLength
                                        + sizeof(int) // EventId
                                        + sizeof(int) // Version
                                        + sizeof(int) // MetadataPayloadLength
                                        + metadataPayloadLength;
                Debug.Assert(payloadSize == actualPayloadSize, $"The total event payload size is {actualPayloadSize}. But it is expected to be {payloadSize}.");

                // Read EventSource definition: https://github.com/dotnet/coreclr/blob/release/2.0.0/src/mscorlib/shared/System/Diagnostics/Tracing/EventSource.cs#L708
                eventMetadata.EventId   = (uint)_deserializer.ReadInt();
                eventMetadata.EventName = _deserializer.ReadNullTerminatedUnicodeString();
                eventMetadata.Keywords  = (ulong)_deserializer.ReadInt64();
                eventMetadata.Version   = (uint)_deserializer.ReadInt();
                eventMetadata.Level     = (uint)_deserializer.ReadInt();

                int parameterCount = _deserializer.ReadInt();
                Debug.Assert(parameterCount >= 0, "Parameter count should not be negative.");

                if (parameterCount > 0)
                {
                    eventMetadata.ParameterDefinitions = new Tuple <TypeCode, string> [parameterCount];
                    for (int i = 0; i < parameterCount; i++)
                    {
                        var type = (uint)_deserializer.ReadInt();
                        var name = _deserializer.ReadNullTerminatedUnicodeString();
                        eventMetadata.ParameterDefinitions[i] = new Tuple <TypeCode, string>((TypeCode)type, name);
                    }
                }

                // add a new template to event parser
                _eventParser.AddTemplate(eventMetadata);
            }

            // Add the new event meta data into dictionary
            _eventMetadataDictionary.Add(eventStart, eventMetadata);

            // Read and verify stack size
            _deserializer.ReadIntAndVerify(0);
        }
Ejemplo n.º 21
0
 public unsafe TraceEventNativeMethods.EVENT_RECORD* GetPointer(StreamLabel Position, int length)
 {
     Goto(Position);
     return GetPointer(length);
 }
Ejemplo n.º 22
0
 /// <summary>
 /// Implementation of IStreamReader
 /// </summary>
 public virtual void Goto(StreamLabel label)
 {
     Debug.Assert(label != StreamLabel.Invalid);
     Debug.Assert((long)label <= int.MaxValue);
     position = (int)label;
 }
Ejemplo n.º 23
0
 public virtual void Goto(StreamLabel label)
 {
     position = (int)label;
 }
Ejemplo n.º 24
0
 /// <summary>
 /// Implementation of IStreamWriter
 /// </summary>
 public void Write(StreamLabel value)
 {
     Debug.Assert((long)value <= int.MaxValue);
     Write((int)value);
 }
Ejemplo n.º 25
0
 public void WriteSuffixLabel(StreamLabel value)
 {
     // This is guarenteed to be uncompressed, but since we are not compressing anything, we can
     // simply write the value.
     Write(value);
 }
Ejemplo n.º 26
0
 public unsafe byte* GetPointer(StreamLabel Position, int length)
 {
     Goto(Position);
     return GetPointer(length);
 }
Ejemplo n.º 27
0
 public unsafe TraceEventNativeMethods.EVENT_RECORD *GetPointer(StreamLabel Position, int length)
 {
     Goto(Position);
     return(GetPointer(length));
 }
Ejemplo n.º 28
0
 /// <summary>
 /// Implementation of IStreamWriter
 /// </summary>
 public void Write(StreamLabel value)
 {
     writeLabel(value);
 }