Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- Deduplicate profiling stack frames ([#3941](https://github.com/getsentry/sentry-dotnet/pull/3941))
- OperatingSystem will now return macOS as OS name instead of 'Darwin' as well as the proper version. ([#2710](https://github.com/getsentry/sentry-dotnet/pull/3956))
- Ignore null value on CocoaScopeObserver.SetTag ([#3948](https://github.com/getsentry/sentry-dotnet/pull/3948))
- Unknown stack frames in profiles on .NET 8+ ([#3967](https://github.com/getsentry/sentry-dotnet/pull/3967))

## 5.1.0

Expand Down
18 changes: 10 additions & 8 deletions src/Sentry.Profiling/SampleProfilerSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ namespace Sentry.Profiling;
internal class SampleProfilerSession : IDisposable
{
private readonly EventPipeSession _session;
private readonly TraceLogEventSource _eventSource;
private readonly SampleProfilerTraceEventParser _sampleEventParser;
private readonly IDiagnosticLogger? _logger;
private readonly SentryStopwatch _stopwatch;
Expand All @@ -22,8 +21,8 @@ private SampleProfilerSession(SentryStopwatch stopwatch, EventPipeSession sessio
{
_session = session;
_logger = logger;
_eventSource = eventSource;
_sampleEventParser = new SampleProfilerTraceEventParser(_eventSource);
EventSource = eventSource;
_sampleEventParser = new SampleProfilerTraceEventParser(EventSource);
_stopwatch = stopwatch;
}

Expand All @@ -36,7 +35,7 @@ private SampleProfilerSession(SentryStopwatch stopwatch, EventPipeSession sessio
// Default = GC | Type | GCHeapSurvivalAndMovement | Binder | Loader | Jit | NGen | SupressNGen
// | StopEnumeration | Security | AppDomainResourceManagement | Exception | Threading | Contention | Stack | JittedMethodILToNativeMap
// | ThreadTransfer | GCHeapAndTypeNames | Codesymbols | Compilation,
new EventPipeProvider(ClrTraceEventParser.ProviderName, EventLevel.Informational, (long) ClrTraceEventParser.Keywords.Default),
new EventPipeProvider(ClrTraceEventParser.ProviderName, EventLevel.Verbose, (long) ClrTraceEventParser.Keywords.Default),
new EventPipeProvider(SampleProfilerTraceEventParser.ProviderName, EventLevel.Informational),
// new EventPipeProvider(TplEtwProviderTraceEventParser.ProviderName, EventLevel.Informational, (long) TplEtwProviderTraceEventParser.Keywords.Default)
};
Expand All @@ -46,11 +45,14 @@ private SampleProfilerSession(SentryStopwatch stopwatch, EventPipeSession sessio
// need a large buffer if we're connecting righ away. Leaving it too large increases app memory usage.
internal static int CircularBufferMB = 16;

// Exposed for tests
internal TraceLogEventSource EventSource { get; }

public SampleProfilerTraceEventParser SampleEventParser => _sampleEventParser;

public TimeSpan Elapsed => _stopwatch.Elapsed;

public TraceLog TraceLog => _eventSource.TraceLog;
public TraceLog TraceLog => EventSource.TraceLog;

// default is false, set 1 for true.
private static int _throwOnNextStartupForTests = 0;
Expand Down Expand Up @@ -108,15 +110,15 @@ public async Task WaitForFirstEventAsync(CancellationToken cancellationToken = d
{
var tcs = new TaskCompletionSource();
var cb = (TraceEvent _) => { tcs.TrySetResult(); };
_eventSource.AllEvents += cb;
EventSource.AllEvents += cb;
try
{
// Wait for the first event to be processed.
await tcs.Task.WaitAsync(cancellationToken).ConfigureAwait(false);
}
finally
{
_eventSource.AllEvents -= cb;
EventSource.AllEvents -= cb;
}
}

Expand All @@ -129,7 +131,7 @@ public void Stop()
_stopped = true;
_session.Stop();
_session.Dispose();
_eventSource.Dispose();
EventSource.Dispose();
}
catch (Exception ex)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.IO.Abstractions.TestingHelpers;
using Microsoft.Diagnostics.Tracing;
using Microsoft.Diagnostics.Tracing.Parsers.Clr;
using Sentry.Internal.Http;

namespace Sentry.Profiling.Tests;
Expand Down Expand Up @@ -180,6 +181,46 @@ public async Task Profiler_AfterTimeout_Stops()
}
}


/// <summary>
/// Guards regression of https://github.com/microsoft/perfview/issues/2155
/// </summary>
[SkippableFact]
public async Task EventPipeSession_ReceivesExpectedCLREvents()
{
SampleProfilerSession? session = null;
SkipIfFailsInCI(() => session = SampleProfilerSession.StartNew(_testOutputLogger));
using (session)
{
var eventsReceived = new HashSet<string>();
session!.EventSource.Clr.MethodLoadVerbose += (_) => eventsReceived.Add("Method/LoadVerbose");
session!.EventSource.Clr.MethodILToNativeMap += (_) => eventsReceived.Add("Method/ILToNativeMap");

await session.WaitForFirstEventAsync(CancellationToken.None);
var tries = 0;
while (eventsReceived.Count < 2 && tries++ < 10)
{
if (tries > 1)
{
await Task.Delay(100);
}
var limitMs = 50;
var sut = new SamplingTransactionProfiler(_testSentryOptions, session, limitMs, CancellationToken.None);
MethodToBeLoaded(100);
RunForMs(limitMs);
sut.Finish();
}

Assert.Contains("Method/LoadVerbose", eventsReceived);
Assert.Contains("Method/ILToNativeMap", eventsReceived);
}
}

private static long MethodToBeLoaded(int n)
{
return -n;
}

[SkippableTheory]
[InlineData(true)]
[InlineData(false)]
Expand Down
Loading