From a4cbd35f39cc3c9a99188ff885332820ad2f57ac Mon Sep 17 00:00:00 2001 From: Alexandre Mutel Date: Tue, 17 Dec 2024 08:00:58 +0100 Subject: [PATCH] Update native UltraNativeModuleTraceEvent with uuid --- .../Parser/UltraNativeCallstackTraceEvent.cs | 83 +++++++++ .../Parser/UltraNativeModuleTraceEvent.cs | 92 ++++++++++ .../UltraSamplerNativeModuleEventKind.cs | 2 +- src/Ultra.Core/Parser/UltraSamplerParser.cs | 158 +----------------- 4 files changed, 178 insertions(+), 157 deletions(-) create mode 100644 src/Ultra.Core/Parser/UltraNativeCallstackTraceEvent.cs create mode 100644 src/Ultra.Core/Parser/UltraNativeModuleTraceEvent.cs diff --git a/src/Ultra.Core/Parser/UltraNativeCallstackTraceEvent.cs b/src/Ultra.Core/Parser/UltraNativeCallstackTraceEvent.cs new file mode 100644 index 0000000..00a0081 --- /dev/null +++ b/src/Ultra.Core/Parser/UltraNativeCallstackTraceEvent.cs @@ -0,0 +1,83 @@ +// Copyright (c) Alexandre Mutel. All rights reserved. +// Licensed under the BSD-Clause 2 license. +// See license.txt file in the project root for full license information. + +using Microsoft.Diagnostics.Tracing; +using Ultra.Sampler; + +namespace Ultra.Core; + +internal sealed class UltraNativeCallstackTraceEvent : TraceEvent +{ + private static readonly string[] _payloadNames = + [ + nameof(FrameThreadId), + nameof(ThreadState), + nameof(ThreadCpuUsage), + nameof(PreviousFrameCount), + nameof(FrameSize), + nameof(FrameAddresses) + ]; + + private Action? _target; + + internal UltraNativeCallstackTraceEvent(Action? target, int eventID, int task, string taskName, Guid taskGuid, int opcode, string opcodeName, Guid providerGuid, string providerName) : base(eventID, task, taskName, taskGuid, opcode, opcodeName, providerGuid, providerName) + { + _target = target; + } + + public ulong FrameThreadId => (ulong)GetInt64At(0); + + public UltraSamplerThreadState ThreadState => (UltraSamplerThreadState)GetInt32At(8); + + public double ThreadCpuUsage => GetInt32At(12) / 1000.0; + + public int PreviousFrameCount => GetInt32At(16); + + public int FrameSize => GetInt32At(20); + + public unsafe ReadOnlySpan FrameAddresses => new((byte*)DataStart + 24, FrameSize / sizeof(ulong)); + + /// + + public override object PayloadValue(int index) + { + switch (index) + { + case 0: + return FrameThreadId; + case 1: + return (int)ThreadState; + case 2: + return GetInt32At(12); + case 3: + return PreviousFrameCount; + case 4: + return FrameSize; + case 5: + return FrameAddresses.ToArray(); + default: + throw new ArgumentOutOfRangeException(nameof(index)); + } + } + + public override string[] PayloadNames => _payloadNames; + + /// + protected override Delegate? Target + { + get => _target; + set => _target = (Action?)value; + } + + /// + protected override void Dispatch() + { + _target?.Invoke(this); + } + + /// + protected override void Validate() + { + } +} \ No newline at end of file diff --git a/src/Ultra.Core/Parser/UltraNativeModuleTraceEvent.cs b/src/Ultra.Core/Parser/UltraNativeModuleTraceEvent.cs new file mode 100644 index 0000000..8ae6e33 --- /dev/null +++ b/src/Ultra.Core/Parser/UltraNativeModuleTraceEvent.cs @@ -0,0 +1,92 @@ +// Copyright (c) Alexandre Mutel. All rights reserved. +// Licensed under the BSD-Clause 2 license. +// See license.txt file in the project root for full license information. + +using System.Text; +using Microsoft.Diagnostics.Tracing; + +namespace Ultra.Core; + +internal sealed class UltraNativeModuleTraceEvent : TraceEvent +{ + private static readonly string[] _payloadNames = + [ + nameof(NativeModuleEventKind), + nameof(LoadAddress), + nameof(Size), + nameof(TimestampUtc), + nameof(Uuid), + nameof(ModulePathUtf8Length), + nameof(ModulePath) + ]; + + private Action? _target; + + internal UltraNativeModuleTraceEvent(Action? target, int eventID, int task, string taskName, Guid taskGuid, int opcode, string opcodeName, Guid providerGuid, string providerName) : base(eventID, task, taskName, taskGuid, opcode, opcodeName, + providerGuid, + providerName) + { + _target = target; + } + + public UltraSamplerNativeModuleEventKind NativeModuleEventKind => (UltraSamplerNativeModuleEventKind)GetInt32At(0); + + public ulong LoadAddress => (ulong)GetInt64At(4); + + public ulong Size => (ulong)GetInt64At(12); + + public DateTime TimestampUtc => DateTime.FromFileTimeUtc(GetInt64At(20)); + + public unsafe Guid Uuid => *(Guid*)(DataStart + 28); + + public unsafe int ModulePathUtf8Length => GetInt32At(44); + + public unsafe ReadOnlySpan ModulePathUtf8 => ModulePathUtf8Length == 0 ? ReadOnlySpan.Empty : new((byte*)DataStart + 48, ModulePathUtf8Length); + + public unsafe string? ModulePath => ModulePathUtf8Length == 0 ? null : Encoding.UTF8.GetString(ModulePathUtf8); + + /// + public override object? PayloadValue(int index) + { + switch (index) + { + case 0: + return (int)NativeModuleEventKind; + case 1: + return LoadAddress; + case 2: + return Size; + case 3: + return TimestampUtc; + case 4: + return Uuid; + case 5: + return ModulePathUtf8Length; + case 6: + return ModulePathUtf8.ToArray(); + default: + throw new ArgumentOutOfRangeException(nameof(index)); + } + } + + /// + public override string[] PayloadNames => _payloadNames; + + /// + protected override Delegate? Target + { + get => _target; + set => _target = (Action?)value; + } + + /// + protected override void Dispatch() + { + _target?.Invoke(this); + } + + /// + protected override void Validate() + { + } +} \ No newline at end of file diff --git a/src/Ultra.Core/Parser/UltraSamplerNativeModuleEventKind.cs b/src/Ultra.Core/Parser/UltraSamplerNativeModuleEventKind.cs index fc53b77..12e3bc6 100644 --- a/src/Ultra.Core/Parser/UltraSamplerNativeModuleEventKind.cs +++ b/src/Ultra.Core/Parser/UltraSamplerNativeModuleEventKind.cs @@ -4,7 +4,7 @@ namespace Ultra.Core; -public enum UltraSamplerNativeModuleEventKind +internal enum UltraSamplerNativeModuleEventKind { AlreadyLoaded = 0, diff --git a/src/Ultra.Core/Parser/UltraSamplerParser.cs b/src/Ultra.Core/Parser/UltraSamplerParser.cs index 8705407..70861c7 100644 --- a/src/Ultra.Core/Parser/UltraSamplerParser.cs +++ b/src/Ultra.Core/Parser/UltraSamplerParser.cs @@ -2,13 +2,13 @@ // Licensed under the BSD-Clause 2 license. // See license.txt file in the project root for full license information. -using System.Text; +using System.Runtime.CompilerServices; using Microsoft.Diagnostics.Tracing; using Ultra.Sampler; namespace Ultra.Core; -public sealed class UltraSamplerParser : TraceEventParser +internal sealed class UltraSamplerParser : TraceEventParser { public static readonly Guid ProviderGuid = UltraSamplerConstants.ProviderGuid; @@ -61,158 +61,4 @@ private static TraceEvent CreateUltraNativeCallstackTraceEvent(Action? value) => new UltraNativeModuleTraceEvent(value, UltraSamplerConstants.NativeModuleEventId, 0, "OnNativeModule", Guid.Empty, 0, "OnNativeModule", ProviderGuid, ProviderName); -} - -public sealed class UltraNativeCallstackTraceEvent : TraceEvent -{ - private static readonly string[] _payloadNames = - [ - nameof(FrameThreadId), - nameof(ThreadState), - nameof(ThreadCpuUsage), - nameof(PreviousFrameCount), - nameof(FrameSize), - nameof(FrameAddresses) - ]; - - private Action? _target; - - internal UltraNativeCallstackTraceEvent(Action? target, int eventID, int task, string taskName, Guid taskGuid, int opcode, string opcodeName, Guid providerGuid, string providerName) : base(eventID, task, taskName, taskGuid, opcode, opcodeName, providerGuid, providerName) - { - _target = target; - } - - public ulong FrameThreadId => (ulong)GetInt64At(0); - - public UltraSamplerThreadState ThreadState => (UltraSamplerThreadState)GetInt32At(8); - - public double ThreadCpuUsage => GetInt32At(12) / 1000.0; - - public int PreviousFrameCount => GetInt32At(16); - - public int FrameSize => GetInt32At(20); - - public unsafe ReadOnlySpan FrameAddresses => new((byte*)DataStart + 24, FrameSize / sizeof(ulong)); - - /// - - public override object PayloadValue(int index) - { - switch (index) - { - case 0: - return FrameThreadId; - case 1: - return (int)ThreadState; - case 2: - return GetInt32At(12); - case 3: - return PreviousFrameCount; - case 4: - return FrameSize; - case 5: - return FrameAddresses.ToArray(); - default: - throw new ArgumentOutOfRangeException(nameof(index)); - } - } - - public override string[] PayloadNames => _payloadNames; - - /// - protected override Delegate? Target - { - get => _target; - set => _target = (Action?)value; - } - - /// - protected override void Dispatch() - { - _target?.Invoke(this); - } - - /// - protected override void Validate() - { - } -} - -public sealed class UltraNativeModuleTraceEvent : TraceEvent -{ - private static readonly string[] _payloadNames = - [ - nameof(NativeModuleEventKind), - nameof(LoadAddress), - nameof(Size), - nameof(TimestampUtc), - nameof(ModulePathUtf8Length), - nameof(ModulePath) - ]; - - private Action? _target; - - internal UltraNativeModuleTraceEvent(Action? target, int eventID, int task, string taskName, Guid taskGuid, int opcode, string opcodeName, Guid providerGuid, string providerName) : base(eventID, task, taskName, taskGuid, opcode, opcodeName, - providerGuid, - providerName) - { - _target = target; - } - - public UltraSamplerNativeModuleEventKind NativeModuleEventKind => (UltraSamplerNativeModuleEventKind)GetInt32At(0); - - public ulong LoadAddress => (ulong)GetInt64At(4); - - public ulong Size => (ulong)GetInt64At(12); - - public DateTime TimestampUtc => DateTime.FromFileTimeUtc(GetInt64At(20)); - - private int ModulePathUtf8Length => GetInt32At(28); - - private unsafe ReadOnlySpan ModulePathUtf8 => ModulePathUtf8Length == 0 ? ReadOnlySpan.Empty : new((byte*)DataStart + 32, ModulePathUtf8Length); - - public unsafe string? ModulePath => ModulePathUtf8Length == 0 ? null : Encoding.UTF8.GetString(ModulePathUtf8); - - /// - public override object? PayloadValue(int index) - { - switch (index) - { - case 0: - return (int)NativeModuleEventKind; - case 1: - return LoadAddress; - case 2: - return Size; - case 3: - return TimestampUtc; - case 4: - return ModulePathUtf8Length; - case 5: - return ModulePathUtf8.ToArray(); - default: - throw new ArgumentOutOfRangeException(nameof(index)); - } - } - - /// - public override string[] PayloadNames => _payloadNames; - - /// - protected override Delegate? Target - { - get => _target; - set => _target = (Action?)value; - } - - /// - protected override void Dispatch() - { - _target?.Invoke(this); - } - - /// - protected override void Validate() - { - } } \ No newline at end of file