diff --git a/src/FastSerialization/FastSerialization.cs b/src/FastSerialization/FastSerialization.cs index bcc2e4c5e..c508d58e5 100644 --- a/src/FastSerialization/FastSerialization.cs +++ b/src/FastSerialization/FastSerialization.cs @@ -9,7 +9,8 @@ using System.Diagnostics; using System.IO; using System.Text; // For StringBuilder. - +using System.Runtime.InteropServices; +using System.Buffers.Binary; // see #Introduction and #SerializerIntroduction namespace FastSerialization { @@ -184,6 +185,10 @@ interface IStreamWriter : IDisposable /// void Write(int value); /// + /// Write an blob to a stream + /// + void WriteBlobAsInt(int value); + /// /// Write a long to a stream /// void Write(long value); @@ -590,7 +595,6 @@ public Serializer(IStreamWriter writer, IFastSerializable entryObject) Log(""); // Write the header. Write("!FastSerialization.1"); - // Write the main object. This is recursive and does most of the work. Write(entryObject); @@ -675,6 +679,14 @@ public void Write(int value) writer.Write(value); } /// + /// Write an blob to a stream + /// + public void WriteBlobAsInt(int value) + { + Log(""); + writer.WriteBlobAsInt(value); + } + /// /// Write a long to a stream /// public void Write(long value) @@ -688,7 +700,15 @@ public void Write(long value) public void Write(Guid value) { Log(""); - byte[] bytes = value.ToByteArray(); + Span bytes = value.ToByteArray(); + + if (!BitConverter.IsLittleEndian) + { + BinaryPrimitives.WriteInt32LittleEndian(bytes.Slice(0), (MemoryMarshal.Read(bytes.Slice(0,4)))); + BinaryPrimitives.WriteInt16LittleEndian(bytes.Slice(4), (MemoryMarshal.Read(bytes.Slice(4,6)))); + BinaryPrimitives.WriteInt16LittleEndian(bytes.Slice(6), (MemoryMarshal.Read(bytes.Slice(6,8)))); + } + for (int i = 0; i < bytes.Length; i++) { writer.Write(bytes[i]); @@ -1591,7 +1611,7 @@ public StreamLabel ResolveForwardReference(ForwardReference reference, bool pres reader.GotoSuffixLabel(); Log(""); StreamLabel forwardRefsLabel = reader.ReadLabel(); - + Goto(forwardRefsLabel); int fowardRefCount = reader.ReadInt32(); Log(" + + + + diff --git a/src/FastSerialization/StreamReaderWriter.cs b/src/FastSerialization/StreamReaderWriter.cs index 5c3b8b376..68eed0099 100644 --- a/src/FastSerialization/StreamReaderWriter.cs +++ b/src/FastSerialization/StreamReaderWriter.cs @@ -8,6 +8,7 @@ using System.Diagnostics; using System.IO; using System.Text; // For StringBuilder. +using System.Buffers.Binary; namespace FastSerialization { @@ -328,6 +329,7 @@ public void Write(byte value) /// public unsafe void Write(short value) { + value = BinaryPrimitives.ReadInt16LittleEndian(BitConverter.GetBytes(value)); if (endPosition + sizeof(short) > bytes.Length) { MakeSpace(); @@ -344,6 +346,24 @@ public unsafe void Write(short value) /// Implementation of IStreamWriter /// public unsafe void Write(int value) + { + value = BinaryPrimitives.ReadInt32LittleEndian(BitConverter.GetBytes(value)); + if (endPosition + sizeof(int) > bytes.Length) + { + MakeSpace(); + } + + fixed (byte* data = bytes) + { + *(int*)(data + endPosition) = value; + } + + endPosition += sizeof(int); + } + /// + /// Write an blob to a stream + /// + public unsafe void WriteBlobAsInt(int value) { if (endPosition + sizeof(int) > bytes.Length) { @@ -362,6 +382,7 @@ public unsafe void Write(int value) /// public unsafe void Write(long value) { + value = BinaryPrimitives.ReadInt64LittleEndian(BitConverter.GetBytes(value)); if (endPosition + sizeof(long) > bytes.Length) { MakeSpace(); diff --git a/src/TraceEvent/EventPipe/RewindableStream.cs b/src/TraceEvent/EventPipe/RewindableStream.cs index 40431e0e9..4474d77dd 100644 --- a/src/TraceEvent/EventPipe/RewindableStream.cs +++ b/src/TraceEvent/EventPipe/RewindableStream.cs @@ -5,7 +5,7 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - +using System.Buffers.Binary; namespace Microsoft.Diagnostics.Tracing.EventPipe { @@ -60,6 +60,40 @@ public T Read() where T : struct { Span buffer = stackalloc byte[Unsafe.SizeOf()]; Read(buffer); + if (!BitConverter.IsLittleEndian) + { + if(typeof(T) == typeof(short)) + { + short val = BinaryPrimitives.ReadInt16LittleEndian(buffer); + return (T)(object)val; + } + else if(typeof(T) == typeof(int)) + { + int val = BinaryPrimitives.ReadInt32LittleEndian(buffer); + return (T)(object)val; + } + else if(typeof(T) == typeof(long)) + { + long val = BinaryPrimitives.ReadInt64LittleEndian(buffer); + return (T)(object)val; + } + else if(typeof(T) == typeof(ushort)) + { + ushort val = BinaryPrimitives.ReadUInt16LittleEndian(buffer); + return (T)(object)val; + } + else if(typeof(T) == typeof(uint)) + { + uint val = BinaryPrimitives.ReadUInt32LittleEndian(buffer); + return (T)(object)val; + } + else if(typeof(T) == typeof(ulong)) + { + ulong val = BinaryPrimitives.ReadUInt64LittleEndian(buffer); + return (T)(object)val; + } + + } return MemoryMarshal.Read(buffer); } diff --git a/src/TraceEvent/EventPipe/SpanReader.cs b/src/TraceEvent/EventPipe/SpanReader.cs index 3a0cf90cf..f8b99e83d 100644 --- a/src/TraceEvent/EventPipe/SpanReader.cs +++ b/src/TraceEvent/EventPipe/SpanReader.cs @@ -2,7 +2,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; - +using System.Buffers.Binary; namespace Microsoft.Diagnostics.Tracing.EventPipe { ref struct SpanReader @@ -21,12 +21,90 @@ public SpanReader(ReadOnlySpan buffer, long spanStartStreamOffset) public sbyte ReadInt8() => Read(); public byte ReadUInt8() => Read(); - public short ReadInt16() => Read(); - public ushort ReadUInt16() => Read(); - public int ReadInt32() => Read(); - public uint ReadUInt32() => Read(); - public long ReadInt64() => Read(); - public ulong ReadUInt64() => Read(); + + public short ReadInt16() + { + short val; + if (BinaryPrimitives.TryReadInt16LittleEndian(_buffer, out val)) + { + _buffer = _buffer.Slice(sizeof(short)); + } + else + { + ThrowFormatException(); + } + return val; + } + + public ushort ReadUInt16() + { + ushort val; + if (BinaryPrimitives.TryReadUInt16LittleEndian(_buffer, out val)) + { + _buffer = _buffer.Slice(sizeof(ushort)); + } + else + { + ThrowFormatException(); + } + return val; + } + + public int ReadInt32() + { + int val; + if (BinaryPrimitives.TryReadInt32LittleEndian(_buffer, out val)) + { + _buffer = _buffer.Slice(sizeof(int)); + } + else + { + ThrowFormatException(); + } + return val; + } + + public uint ReadUInt32() + { + uint val; + if (BinaryPrimitives.TryReadUInt32LittleEndian(_buffer, out val)) + { + _buffer = _buffer.Slice(sizeof(uint)); + } + else + { + ThrowFormatException(); + } + return val; + } + + public long ReadInt64() + { + long val; + if (BinaryPrimitives.TryReadInt64LittleEndian(_buffer, out val)) + { + _buffer = _buffer.Slice(sizeof(long)); + } + else + { + ThrowFormatException(); + } + return val; + } + + public ulong ReadUInt64() + { + ulong val; + if (BinaryPrimitives.TryReadUInt64LittleEndian(_buffer, out val)) + { + _buffer = _buffer.Slice(sizeof(ulong)); + } + else + { + ThrowFormatException(); + } + return val; + } public T Read() where T : struct { @@ -156,7 +234,17 @@ public string ReadVarUIntUTF8String() public string ReadNullTerminatedUTF16String() { - ReadOnlySpan charBuffer = MemoryMarshal.Cast(_buffer); + + ReadOnlySpan Buffer = MemoryMarshal.Cast(_buffer); + Span charBuffer = stackalloc char [Buffer.Length]; + Buffer.CopyTo(charBuffer); + if (!BitConverter.IsLittleEndian) + { + for(int ii = 0; ii < charBuffer.Length; ii++) + { + charBuffer[ii] = (char)BinaryPrimitives.ReverseEndianness((ushort)charBuffer[ii]); + } + } for(int i = 0; i < charBuffer.Length; i++) { if (charBuffer[i] == 0) diff --git a/src/TraceEvent/Parsers/ClrTraceEventParser.cs b/src/TraceEvent/Parsers/ClrTraceEventParser.cs index c28710c0f..9d034931d 100644 --- a/src/TraceEvent/Parsers/ClrTraceEventParser.cs +++ b/src/TraceEvent/Parsers/ClrTraceEventParser.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; +using System.Buffers.Binary; using Address = System.UInt64; // This file was generated with the following command: @@ -4788,11 +4789,28 @@ public sealed class GCBulkNodeTraceData : TraceEvent buffer->TypeID = value->TypeID; buffer->EdgeCount = value->EdgeCount; ret = buffer; + + if (!BitConverter.IsLittleEndian) + { + ret->Address = BinaryPrimitives.ReadUInt32LittleEndian(BitConverter.GetBytes(ret->Address)); + ret->Size = BinaryPrimitives.ReadUInt64LittleEndian(BitConverter.GetBytes(ret->Size)); + ret->TypeID = BinaryPrimitives.ReadUInt64LittleEndian(BitConverter.GetBytes(ret->TypeID)); + ret->EdgeCount = BinaryPrimitives.ReadInt64LittleEndian(BitConverter.GetBytes(ret->EdgeCount)); + } + } else { GCBulkNodeUnsafeNodes* basePtr = (GCBulkNodeUnsafeNodes*)(((byte*)DataStart) + 10); ret = basePtr + arrayIdx; + + if (!BitConverter.IsLittleEndian) + { + ret->Address = BinaryPrimitives.ReadUInt64LittleEndian(BitConverter.GetBytes(ret->Address)); + ret->Size = BinaryPrimitives.ReadUInt64LittleEndian(BitConverter.GetBytes(ret->Size)); + ret->TypeID = BinaryPrimitives.ReadUInt64LittleEndian(BitConverter.GetBytes(ret->TypeID)); + ret->EdgeCount = BinaryPrimitives.ReadInt64LittleEndian(BitConverter.GetBytes(ret->EdgeCount)); + } } Debug.Assert((ret->Address & 0xFF00000000000003L) == 0); Debug.Assert((ret->TypeID & 0xFF00000000000001L) == 0); diff --git a/src/TraceEvent/TraceEvent.cs b/src/TraceEvent/TraceEvent.cs index 921f3747c..43b71571b 100644 --- a/src/TraceEvent/TraceEvent.cs +++ b/src/TraceEvent/TraceEvent.cs @@ -17,8 +17,9 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; -using Address = System.UInt64; +using System.Buffers.Binary; +using Address = System.UInt64; // #Introduction // // Note that TraceEvent lives in a Nuget package. See @@ -3693,7 +3694,7 @@ internal TraceEvent Lookup(TraceEventNativeMethods.EVENT_RECORD* eventRecord) // calculate the hash, and look it up in the table please note that this was hand // inlined, and is replicated in TraceEventDispatcher.Insert - int* guidPtr = (int*)&eventRecord->EventHeader.ProviderId; // This is the taskGuid for Classic events. + int* guidPtr = (int*)&eventRecord->EventHeader.ProviderId; // This is the taskGuid for Classic events. int hash = (*guidPtr + eventID * 9) & templatesLengthMask; for (; ; ) { @@ -4598,15 +4599,15 @@ internal static unsafe float ReadSingle(IntPtr pointer, int offset) } internal static unsafe long ReadInt64(IntPtr pointer, int offset) { - return Unsafe.ReadUnaligned((byte*)pointer.ToPointer() + offset); + return BinaryPrimitives.ReadInt64LittleEndian(BitConverter.GetBytes(Unsafe.ReadUnaligned((byte*)pointer.ToPointer() + offset))); } internal static unsafe int ReadInt32(IntPtr pointer, int offset) { - return Unsafe.ReadUnaligned((byte*)pointer.ToPointer() + offset); + return BinaryPrimitives.ReadInt32LittleEndian(BitConverter.GetBytes(Unsafe.ReadUnaligned((byte*)pointer.ToPointer() + offset))); } internal static unsafe short ReadInt16(IntPtr pointer, int offset) { - return *((short*)((byte*)pointer.ToPointer() + offset)); + return BinaryPrimitives.ReadInt16LittleEndian(BitConverter.GetBytes(*((short*)((byte*)pointer.ToPointer() + offset)))); } internal static unsafe IntPtr ReadIntPtr(IntPtr pointer, int offset) { @@ -4649,7 +4650,26 @@ internal static unsafe string ReadUnicodeString(IntPtr pointer, int offset, int // Really we should be able to count on pointers being null terminated. However we have had instances // where this is not true. To avoid scanning the string twice we first check if the last character // in the buffer is a 0 if so, we KNOW we can use the 'fast path' Otherwise we check - byte* ptr = (byte*)pointer; + byte* ptr = (byte*)pointer; + char* charStart = (char*)(ptr + offset); + int maxPos = (bufferLength - offset) / sizeof(char); + int curPos = 0; + if(!BitConverter.IsLittleEndian) + { + char *temp = stackalloc char[maxPos]; + while(curPos < maxPos) + { + char ch = (char)BinaryPrimitives.ReverseEndianness((ushort)charStart[curPos]); + if (ch == 0) + break; + + temp[curPos] = ch; + curPos++; + + } + return new string(temp, 0, curPos); + } + char* charEnd = (char*)(ptr + bufferLength); if (charEnd[-1] == 0) // Is the last character a null? { @@ -4659,14 +4679,11 @@ internal static unsafe string ReadUnicodeString(IntPtr pointer, int offset, int // but who cares as long as it stays in the buffer. // unoptimized path. Carefully count characters and create a string up to the null. - char* charStart = (char*)(ptr + offset); - int maxPos = (bufferLength - offset) / sizeof(char); - int curPos = 0; while (curPos < maxPos && charStart[curPos] != 0) { curPos++; } - // CurPos now points at the end (either buffer end or null terminator, make just the right sized string. + // CurPos now points at the end (either buffer end or null terminator, make just the right sized string. return new string(charStart, 0, curPos); } internal static unsafe string ReadUTF8String(IntPtr pointer, int offset, int bufferLength) diff --git a/src/TraceEvent/TraceEvent.csproj b/src/TraceEvent/TraceEvent.csproj index c8abab7f6..259ea4a2f 100644 --- a/src/TraceEvent/TraceEvent.csproj +++ b/src/TraceEvent/TraceEvent.csproj @@ -77,6 +77,7 @@ + diff --git a/src/TraceEvent/TraceEventSession.cs b/src/TraceEvent/TraceEventSession.cs index 3e1cb624b..2d17130da 100644 --- a/src/TraceEvent/TraceEventSession.cs +++ b/src/TraceEvent/TraceEventSession.cs @@ -3112,6 +3112,10 @@ public static string GetProviderName(Guid providerGuid) public static unsafe bool MaybeAnEventSource(Guid providerGuid) { byte octet7 = ((byte*)(&providerGuid))[7]; + if (!BitConverter.IsLittleEndian) + { + octet7 = ((byte*)(&providerGuid))[6]; + } if ((octet7 & 0xF0) == 0x50) { return true; diff --git a/src/TraceEvent/TraceLog.cs b/src/TraceEvent/TraceLog.cs index f397c03bb..b0ca7f164 100644 --- a/src/TraceEvent/TraceLog.cs +++ b/src/TraceEvent/TraceLog.cs @@ -23,6 +23,7 @@ using Microsoft.Diagnostics.Tracing.Utilities; using Microsoft.Diagnostics.Utilities; using System; +using System.Buffers.Binary; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.Tracing; @@ -36,7 +37,6 @@ using System.Threading.Tasks; using Address = System.UInt64; - namespace Microsoft.Diagnostics.Tracing.Etlx { /// @@ -2343,8 +2343,22 @@ private unsafe void CopyRawEvents(TraceEventDispatcher rawEvents, IStreamWriter } unsafe { - Debug.Assert(data.eventRecord->EventHeader.TimeStamp < long.MaxValue); - WriteBlob((IntPtr)data.eventRecord, writer, headerSize); + if (!BitConverter.IsLittleEndian) + { + Span buffer = stackalloc byte[headerSize]; + new Span(data.eventRecord, headerSize).CopyTo(buffer); + SwapEventRecordEndianness(buffer); + fixed (byte* bufferPtr = buffer) + { + WriteBlob((IntPtr)bufferPtr, writer, headerSize); + } + } + else + { + Debug.Assert(data.eventRecord->EventHeader.TimeStamp < long.MaxValue); + WriteBlob((IntPtr)data.eventRecord, writer, headerSize); + } + WriteBlob(data.userData, writer, (data.EventDataLength + 3 & ~3)); } numberOnPage++; @@ -3458,11 +3472,68 @@ private static unsafe void WriteBlob(IntPtr source, IStreamWriter writer, int by int intCount = byteCount >> 2; while (intCount > 0) { - writer.Write(*sourcePtr++); + writer.WriteBlobAsInt(*sourcePtr++); --intCount; } } + private static void SwapEventRecordEndianness(Span buffer) + { + int offset = 0; + buffer.Slice(offset, 2).Reverse(); + offset += 2; // Size (UInt16) + buffer.Slice(offset, 2).Reverse(); + offset += 2; // HeaderType (UInt16) + buffer.Slice(offset, 2).Reverse(); + offset += 2; // Flags (UInt16) + buffer.Slice(offset, 2).Reverse(); + offset += 2; // EventProperty (UInt16) + buffer.Slice(offset, 4).Reverse(); + offset += 4; // ThreadId (Int32) + buffer.Slice(offset, 4).Reverse(); + offset += 4; // ProcessId (Int32) + buffer.Slice(offset, 8).Reverse(); + offset += 8; // TimeStamp (Int64) + + // ProviderId GUID (16 bytes) - swap first 3 components only + buffer.Slice(offset, 4).Reverse(); + offset += 4; // Data1 (Int32) + buffer.Slice(offset, 2).Reverse(); + offset += 2; // Data2 (Int16) + buffer.Slice(offset, 2).Reverse(); + offset += 10; // Data3 (Int16) + Data4 (8 bytes) - unchanged + + buffer.Slice(offset, 2).Reverse(); + offset += 6; // Id (UInt16) + Version, Channel, Level, Opcode (4 single bytes) + buffer.Slice(offset, 2).Reverse(); + offset += 2; // Task (UInt16) + buffer.Slice(offset, 8).Reverse(); + offset += 8; // Keyword (UInt64) + buffer.Slice(offset, 4).Reverse(); + offset += 4; // KernelTime (UInt32) + buffer.Slice(offset, 4).Reverse(); + offset += 4; // UserTime (UInt32) + + // ActivityId GUID (16 bytes) - swap first 3 components only + buffer.Slice(offset, 4).Reverse(); + offset += 4; // Data1 (Int32) + buffer.Slice(offset, 2).Reverse(); + offset += 2; // Data2 (Int16) + buffer.Slice(offset, 2).Reverse(); + offset += 12; // Data3 (Int16) + Data4 (8 bytes) - unchanged + ProcessorNumber, Alignment (2 single bytes) + buffer.Slice(offset, 2).Reverse(); + offset += 2; // LoggerId (UInt16) + + buffer.Slice(offset, 2).Reverse(); + offset += 2; // ExtendedDataCount (UInt16) + buffer.Slice(offset, 2).Reverse(); + offset += 2; // UserDataLength (UInt16) + buffer.Slice(offset, 8).Reverse(); + offset += 8; // ExtendedData (pointer - UInt64) + buffer.Slice(offset, 8).Reverse(); + offset += 8; // UserData (pointer - UInt64) + } + // [Conditional("DEBUG")] internal void DebugWarn(bool condition, string message, TraceEvent data) { @@ -3588,7 +3659,7 @@ internal unsafe void SeekToTimeOnPage(PinnedStreamReader reader, long timeQPC, i Debug.Assert(ptr->EventHeader.Level <= 6); Debug.Assert(ptr->EventHeader.Version <= 10); - long eventTimeQPC = ptr->EventHeader.TimeStamp; + long eventTimeQPC = BinaryPrimitives.ReadInt64LittleEndian(BitConverter.GetBytes(ptr->EventHeader.TimeStamp)); Debug.Assert(sessionStartTimeQPC <= eventTimeQPC && eventTimeQPC < DateTime.Now.Ticks || eventTimeQPC == long.MaxValue); if (eventTimeQPC >= timeQPC) @@ -5329,6 +5400,39 @@ public void Reset() protected unsafe TraceEvent GetNext() { TraceEventNativeMethods.EVENT_RECORD* ptr = (TraceEventNativeMethods.EVENT_RECORD*)reader.GetPointer(TraceLog.headerSize); + if (!BitConverter.IsLittleEndian) + { + ptr->EventHeader.Size = BinaryPrimitives.ReadUInt16LittleEndian(BitConverter.GetBytes(ptr->EventHeader.Size)); + ptr->EventHeader.HeaderType = BinaryPrimitives.ReadUInt16LittleEndian(BitConverter.GetBytes(ptr->EventHeader.HeaderType)); + ptr->EventHeader.Flags = BinaryPrimitives.ReadUInt16LittleEndian(BitConverter.GetBytes(ptr->EventHeader.Flags)); + ptr->EventHeader.EventProperty = BinaryPrimitives.ReadUInt16LittleEndian(BitConverter.GetBytes(ptr->EventHeader.EventProperty)); + ptr->EventHeader.ThreadId = BinaryPrimitives.ReadInt32LittleEndian(BitConverter.GetBytes(ptr->EventHeader.ThreadId)); + ptr->EventHeader.ProcessId = BinaryPrimitives.ReadInt32LittleEndian(BitConverter.GetBytes(ptr->EventHeader.ProcessId)); + ptr->EventHeader.TimeStamp = BinaryPrimitives.ReadInt64LittleEndian(BitConverter.GetBytes(ptr->EventHeader.TimeStamp)); + ptr->EventHeader.Id = BinaryPrimitives.ReadUInt16LittleEndian(BitConverter.GetBytes(ptr->EventHeader.Id)); + ptr->EventHeader.Task = BinaryPrimitives.ReadUInt16LittleEndian(BitConverter.GetBytes(ptr->EventHeader.Task)); + ptr->EventHeader.Keyword = BinaryPrimitives.ReadUInt64LittleEndian(BitConverter.GetBytes(ptr->EventHeader.Keyword)); + ptr->EventHeader.KernelTime = BinaryPrimitives.ReadUInt32LittleEndian(BitConverter.GetBytes(ptr->EventHeader.KernelTime)); + ptr->EventHeader.UserTime = BinaryPrimitives.ReadUInt32LittleEndian(BitConverter.GetBytes(ptr->EventHeader.UserTime)); + + Span guidarr = stackalloc byte[16]; + + guidarr = ptr->EventHeader.ProviderId.ToByteArray(); + BinaryPrimitives.WriteInt32LittleEndian(guidarr.Slice(0), (MemoryMarshal.Read(guidarr.Slice(0,4)))); + BinaryPrimitives.WriteInt16LittleEndian(guidarr.Slice(4), (MemoryMarshal.Read(guidarr.Slice(4,6)))); + BinaryPrimitives.WriteInt16LittleEndian(guidarr.Slice(6), (MemoryMarshal.Read(guidarr.Slice(6,8)))); + ptr->EventHeader.ProviderId = new Guid(guidarr.ToArray()); + + guidarr = ptr->EventHeader.ActivityId.ToByteArray(); + BinaryPrimitives.WriteInt32LittleEndian(guidarr.Slice(0), (MemoryMarshal.Read(guidarr.Slice(0,4)))); + BinaryPrimitives.WriteInt16LittleEndian(guidarr.Slice(4), (MemoryMarshal.Read(guidarr.Slice(4,6)))); + BinaryPrimitives.WriteInt16LittleEndian(guidarr.Slice(6), (MemoryMarshal.Read(guidarr.Slice(6,8)))); + ptr->EventHeader.ActivityId = new Guid(guidarr.ToArray()); + + ptr->UserDataLength = BinaryPrimitives.ReadUInt16LittleEndian(BitConverter.GetBytes(ptr->UserDataLength)); + ptr->UserData = (IntPtr)BinaryPrimitives.ReadUInt64LittleEndian(BitConverter.GetBytes((ulong)ptr->UserData)); + ptr->UserContext = (IntPtr)BinaryPrimitives.ReadUInt64LittleEndian(BitConverter.GetBytes((ulong)ptr->UserContext)); + } TraceEvent ret = lookup.Lookup(ptr); // We use the first item in the linked list in 'ret'. This should always be the 'best' way of decoding @@ -7853,12 +7957,11 @@ internal unsafe CallStackIndex GetStackIndexForStackEvent(void* addresses, GetStackIndexForStackEvent64((ulong*)addresses, addressCount, thread.Process, start) : GetStackIndexForStackEvent32((uint*)addresses, addressCount, thread.Process, start); } - private unsafe CallStackIndex GetStackIndexForStackEvent32(uint* addresses, int addressCount, TraceProcess process, CallStackIndex start) { for (var it = &addresses[addressCount]; it-- != addresses;) { - CodeAddressIndex codeAddress = codeAddresses.GetOrCreateCodeAddressIndex(process, *it); + CodeAddressIndex codeAddress = codeAddresses.GetOrCreateCodeAddressIndex(process, BinaryPrimitives.ReadUInt32LittleEndian(BitConverter.GetBytes((uint)(*it)))); start = InternCallStackIndex(codeAddress, start); } @@ -7869,7 +7972,7 @@ private unsafe CallStackIndex GetStackIndexForStackEvent64(ulong* addresses, int { for (var it = &addresses[addressCount]; it-- != addresses;) { - CodeAddressIndex codeAddress = codeAddresses.GetOrCreateCodeAddressIndex(process, *it); + CodeAddressIndex codeAddress = codeAddresses.GetOrCreateCodeAddressIndex(process, BinaryPrimitives.ReadUInt64LittleEndian(BitConverter.GetBytes((ulong)(*it)))); start = InternCallStackIndex(codeAddress, start); }