Пример #1
0
        public void ProcessStackBlock(byte[] stackBlock)
        {
            PinnedBuffer buffer = new PinnedBuffer(stackBlock);

            if (stackBlock.Length < 8)
            {
                Debug.Assert(false, "Bad stack block size");
                return;
            }
            int cursor       = 0;
            int firstStackId = BitConverter.ToInt32(stackBlock, cursor);

            cursor += 4;
            int countStackIds = BitConverter.ToInt32(stackBlock, cursor);

            cursor += 4;
            int nextStackId = firstStackId;

            while (cursor < stackBlock.Length)
            {
                StackMarker marker = new StackMarker();
                marker.BackingBuffer = buffer;
                int stackId = nextStackId++;
                marker.StackBytesSize = BitConverter.ToInt32(stackBlock, cursor);
                cursor += 4;
                if (cursor + marker.StackBytesSize <= stackBlock.Length)
                {
                    marker.StackBytes = buffer.PinningHandle.AddrOfPinnedObject() + cursor;
                    cursor           += marker.StackBytesSize;
                    _stacks.Add(stackId, marker);
                }
                else
                {
                    Debug.Assert(false, "Stack size exceeds stack block region");
                    break;
                }
            }
            Debug.Assert(nextStackId == firstStackId + countStackIds);
        }
Пример #2
0
 public EventMarker(PinnedBuffer buffer)
 {
     Buffer = buffer;
 }
Пример #3
0
        public unsafe void ProcessEventBlock(byte[] eventBlockData)
        {
            // parse the header
            if (eventBlockData.Length < 20)
            {
                Debug.Assert(false, "Expected EventBlock of at least 20 bytes");
                return;
            }
            ushort headerSize = BitConverter.ToUInt16(eventBlockData, 0);

            if (headerSize < 20 || headerSize > eventBlockData.Length)
            {
                Debug.Assert(false, "Invalid EventBlock header size");
                return;
            }
            ushort flags = BitConverter.ToUInt16(eventBlockData, 2);
            bool   useHeaderCompression = (flags & (ushort)EventBlockFlags.HeaderCompression) != 0;

            // parse the events
            PinnedBuffer buffer = new PinnedBuffer(eventBlockData);
            byte *       cursor = (byte *)buffer.PinningHandle.AddrOfPinnedObject();
            byte *       end    = cursor + eventBlockData.Length;

            cursor += headerSize;
            EventMarker eventMarker = new EventMarker(buffer);
            long        timestamp   = 0;

            EventPipeEventHeader.ReadFromFormatV4(cursor, useHeaderCompression, ref eventMarker.Header);
            if (!_threads.TryGetValue(eventMarker.Header.CaptureThreadId, out EventCacheThread thread))
            {
                thread = new EventCacheThread();
                thread.SequenceNumber = eventMarker.Header.SequenceNumber - 1;
                AddThread(eventMarker.Header.CaptureThreadId, thread);
            }
            eventMarker = new EventMarker(buffer);
            while (cursor < end)
            {
                EventPipeEventHeader.ReadFromFormatV4(cursor, useHeaderCompression, ref eventMarker.Header);
                bool isSortedEvent = eventMarker.Header.IsSorted;
                timestamp = eventMarker.Header.TimeStamp;
                int sequenceNumber = eventMarker.Header.SequenceNumber;
                if (isSortedEvent)
                {
                    thread.LastCachedEventTimestamp = timestamp;

                    // sorted events are the only time the captureThreadId should change
                    long captureThreadId = eventMarker.Header.CaptureThreadId;
                    if (!_threads.TryGetValue(captureThreadId, out thread))
                    {
                        thread = new EventCacheThread();
                        thread.SequenceNumber = sequenceNumber - 1;
                        AddThread(captureThreadId, thread);
                    }
                }

                int droppedEvents = (int)Math.Min(int.MaxValue, sequenceNumber - thread.SequenceNumber - 1);
                if (droppedEvents > 0)
                {
                    OnEventsDropped?.Invoke(droppedEvents);
                }
                else
                {
                    // When a thread id is recycled the sequenceNumber can abruptly reset to 1 which
                    // makes droppedEvents go negative
                    Debug.Assert(droppedEvents == 0 || sequenceNumber == 1);
                }
                thread.SequenceNumber = sequenceNumber;

                if (isSortedEvent)
                {
                    SortAndDispatch(timestamp);
                    OnEvent?.Invoke(ref eventMarker.Header);
                }
                else
                {
                    thread.Events.Enqueue(eventMarker);
                }

                cursor += eventMarker.Header.TotalNonHeaderSize + eventMarker.Header.HeaderSize;
                EventMarker lastEvent = eventMarker;
                eventMarker        = new EventMarker(buffer);
                eventMarker.Header = lastEvent.Header;
            }
            thread.LastCachedEventTimestamp = timestamp;
        }