diff --git a/src/Directory.Build.props b/src/Directory.Build.props index a63860aea1..5638357c5c 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -4,7 +4,7 @@ - true + Sentry Team and Contributors Sentry.io diff --git a/src/Sentry.Profiling/Downsampler.cs b/src/Sentry.Profiling/Downsampler.cs index 1580231a3b..c20d9e254b 100644 --- a/src/Sentry.Profiling/Downsampler.cs +++ b/src/Sentry.Profiling/Downsampler.cs @@ -1,30 +1,30 @@ -/// -/// Reduce sampling rate from 1 Hz that is the default for the provider to the configured SamplingRateMs. -/// -internal class Downsampler -{ - private static double _samplingRateMs = (double)1_000 / 101; // 101 Hz - - // Maps from ThreadIndex to the last sample timestamp for that thread. - private GrowableArray _prevThreadSamples = new(10); - - public void NewThreadAdded(int threadIndex) - { - if (threadIndex >= _prevThreadSamples.Count) - { - _prevThreadSamples.Count = threadIndex + 1; - _prevThreadSamples[threadIndex] = double.MinValue; - } - } - - public bool ShouldSample(int threadIndex, double timestampMs) - { - Debug.Assert(threadIndex < _prevThreadSamples.Count, "ThreadIndex too large - you must call NewThreadAdded() if a new thread is added."); - if (_prevThreadSamples[threadIndex] + _samplingRateMs <= timestampMs) - { - _prevThreadSamples[threadIndex] = timestampMs; - return true; - } - return false; - } -} +// /// +// /// Reduce sampling rate from 1 Hz that is the default for the provider to the configured SamplingRateMs. +// /// +// internal class Downsampler +// { +// private static double _samplingRateMs = (double)1_000 / 101; // 101 Hz +// +// // Maps from ThreadIndex to the last sample timestamp for that thread. +// private GrowableArray _prevThreadSamples = new(10); +// +// public void NewThreadAdded(int threadIndex) +// { +// if (threadIndex >= _prevThreadSamples.Count) +// { +// _prevThreadSamples.Count = threadIndex + 1; +// _prevThreadSamples[threadIndex] = double.MinValue; +// } +// } +// +// public bool ShouldSample(int threadIndex, double timestampMs) +// { +// Debug.Assert(threadIndex < _prevThreadSamples.Count, "ThreadIndex too large - you must call NewThreadAdded() if a new thread is added."); +// if (_prevThreadSamples[threadIndex] + _samplingRateMs <= timestampMs) +// { +// _prevThreadSamples[threadIndex] = timestampMs; +// return true; +// } +// return false; +// } +// } diff --git a/src/Sentry.Profiling/SampleProfileBuilder.cs b/src/Sentry.Profiling/SampleProfileBuilder.cs index 56927be4a9..fbf4ca88a6 100644 --- a/src/Sentry.Profiling/SampleProfileBuilder.cs +++ b/src/Sentry.Profiling/SampleProfileBuilder.cs @@ -30,7 +30,7 @@ internal class SampleProfileBuilder private readonly Dictionary _threadIndexes = new(); // TODO make downsampling conditional once this is available: https://github.com/dotnet/runtime/issues/82939 - private readonly Downsampler _downsampler = new(); + // private readonly Downsampler _downsampler = new(); public SampleProfileBuilder(SentryOptions options, TraceLog traceLog) { @@ -61,10 +61,10 @@ internal void AddSample(TraceEvent data, double timestampMs) return; } - if (!_downsampler.ShouldSample(threadIndex, timestampMs)) - { - return; - } + // if (!_downsampler.ShouldSample(threadIndex, timestampMs)) + // { + // return; + // } var stackIndex = AddStackTrace(callStackIndex); if (stackIndex < 0) @@ -204,7 +204,7 @@ private int AddThread(TraceThread thread) }); value = Profile.Threads.Count - 1; _threadIndexes[key] = value; - _downsampler.NewThreadAdded(_threadIndexes[key]); + // _downsampler.NewThreadAdded(_threadIndexes[key]); } return value; diff --git a/src/Sentry.Profiling/Sentry.Profiling.csproj b/src/Sentry.Profiling/Sentry.Profiling.csproj index c453876242..3da1ff8be9 100644 --- a/src/Sentry.Profiling/Sentry.Profiling.csproj +++ b/src/Sentry.Profiling/Sentry.Profiling.csproj @@ -31,9 +31,9 @@ - + - + diff --git a/src/Sentry/ISpanData.cs b/src/Sentry/ISpanData.cs index 55c1dd80c1..9a4ea133b3 100644 --- a/src/Sentry/ISpanData.cs +++ b/src/Sentry/ISpanData.cs @@ -63,10 +63,6 @@ public static void SetMeasurement(this ISpanData spanData, string name, long val spanData.SetMeasurement(name, new Measurement(value, unit)); /// -#if !__MOBILE__ - // ulong parameter is not CLS compliant - [CLSCompliant(false)] -#endif public static void SetMeasurement(this ISpanData spanData, string name, ulong value, MeasurementUnit unit = default) => spanData.SetMeasurement(name, new Measurement(value, unit)); diff --git a/src/Sentry/Sentry.csproj b/src/Sentry/Sentry.csproj index f5d358f8bc..b39667c75a 100644 --- a/src/Sentry/Sentry.csproj +++ b/src/Sentry/Sentry.csproj @@ -3,7 +3,6 @@ Official SDK for Sentry - Open-source error tracking that helps developers monitor and fix crashes in real time. $(NoWarn);RS0017 - true true @@ -50,7 +49,42 @@ - + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Sentry/SentryOptions.cs b/src/Sentry/SentryOptions.cs index ceab5113bc..6117111afa 100644 --- a/src/Sentry/SentryOptions.cs +++ b/src/Sentry/SentryOptions.cs @@ -1199,9 +1199,6 @@ public bool JsonPreserveReferences /// /// This is for Sentry use only, and can change without a major version bump. /// -#if !__MOBILE__ - [CLSCompliant(false)] -#endif [EditorBrowsable(EditorBrowsableState.Never)] public Func? AssemblyReader { get; set; } diff --git a/test/Sentry.Profiling.Tests/SamplingTransactionProfilerTests.cs b/test/Sentry.Profiling.Tests/SamplingTransactionProfilerTests.cs index c5aa9a83ed..f2633c9b49 100644 --- a/test/Sentry.Profiling.Tests/SamplingTransactionProfilerTests.cs +++ b/test/Sentry.Profiling.Tests/SamplingTransactionProfilerTests.cs @@ -445,13 +445,13 @@ public void ProfilerIntegration_WithProfilingEnabled_SetsFactory() [SkippableFact] public void Downsampler_ShouldSample_Works() { - var sut = new Downsampler(); - sut.NewThreadAdded(0); - Assert.True(sut.ShouldSample(0, 5)); - Assert.False(sut.ShouldSample(0, 3)); - Assert.False(sut.ShouldSample(0, 6)); - Assert.True(sut.ShouldSample(0, 15)); - Assert.False(sut.ShouldSample(0, 6)); - Assert.False(sut.ShouldSample(0, 16)); + // var sut = new Downsampler(); + // sut.NewThreadAdded(0); + // Assert.True(sut.ShouldSample(0, 5)); + // Assert.False(sut.ShouldSample(0, 3)); + // Assert.False(sut.ShouldSample(0, 6)); + // Assert.True(sut.ShouldSample(0, 15)); + // Assert.False(sut.ShouldSample(0, 6)); + // Assert.False(sut.ShouldSample(0, 16)); } } diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt index 97dac16884..9a955816d4 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt @@ -1,5 +1,4 @@ -[assembly: System.CLSCompliant(true)] -namespace Sentry +namespace Sentry { public enum AttachmentType { @@ -663,7 +662,6 @@ namespace Sentry public class SentryOptions { public SentryOptions() { } - [System.CLSCompliant(false)] public System.Func? AssemblyReader { get; set; } public bool AttachStacktrace { get; set; } public bool AutoSessionTracking { get; set; } @@ -1060,7 +1058,6 @@ namespace Sentry public static void SetMeasurement(this Sentry.ISpanData spanData, string name, double value, Sentry.MeasurementUnit unit = default) { } public static void SetMeasurement(this Sentry.ISpanData spanData, string name, int value, Sentry.MeasurementUnit unit = default) { } public static void SetMeasurement(this Sentry.ISpanData spanData, string name, long value, Sentry.MeasurementUnit unit = default) { } - [System.CLSCompliant(false)] public static void SetMeasurement(this Sentry.ISpanData spanData, string name, ulong value, Sentry.MeasurementUnit unit = default) { } } public static class SpanExtensions diff --git a/test/Sentry.Tests/MemDumpTests.cs b/test/Sentry.Tests/MemDumpTests.cs new file mode 100644 index 0000000000..b07944e5c8 --- /dev/null +++ b/test/Sentry.Tests/MemDumpTests.cs @@ -0,0 +1,59 @@ +#if NET8_0_OR_GREATER +using Graphs; +using Microsoft.Diagnostics.Utilities; + +namespace Sentry.Tests; + +public class MemDumpTests +{ + // private readonly ITestOutputHelper _testOutputHelper; + // private readonly IDiagnosticLogger _testOutputLogger; + + // public MemDumpTests(ITestOutputHelper output, ITestOutputHelper testOutputHelper) + // { + // _testOutputHelper = testOutputHelper; + // _testOutputLogger = new TestOutputDiagnosticLogger(output); + // } + + [Fact] + public void MemDump_Tests() + { + var path = "/Users/bruno/git/ConsoleApp1/ConsoleApp1/ConsoleApp1/20250526_133030_1.gcdump"; + var dump = new GCHeapDump(path); + var graph = dump.MemoryGraph; + Console.WriteLine(dump.CreationTool); + Console.WriteLine(dump.CollectionLog); + var ret = new Graph.SizeAndCount[(int)graph.NodeTypeIndexLimit]; + for (int i = 0; i < ret.Length; i++) + { + ret[i] = new Graph.SizeAndCount((NodeTypeIndex)i); + } + + var nodeStorage = graph.AllocNodeStorage(); + for (NodeIndex idx = 0; idx < graph.NodeIndexLimit; idx++) + { + var node = graph.GetNode(idx, nodeStorage); + var sizeAndCount = ret[(int)node.TypeIndex]; + sizeAndCount.Count++; + sizeAndCount.Size += node.Size; + } + + Array.Sort(ret, (Graph.SizeAndCount x, Graph.SizeAndCount y) => y.Size.CompareTo(x.Size)); + Console.WriteLine("", dump.MemoryGraph.TotalSize, (int)dump.MemoryGraph.NodeIndexLimit); + var typeStorage = new NodeType(graph); + var sizeAndCounts = graph.GetHistogramByType(); + long minSize = 0; + foreach (var sizeAndCount in sizeAndCounts) + { + if (sizeAndCount.Size <= minSize) + { + break; + } + + var line = string.Format("Name=\"{0}\" Size=\"{1}\" Count=\"{2}\"", + graph.GetType(sizeAndCount.TypeIdx, typeStorage).Name, sizeAndCount.Size, sizeAndCount.Count); + Console.WriteLine(line); + } + } +} +#endif