LogEvent ReadEvent() { var type = Reader.ReadByte(); var basicType = (LogEventType)(type & 0xf); var extType = (LogEventType)(type & 0xf0); _time = ReadTime(); switch (basicType) { case LogEventType.Allocation: switch (extType) { case LogEventType.AllocationBacktrace: case LogEventType.AllocationNoBacktrace: return(new AllocationEvent { ClassPointer = ReadPointer(), ObjectPointer = ReadObject(), ObjectSize = (long)Reader.ReadULeb128(), Backtrace = ReadBacktrace(extType == LogEventType.AllocationBacktrace), }); default: throw new LogException($"Invalid extended event type ({extType})."); } case LogEventType.GC: switch (extType) { case LogEventType.GCEvent: return(new GCEvent { Type = (LogGCEvent)Reader.ReadByte(), Generation = Reader.ReadByte(), }); case LogEventType.GCResize: return(new GCResizeEvent { NewSize = (long)Reader.ReadULeb128(), }); case LogEventType.GCMove: { var list = new long [(int)Reader.ReadULeb128()]; for (var i = 0; i < list.Length; i++) { list [i] = ReadObject(); } return(new GCMoveEvent { OldObjectPointers = list.Where((_, i) => i % 2 == 0).ToArray(), NewObjectPointers = list.Where((_, i) => i % 2 != 0).ToArray(), }); } case LogEventType.GCHandleCreationNoBacktrace: case LogEventType.GCHandleCreationBacktrace: return(new GCHandleCreationEvent { Type = (LogGCHandleType)Reader.ReadULeb128(), Handle = (long)Reader.ReadULeb128(), ObjectPointer = ReadObject(), Backtrace = ReadBacktrace(extType == LogEventType.GCHandleCreationBacktrace), }); case LogEventType.GCHandleDeletionNoBacktrace: case LogEventType.GCHandleDeletionBacktrace: return(new GCHandleDeletionEvent { Type = (LogGCHandleType)Reader.ReadULeb128(), Handle = (long)Reader.ReadULeb128(), Backtrace = ReadBacktrace(extType == LogEventType.GCHandleDeletionBacktrace), }); case LogEventType.GCFinalizeBegin: return(new GCFinalizeBeginEvent()); case LogEventType.GCFinalizeEnd: return(new GCFinalizeEndEvent()); case LogEventType.GCFinalizeObjectBegin: return(new GCFinalizeObjectBeginEvent { ObjectPointer = ReadObject(), }); case LogEventType.GCFinalizeObjectEnd: return(new GCFinalizeObjectEndEvent { ObjectPointer = ReadObject(), }); default: throw new LogException($"Invalid extended event type ({extType})."); } case LogEventType.Metadata: { var load = false; var unload = false; switch (extType) { case LogEventType.MetadataExtra: break; case LogEventType.MetadataEndLoad: load = true; break; case LogEventType.MetadataEndUnload: unload = true; break; default: throw new LogException($"Invalid extended event type ({extType})."); } var metadataType = (LogMetadataType)Reader.ReadByte(); switch (metadataType) { case LogMetadataType.Class: if (load) { return(new ClassLoadEvent { ClassPointer = ReadPointer(), ImagePointer = ReadPointer(), Name = Reader.ReadCString(), }); } else { throw new LogException("Invalid class metadata event."); } case LogMetadataType.Image: if (load) { return(new ImageLoadEvent { ImagePointer = ReadPointer(), Name = Reader.ReadCString(), }); } else if (unload) { return(new ImageUnloadEvent { ImagePointer = ReadPointer(), Name = Reader.ReadCString(), }); } else { throw new LogException("Invalid image metadata event."); } case LogMetadataType.Assembly: if (load) { return(new AssemblyLoadEvent { AssemblyPointer = ReadPointer(), ImagePointer = ReadPointer(), Name = Reader.ReadCString(), }); } else if (unload) { return(new AssemblyUnloadEvent { AssemblyPointer = ReadPointer(), ImagePointer = ReadPointer(), Name = Reader.ReadCString(), }); } else { throw new LogException("Invalid assembly metadata event."); } case LogMetadataType.AppDomain: if (load) { return(new AppDomainLoadEvent { AppDomainId = ReadPointer(), }); } else if (unload) { return(new AppDomainUnloadEvent { AppDomainId = ReadPointer(), }); } else { return(new AppDomainNameEvent { AppDomainId = ReadPointer(), Name = Reader.ReadCString(), }); } case LogMetadataType.Thread: if (load) { return(new ThreadStartEvent { ThreadId = ReadPointer(), }); } else if (unload) { return(new ThreadEndEvent { ThreadId = ReadPointer(), }); } else { return(new ThreadNameEvent { ThreadId = ReadPointer(), Name = Reader.ReadCString(), }); } case LogMetadataType.Context: if (load) { return(new ContextLoadEvent { ContextId = ReadPointer(), AppDomainId = ReadPointer(), }); } else if (unload) { return(new ContextUnloadEvent { ContextId = ReadPointer(), AppDomainId = ReadPointer(), }); } else { throw new LogException("Invalid context metadata event."); } default: throw new LogException($"Invalid metadata type ({metadataType})."); } } case LogEventType.Method: switch (extType) { case LogEventType.MethodLeave: return(new LeaveEvent { MethodPointer = ReadMethod(), }); case LogEventType.MethodEnter: return(new EnterEvent { MethodPointer = ReadMethod(), }); case LogEventType.MethodLeaveExceptional: return(new ExceptionalLeaveEvent { MethodPointer = ReadMethod(), }); case LogEventType.MethodJit: return(new JitEvent { MethodPointer = ReadMethod(), CodePointer = ReadPointer(), CodeSize = (long)Reader.ReadULeb128(), Name = Reader.ReadCString(), }); default: throw new LogException($"Invalid extended event type ({extType})."); } case LogEventType.Exception: switch (extType) { case LogEventType.ExceptionThrowNoBacktrace: case LogEventType.ExceptionThrowBacktrace: return(new ThrowEvent { ObjectPointer = ReadObject(), Backtrace = ReadBacktrace(extType == LogEventType.ExceptionThrowBacktrace), }); case LogEventType.ExceptionClause: return(new ExceptionClauseEvent { Type = (LogExceptionClause)Reader.ReadByte(), Index = (long)Reader.ReadULeb128(), MethodPointer = ReadMethod(), ObjectPointer = ReadObject(), }); default: throw new LogException($"Invalid extended event type ({extType})."); } case LogEventType.Monitor: switch (extType) { case LogEventType.MonitorNoBacktrace: case LogEventType.MonitorBacktrace: return(new MonitorEvent { Event = (LogMonitorEvent)Reader.ReadByte(), ObjectPointer = ReadObject(), Backtrace = ReadBacktrace(extType == LogEventType.MonitorBacktrace), }); default: throw new LogException($"Invalid extended event type ({extType})."); } case LogEventType.Heap: switch (extType) { case LogEventType.HeapBegin: return(new HeapBeginEvent()); case LogEventType.HeapEnd: return(new HeapEndEvent()); case LogEventType.HeapObject: { var ev = new HeapObjectEvent { ObjectPointer = ReadObject(), ClassPointer = ReadPointer(), ObjectSize = (long)Reader.ReadULeb128(), }; var list = new HeapObjectEvent.HeapObjectReference [(int)Reader.ReadULeb128()]; for (var i = 0; i < list.Length; i++) { list [i] = new HeapObjectEvent.HeapObjectReference { Offset = (long)Reader.ReadULeb128(), ObjectPointer = ReadObject(), }; } ev.References = list; return(ev); } case LogEventType.HeapRoots: { // TODO: This entire event makes no sense. var ev = new HeapRootsEvent(); var list = new HeapRootsEvent.HeapRoot [(int)Reader.ReadULeb128()]; ev.MaxGenerationCollectionCount = (long)Reader.ReadULeb128(); for (var i = 0; i < list.Length; i++) { list [i] = new HeapRootsEvent.HeapRoot { ObjectPointer = ReadObject(), Attributes = (LogHeapRootAttributes)Reader.ReadByte(), ExtraInfo = (long)Reader.ReadULeb128(), }; } ev.Roots = list; return(ev); } default: throw new LogException($"Invalid extended event type ({extType})."); } case LogEventType.Sample: switch (extType) { case LogEventType.SampleHit: return(new SampleHitEvent { ThreadId = ReadPointer(), UnmanagedBacktrace = ReadBacktrace(true, false), ManagedBacktrace = ReadBacktrace(true), }); case LogEventType.SampleUnmanagedSymbol: return(new UnmanagedSymbolEvent { CodePointer = ReadPointer(), CodeSize = (long)Reader.ReadULeb128(), Name = Reader.ReadCString(), }); case LogEventType.SampleUnmanagedBinary: return(new UnmanagedBinaryEvent { SegmentPointer = ReadPointer(), SegmentOffset = (long)Reader.ReadULeb128(), SegmentSize = (long)Reader.ReadULeb128(), FileName = Reader.ReadCString(), }); case LogEventType.SampleCounterDescriptions: { var ev = new CounterDescriptionsEvent(); var list = new CounterDescriptionsEvent.CounterDescription [(int)Reader.ReadULeb128()]; for (var i = 0; i < list.Length; i++) { var section = (LogCounterSection)Reader.ReadULeb128(); list [i] = new CounterDescriptionsEvent.CounterDescription { Section = section, SectionName = section == LogCounterSection.User ? Reader.ReadCString() : string.Empty, CounterName = Reader.ReadCString(), Type = (LogCounterType)Reader.ReadByte(), Unit = (LogCounterUnit)Reader.ReadByte(), Variance = (LogCounterVariance)Reader.ReadByte(), Index = (long)Reader.ReadULeb128(), }; } ev.Descriptions = list; return(ev); } case LogEventType.SampleCounters: { var ev = new CounterSamplesEvent(); var list = new List <CounterSamplesEvent.CounterSample> (); while (true) { var index = (long)Reader.ReadULeb128(); if (index == 0) { break; } var counterType = (LogCounterType)Reader.ReadByte(); object value = null; switch (counterType) { case LogCounterType.String: value = Reader.ReadByte() == 1 ? Reader.ReadCString() : null; break; case LogCounterType.Int32: case LogCounterType.Word: case LogCounterType.Int64: case LogCounterType.Interval: value = Reader.ReadSLeb128(); break; case LogCounterType.UInt32: case LogCounterType.UInt64: value = Reader.ReadULeb128(); break; case LogCounterType.Double: value = Reader.ReadDouble(); break; default: throw new LogException($"Invalid counter type ({counterType})."); } list.Add(new CounterSamplesEvent.CounterSample { Index = index, Type = counterType, Value = value, }); } ev.Samples = list; return(ev); } default: throw new LogException($"Invalid extended event type ({extType})."); } case LogEventType.Runtime: switch (extType) { case LogEventType.RuntimeJitHelper: { var helperType = (LogJitHelper)Reader.ReadByte(); return(new JitHelperEvent { Type = helperType, BufferPointer = ReadPointer(), BufferSize = (long)Reader.ReadULeb128(), Name = helperType == LogJitHelper.SpecificTrampoline ? Reader.ReadCString() : string.Empty, }); } default: throw new LogException($"Invalid extended event type ({extType})."); } case LogEventType.Coverage: switch (extType) { case LogEventType.CoverageAssembly: return(new AssemblyCoverageEvent { AssemblyName = Reader.ReadCString(), Guid = Guid.Parse(Reader.ReadCString()), FileName = Reader.ReadCString(), NumberOfMethods = (long)Reader.ReadULeb128(), FullyCovered = (long)Reader.ReadULeb128(), PartiallyCovered = (long)Reader.ReadULeb128(), }); case LogEventType.CoverageMethod: return(new MethodCoverageEvent { AssemblyName = Reader.ReadCString(), ClassName = Reader.ReadCString(), MethodName = Reader.ReadCString(), MethodSignature = Reader.ReadCString(), FileName = Reader.ReadCString(), MetadataToken = Reader.ReadULeb128(), MethodId = (long)Reader.ReadULeb128(), NumberOfStatements = (long)Reader.ReadULeb128(), }); case LogEventType.CoverageStatement: return(new StatementCoverageEvent { MethodId = (long)Reader.ReadULeb128(), RelativeILOffset = (long)Reader.ReadULeb128(), Counter = Reader.ReadULeb128(), Line = (long)Reader.ReadULeb128(), Column = (long)Reader.ReadULeb128(), }); case LogEventType.CoverageClass: return(new ClassCoverageEvent { AssemblyName = Reader.ReadCString(), ClassName = Reader.ReadCString(), NumberOfMethods = (long)Reader.ReadULeb128(), FullyCovered = (long)Reader.ReadULeb128(), PartiallyCovered = (long)Reader.ReadULeb128(), }); default: throw new LogException($"Invalid extended event type ({extType})."); } case LogEventType.Meta: switch (extType) { case LogEventType.MetaSynchronizationPoint: return(new SynchronizationPointEvent { Type = (LogSynchronizationPoint)Reader.ReadByte(), }); default: throw new LogException($"Invalid extended event type ({extType})."); } default: throw new LogException($"Invalid basic event type ({basicType})."); } }
LogEvent ReadEvent() { var type = _reader.ReadByte(); var basicType = (LogEventType)(type & 0xf); var extType = (LogEventType)(type & 0xf0); _time = ReadTime(); LogEvent ev = null; switch (basicType) { case LogEventType.Allocation: switch (extType) { case LogEventType.AllocationBacktrace: case LogEventType.AllocationNoBacktrace: ev = new AllocationEvent { ClassPointer = StreamHeader.FormatVersion < 15 ? ReadPointer() : 0, VTablePointer = StreamHeader.FormatVersion >= 15 ? ReadPointer() : 0, ObjectPointer = ReadObject(), ObjectSize = (long)_reader.ReadULeb128(), Backtrace = ReadBacktrace(extType == LogEventType.AllocationBacktrace), }; break; default: throw new LogException($"Invalid extended event type ({extType})."); } break; case LogEventType.GC: switch (extType) { case LogEventType.GCEvent: ev = new GCEvent { Type = (LogGCEvent)_reader.ReadByte(), Generation = _reader.ReadByte(), }; break; case LogEventType.GCResize: ev = new GCResizeEvent { NewSize = (long)_reader.ReadULeb128(), }; break; case LogEventType.GCMove: { var list = new long [(int)_reader.ReadULeb128()]; for (var i = 0; i < list.Length; i++) { list [i] = ReadObject(); } ev = new GCMoveEvent { OldObjectPointers = list.Where((_, i) => i % 2 == 0).ToArray(), NewObjectPointers = list.Where((_, i) => i % 2 != 0).ToArray(), }; break; } case LogEventType.GCHandleCreationNoBacktrace: case LogEventType.GCHandleCreationBacktrace: ev = new GCHandleCreationEvent { Type = (LogGCHandleType)_reader.ReadULeb128(), Handle = (long)_reader.ReadULeb128(), ObjectPointer = ReadObject(), Backtrace = ReadBacktrace(extType == LogEventType.GCHandleCreationBacktrace), }; break; case LogEventType.GCHandleDeletionNoBacktrace: case LogEventType.GCHandleDeletionBacktrace: ev = new GCHandleDeletionEvent { Type = (LogGCHandleType)_reader.ReadULeb128(), Handle = (long)_reader.ReadULeb128(), Backtrace = ReadBacktrace(extType == LogEventType.GCHandleDeletionBacktrace), }; break; case LogEventType.GCFinalizeBegin: ev = new GCFinalizeBeginEvent(); break; case LogEventType.GCFinalizeEnd: ev = new GCFinalizeEndEvent(); break; case LogEventType.GCFinalizeObjectBegin: ev = new GCFinalizeObjectBeginEvent { ObjectPointer = ReadObject(), }; break; case LogEventType.GCFinalizeObjectEnd: ev = new GCFinalizeObjectEndEvent { ObjectPointer = ReadObject(), }; break; default: throw new LogException($"Invalid extended event type ({extType})."); } break; case LogEventType.Metadata: { var load = false; var unload = false; switch (extType) { case LogEventType.MetadataExtra: break; case LogEventType.MetadataEndLoad: load = true; break; case LogEventType.MetadataEndUnload: unload = true; break; default: throw new LogException($"Invalid extended event type ({extType})."); } var metadataType = (LogMetadataType)_reader.ReadByte(); switch (metadataType) { case LogMetadataType.Class: if (load) { ev = new ClassLoadEvent { ClassPointer = ReadPointer(), ImagePointer = ReadPointer(), Name = _reader.ReadCString(), }; } else { throw new LogException("Invalid class metadata event."); } break; case LogMetadataType.Image: if (load) { var ile = new ImageLoadEvent { ImagePointer = ReadPointer(), Name = _reader.ReadCString(), }; if (StreamHeader.FormatVersion >= 16) { var guid = _reader.ReadCString(); ile.ModuleVersionId = guid == string.Empty ? Guid.Empty : Guid.Parse(guid); } ev = ile; } else if (unload) { ev = new ImageUnloadEvent { ImagePointer = ReadPointer(), Name = _reader.ReadCString(), }; } else { throw new LogException("Invalid image metadata event."); } break; case LogMetadataType.Assembly: if (load) { ev = new AssemblyLoadEvent { AssemblyPointer = ReadPointer(), ImagePointer = StreamHeader.FormatVersion >= 14 ? ReadPointer() : 0, Name = _reader.ReadCString(), }; } else if (unload) { ev = new AssemblyUnloadEvent { AssemblyPointer = ReadPointer(), ImagePointer = StreamHeader.FormatVersion >= 14 ? ReadPointer() : 0, Name = _reader.ReadCString(), }; } else { throw new LogException("Invalid assembly metadata event."); } break; case LogMetadataType.AppDomain: if (load) { ev = new AppDomainLoadEvent { AppDomainId = ReadPointer(), }; } else if (unload) { ev = new AppDomainUnloadEvent { AppDomainId = ReadPointer(), }; } else { ev = new AppDomainNameEvent { AppDomainId = ReadPointer(), Name = _reader.ReadCString(), }; } break; case LogMetadataType.Thread: if (load) { ev = new ThreadStartEvent { ThreadId = ReadPointer(), }; } else if (unload) { ev = new ThreadEndEvent { ThreadId = ReadPointer(), }; } else { ev = new ThreadNameEvent { ThreadId = ReadPointer(), Name = _reader.ReadCString(), }; } break; case LogMetadataType.Context: if (load) { ev = new ContextLoadEvent { ContextId = ReadPointer(), AppDomainId = ReadPointer(), }; } else if (unload) { ev = new ContextUnloadEvent { ContextId = ReadPointer(), AppDomainId = ReadPointer(), }; } else { throw new LogException("Invalid context metadata event."); } break; case LogMetadataType.VTable: if (load) { ev = new VTableLoadEvent { VTablePointer = ReadPointer(), AppDomainId = ReadPointer(), ClassPointer = ReadPointer(), }; } else { throw new LogException("Invalid VTable metadata event."); } break; default: throw new LogException($"Invalid metadata type ({metadataType})."); } break; } case LogEventType.Method: switch (extType) { case LogEventType.MethodLeave: ev = new LeaveEvent { MethodPointer = ReadMethod(), }; break; case LogEventType.MethodEnter: ev = new EnterEvent { MethodPointer = ReadMethod(), }; break; case LogEventType.MethodLeaveExceptional: ev = new ExceptionalLeaveEvent { MethodPointer = ReadMethod(), }; break; case LogEventType.MethodJit: ev = new JitEvent { MethodPointer = ReadMethod(), CodePointer = ReadPointer(), CodeSize = (long)_reader.ReadULeb128(), Name = _reader.ReadCString(), }; break; default: throw new LogException($"Invalid extended event type ({extType})."); } break; case LogEventType.Exception: switch (extType) { case LogEventType.ExceptionThrowNoBacktrace: case LogEventType.ExceptionThrowBacktrace: ev = new ThrowEvent { ObjectPointer = ReadObject(), Backtrace = ReadBacktrace(extType == LogEventType.ExceptionThrowBacktrace), }; break; case LogEventType.ExceptionClause: ev = new ExceptionClauseEvent { Type = (LogExceptionClause)_reader.ReadByte(), Index = (long)_reader.ReadULeb128(), MethodPointer = ReadMethod(), ObjectPointer = StreamHeader.FormatVersion >= 14 ? ReadObject() : 0, }; break; default: throw new LogException($"Invalid extended event type ({extType})."); } break; case LogEventType.Monitor: if (StreamHeader.FormatVersion < 14) { if (extType.HasFlag(LogEventType.MonitorBacktrace)) { extType = LogEventType.MonitorBacktrace; } else { extType = LogEventType.MonitorNoBacktrace; } } switch (extType) { case LogEventType.MonitorNoBacktrace: case LogEventType.MonitorBacktrace: ev = new MonitorEvent { Event = StreamHeader.FormatVersion >= 14 ? (LogMonitorEvent)_reader.ReadByte() : (LogMonitorEvent)((((byte)type & 0xf0) >> 4) & 0x3), ObjectPointer = ReadObject(), Backtrace = ReadBacktrace(extType == LogEventType.MonitorBacktrace), }; break; default: throw new LogException($"Invalid extended event type ({extType})."); } break; case LogEventType.Heap: switch (extType) { case LogEventType.HeapBegin: ev = new HeapBeginEvent(); break; case LogEventType.HeapEnd: ev = new HeapEndEvent(); break; case LogEventType.HeapObject: { HeapObjectEvent hoe = new HeapObjectEvent { ObjectPointer = ReadObject(), ClassPointer = StreamHeader.FormatVersion < 15 ? ReadPointer() : 0, VTablePointer = StreamHeader.FormatVersion >= 15 ? ReadPointer() : 0, ObjectSize = (long)_reader.ReadULeb128(), Generation = StreamHeader.FormatVersion >= 16 ? _reader.ReadByte() : 0, }; var list = new HeapObjectEvent.HeapObjectReference [(int)_reader.ReadULeb128()]; for (var i = 0; i < list.Length; i++) { list [i] = new HeapObjectEvent.HeapObjectReference { Offset = (long)_reader.ReadULeb128(), ObjectPointer = ReadObject(), }; } hoe.References = list; ev = hoe; break; } case LogEventType.HeapRoots: { var hre = new HeapRootsEvent(); var list = new HeapRootsEvent.HeapRoot [(int)_reader.ReadULeb128()]; if (StreamHeader.FormatVersion < 15) { hre.MaxGenerationCollectionCount = (long)_reader.ReadULeb128(); } for (var i = 0; i < list.Length; i++) { list [i] = new HeapRootsEvent.HeapRoot { SlotPointer = StreamHeader.FormatVersion >= 15 ? ReadPointer() : 0, ObjectPointer = ReadObject(), Attributes = StreamHeader.FormatVersion < 15 ? (StreamHeader.FormatVersion == 13 ? (LogHeapRootAttributes)_reader.ReadByte() : (LogHeapRootAttributes)_reader.ReadULeb128()) : 0, ExtraInfo = StreamHeader.FormatVersion < 15 ? (long)_reader.ReadULeb128() : 0, }; } hre.Roots = list; ev = hre; break; } case LogEventType.HeapRootRegister: ev = new HeapRootRegisterEvent { RootPointer = ReadPointer(), RootSize = (long)_reader.ReadULeb128(), Source = (LogHeapRootSource)_reader.ReadByte(), Key = ReadPointer(), Name = _reader.ReadCString(), }; break; case LogEventType.HeapRootUnregister: ev = new HeapRootUnregisterEvent { RootPointer = ReadPointer(), }; break; default: throw new LogException($"Invalid extended event type ({extType})."); } break; case LogEventType.Sample: switch (extType) { case LogEventType.SampleHit: if (StreamHeader.FormatVersion < 14) { // Read SampleType (always set to .Cycles) for versions < 14 _reader.ReadByte(); } ev = new SampleHitEvent { ThreadId = ReadPointer(), UnmanagedBacktrace = ReadBacktrace(true, false), ManagedBacktrace = ReadBacktrace(true).Reverse().ToArray(), }; break; case LogEventType.SampleUnmanagedSymbol: ev = new UnmanagedSymbolEvent { CodePointer = ReadPointer(), CodeSize = (long)_reader.ReadULeb128(), Name = _reader.ReadCString(), }; break; case LogEventType.SampleUnmanagedBinary: ev = new UnmanagedBinaryEvent { SegmentPointer = StreamHeader.FormatVersion >= 14 ? ReadPointer() : _reader.ReadSLeb128(), SegmentOffset = (long)_reader.ReadULeb128(), SegmentSize = (long)_reader.ReadULeb128(), FileName = _reader.ReadCString(), }; break; case LogEventType.SampleCounterDescriptions: { var cde = new CounterDescriptionsEvent(); var list = new CounterDescriptionsEvent.CounterDescription [(int)_reader.ReadULeb128()]; for (var i = 0; i < list.Length; i++) { var section = (LogCounterSection)_reader.ReadULeb128(); list [i] = new CounterDescriptionsEvent.CounterDescription { Section = section, SectionName = section == LogCounterSection.User ? _reader.ReadCString() : null, CounterName = _reader.ReadCString(), Type = StreamHeader.FormatVersion < 15 ? (LogCounterType)_reader.ReadByte() : (LogCounterType)_reader.ReadULeb128(), Unit = StreamHeader.FormatVersion < 15 ? (LogCounterUnit)_reader.ReadByte() : (LogCounterUnit)_reader.ReadULeb128(), Variance = StreamHeader.FormatVersion < 15 ? (LogCounterVariance)_reader.ReadByte() : (LogCounterVariance)_reader.ReadULeb128(), Index = (long)_reader.ReadULeb128(), }; } cde.Descriptions = list; ev = cde; break; } case LogEventType.SampleCounters: { var cse = new CounterSamplesEvent(); var list = new List <CounterSamplesEvent.CounterSample> (); while (true) { var index = (long)_reader.ReadULeb128(); if (index == 0) { break; } var counterType = StreamHeader.FormatVersion < 15 ? (LogCounterType)_reader.ReadByte() : (LogCounterType)_reader.ReadULeb128(); object value = null; switch (counterType) { case LogCounterType.String: value = _reader.ReadByte() == 1 ? _reader.ReadCString() : null; break; case LogCounterType.Int32: case LogCounterType.Word: case LogCounterType.Int64: case LogCounterType.Interval: value = _reader.ReadSLeb128(); break; case LogCounterType.UInt32: case LogCounterType.UInt64: value = _reader.ReadULeb128(); break; case LogCounterType.Double: value = _reader.ReadDouble(); break; default: throw new LogException($"Invalid counter type ({counterType})."); } list.Add(new CounterSamplesEvent.CounterSample { Index = index, Type = counterType, Value = value, }); } cse.Samples = list; ev = cse; break; } default: throw new LogException($"Invalid extended event type ({extType})."); } break; case LogEventType.Runtime: switch (extType) { case LogEventType.RuntimeJitHelper: { var helperType = (LogJitHelper)_reader.ReadByte(); if (StreamHeader.FormatVersion < 14) { helperType--; } ev = new JitHelperEvent { Type = helperType, BufferPointer = ReadPointer(), BufferSize = (long)_reader.ReadULeb128(), Name = helperType == LogJitHelper.SpecificTrampoline ? _reader.ReadCString() : null, }; break; } default: throw new LogException($"Invalid extended event type ({extType})."); } break; case LogEventType.Meta: switch (extType) { case LogEventType.MetaSynchronizationPoint: ev = new SynchronizationPointEvent { Type = (LogSynchronizationPoint)_reader.ReadByte(), }; break; case LogEventType.MetaAotId: ev = new AotIdEvent { AotId = Guid.Parse(_reader.ReadCString()), }; break; default: throw new LogException($"Invalid extended event type ({extType})."); } break; default: throw new LogException($"Invalid basic event type ({basicType})."); } ev.Timestamp = _time; ev.Buffer = _bufferHeader; return(ev); }