From 0dbd59ae85e460f5b21b461d01c973b2c55e38e2 Mon Sep 17 00:00:00 2001 From: Alexandre Mutel Date: Mon, 16 Dec 2024 18:53:34 +0100 Subject: [PATCH] Fix compressed frames --- src/Ultra.Sampler/MacOS/MacOSUltraSampler.cs | 16 ++++++++-------- src/Ultra.Sampler/UltraSamplerSource.cs | 16 +++++++++++----- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/Ultra.Sampler/MacOS/MacOSUltraSampler.cs b/src/Ultra.Sampler/MacOS/MacOSUltraSampler.cs index 48ba412..96dd4f9 100644 --- a/src/Ultra.Sampler/MacOS/MacOSUltraSampler.cs +++ b/src/Ultra.Sampler/MacOS/MacOSUltraSampler.cs @@ -19,7 +19,7 @@ internal unsafe class MacOSUltraSampler : UltraSampler private Thread? _samplerThread; private ulong _samplerThreadId; private readonly AutoResetEvent _samplerResumeThreadEvent; - + // Frames information private const int MaximumFrames = 4096; private readonly ulong[] _frames; // 32 KB @@ -366,7 +366,6 @@ private unsafe void Sample(MacOS.MacOSLibSystem.mach_port_t rootTask, NativeSamp // Compute the same frame count var sameFrameCount = ComputeSameFrameCount(threadInfo.thread_id, frameCount, pFrames); frameCount -= sameFrameCount; - pFrames += sameFrameCount; // Long only the delta frames samplingDelegate(threadInfo.thread_id, (int)threadExtendedInfo.pth_run_state, (int)threadExtendedInfo.pth_cpu_usage, sameFrameCount, frameCount * sizeof(ulong), (byte*)pFrames); @@ -387,9 +386,10 @@ private unsafe void Sample(MacOS.MacOSLibSystem.mach_port_t rootTask, NativeSamp // Swap the active and current thread ids (_currentThreadIds, _activeThreadIds) = (_activeThreadIds, _currentThreadIds); } - + private int ComputeSameFrameCount(ulong threadId, int frameCount, ulong* frames) { + int originalFrameCount = frameCount; // We limit the frame recording to MaximumCompressedFrameCount frameCount = Math.Min(frameCount, MaximumCompressedFrameCount); @@ -421,10 +421,10 @@ private int ComputeSameFrameCount(ulong threadId, int frameCount, ulong* frames) int previousFrameCount = (int)previousFrame; previousFrame = ref Unsafe.Add(ref previousFrame, 1); - var minFrameCount = Math.Min(previousFrameCount, frameCount); - for (; sameFrameCount < minFrameCount; sameFrameCount++) + var maxFrameCount = Math.Min(previousFrameCount, frameCount); + for (; sameFrameCount < maxFrameCount; sameFrameCount++) { - if (frames[sameFrameCount] != previousFrame) + if (frames[originalFrameCount - sameFrameCount - 1] != previousFrame) { break; } @@ -439,9 +439,9 @@ private int ComputeSameFrameCount(ulong threadId, int frameCount, ulong* frames) previousFrame = ref Unsafe.Add(ref previousFrame, 1); for (int i = 0; i < frameCount; i++) { - Unsafe.Add(ref previousFrame, i) = frames[i]; + Unsafe.Add(ref previousFrame, i) = frames[originalFrameCount - i - 1]; } - + return sameFrameCount; } diff --git a/src/Ultra.Sampler/UltraSamplerSource.cs b/src/Ultra.Sampler/UltraSamplerSource.cs index 31236e5..db2fb4a 100644 --- a/src/Ultra.Sampler/UltraSamplerSource.cs +++ b/src/Ultra.Sampler/UltraSamplerSource.cs @@ -21,14 +21,20 @@ private UltraSamplerSource() [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "")] public unsafe void NativeCallstack(ulong threadId, int threadState, int threadCpuUsage, int previousFrameCount, int framesSize, byte* frames) // frames is last to allow perfview to visualize previous fixed size arguments and also, it is an ulong otherwise the EventSource will silently fail to register! { - var evt = stackalloc EventData[3]; + var evt = stackalloc EventData[6]; evt[0].DataPointer = (nint)(void*)&threadId; evt[0].Size = sizeof(ulong); - evt[1].DataPointer = (nint)(void*)&framesSize; + evt[1].DataPointer = (nint)(void*)&threadState; evt[1].Size = sizeof(int); - evt[2].DataPointer = (nint)(void*)&frames; - evt[2].Size = framesSize; - WriteEventCore(UltraSamplerConstants.NativeCallStackEventId, 3, evt); + evt[2].DataPointer = (nint)(void*)&threadCpuUsage; + evt[2].Size = sizeof(int); + evt[3].DataPointer = (nint)(void*)&previousFrameCount; + evt[3].Size = sizeof(int); + evt[4].DataPointer = (nint)(void*)&framesSize; + evt[4].Size = sizeof(int); + evt[5].DataPointer = (nint)(void*)frames; + evt[5].Size = framesSize; + WriteEventCore(UltraSamplerConstants.NativeCallStackEventId, 6, evt); } [Event(UltraSamplerConstants.NativeModuleEventId, Level = EventLevel.Informational, Task = (EventTask)UltraSamplerConstants.TaskNativeModuleEventId)]