Skip to content

Commit 69b76b3

Browse files
committed
Fix connect
1 parent 5fcf716 commit 69b76b3

File tree

2 files changed

+56
-48
lines changed

2 files changed

+56
-48
lines changed

src/Ultra.Core/DiagnosticPortSession.cs

+55-47
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Diagnostics;
66
using System.Diagnostics.CodeAnalysis;
77
using System.Diagnostics.Tracing;
8-
using System.Net.Sockets;
98
using Microsoft.Diagnostics.NETCore.Client;
109
using Microsoft.Diagnostics.Tracing.Parsers;
1110
using Ultra.Sampler;
@@ -37,8 +36,8 @@ public DiagnosticPortSession(int pid, bool sampler, string baseName, Cancellatio
3736
_sampler = sampler;
3837
_baseName = baseName;
3938
_cancelConnectSource = new CancellationTokenSource();
40-
_semaphoreSlim = new SemaphoreSlim(0);
41-
_connectTask = ConnectAndStartProfilingImpl(pid, sampler, baseName, token);
39+
_semaphoreSlim = new SemaphoreSlim(1);
40+
_connectTask = ConnectAndStartProfilingImpl(token);
4241
}
4342

4443
public bool TryGetNettraceFilePathIfExists([NotNullWhen(true)] out string? nettraceFilePath)
@@ -53,20 +52,20 @@ public bool TryGetNettraceFilePathIfExists([NotNullWhen(true)] out string? nettr
5352
return nettraceFilePath is not null;
5453
}
5554

56-
private async Task ConnectAndStartProfilingImpl(int pid, bool sampler, string baseName, CancellationToken token)
55+
private async Task ConnectAndStartProfilingImpl(CancellationToken token)
5756
{
5857
CancellationTokenSource linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token, _cancelConnectSource.Token);
5958
try
6059
{
61-
60+
6261
var connectCancellationToken = linkedCancellationTokenSource.Token;
6362

64-
if (sampler)
63+
if (_sampler)
6564
{
6665
_cancelConnectSource.CancelAfter(500);
6766
}
6867

69-
var connectionAddress = await TryFindConnectionAddress(pid, sampler, connectCancellationToken).ConfigureAwait(false);
68+
var connectionAddress = await TryFindConnectionAddress(_pid, _sampler, connectCancellationToken).ConfigureAwait(false);
7069
if (connectionAddress is null) return;
7170

7271
_diagnosticsClient = (await DiagnosticsClientConnector.FromDiagnosticPort(connectionAddress, connectCancellationToken).ConfigureAwait(false))?.Instance;
@@ -76,9 +75,9 @@ private async Task ConnectAndStartProfilingImpl(int pid, bool sampler, string ba
7675
}
7776
catch (OperationCanceledException ex)
7877
{
79-
if (sampler && _cancelConnectSource is not null && _cancelConnectSource.IsCancellationRequested)
78+
if (_sampler && _cancelConnectSource is not null && _cancelConnectSource.IsCancellationRequested)
8079
{
81-
throw new InvalidOperationException($"Cannot connect to the diagnostic port socket for pid {pid}", ex);
80+
throw new InvalidOperationException($"Cannot connect to the diagnostic port socket for pid {_pid}", ex);
8281
}
8382
return;
8483
}
@@ -91,7 +90,9 @@ private async Task ConnectAndStartProfilingImpl(int pid, bool sampler, string ba
9190
public async Task StartProfiling(CancellationToken token)
9291
{
9392
// We want to make sure that we are not disposing while we are starting a session
93+
Console.WriteLine($"Before entering Start/Lock for {(_sampler?"sampler":"clr")}");
9494
await _semaphoreSlim.WaitAsync(token);
95+
Console.WriteLine($"After entering Start/Lock for {(_sampler?"sampler":"clr")}");
9596

9697
try
9798
{
@@ -102,9 +103,12 @@ public async Task StartProfiling(CancellationToken token)
102103

103104
_profilingTask = _connectTask.ContinueWith(async task =>
104105
{
106+
if (task.IsFaulted)
107+
{
108+
return;
109+
}
105110

106-
107-
_nettraceFilePath = Path.Combine(Environment.CurrentDirectory, $"{_baseName}_{(_sampler ? "sampler" : "clr")}_{_pid}.nettrace");
111+
_nettraceFilePath = Path.Combine(Environment.CurrentDirectory, $"{_baseName}_{_pid}_{(_sampler ? "sampler" : "clr")}.nettrace");
108112
_nettraceFileStream = new FileStream(_nettraceFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, 65536, FileOptions.Asynchronous);
109113

110114
long keywords = -1;
@@ -143,11 +147,11 @@ public async Task StartProfiling(CancellationToken token)
143147

144148
public long GetNettraceFileLength() => _nettraceFileStream?.Length ?? 0;
145149

146-
public async Task WaitForConnectAndStartSession()
150+
public async Task WaitForConnect()
147151
{
148152
await _connectTask.ConfigureAwait(false);
149153
}
150-
154+
151155
private static async Task<string?> TryFindConnectionAddress(int pid, bool sampler, CancellationToken token)
152156
{
153157
var tempFolder = Path.GetTempPath();
@@ -186,15 +190,16 @@ public async Task WaitForConnectAndStartSession()
186190

187191
// Let's increase the delay after each check to lower the overhead
188192
waitForNextCheckDelayInMs += 10;
189-
waitForNextCheckDelayInMs = Math.Max(waitForNextCheckDelayInMs, 100);
193+
waitForNextCheckDelayInMs = Math.Min(waitForNextCheckDelayInMs, 100);
190194
}
191195

192196
return diagnosticPortSocket;
193197
}
194198

195199
public async ValueTask StopAndDisposeAsync()
196200
{
197-
// We want to make sure that we are not disposing while we are connecting
201+
// We want to make sure that we are not disposing while we are connecting/trying to start a session
202+
// (This could happen if we are trying to profile a non .NET process with the CLR provider)
198203
await _semaphoreSlim.WaitAsync(CancellationToken.None);
199204

200205
try
@@ -208,54 +213,57 @@ public async ValueTask StopAndDisposeAsync()
208213
{
209214
try
210215
{
216+
await _connectTask.ConfigureAwait(false);
217+
211218
// We wait for the session to start (we will close it right after below
212219
await _profilingTask.ConfigureAwait(false);
213220
}
214-
catch
221+
catch (Exception ex)
215222
{
223+
Console.WriteLine($"Error while waiting for profiling {_baseName} {(_sampler?"sampler":"clr")} to finish: {ex}");
216224
// Ignore
217225
}
218-
}
219226

220-
Debug.Assert(_eventStreamCopyTask is not null);
221-
try
222-
{
223-
await _eventStreamCopyTask.ConfigureAwait(false);
224-
}
225-
catch
226-
{
227-
// Ignore
228-
}
227+
Debug.Assert(_eventStreamCopyTask is not null);
228+
try
229+
{
230+
await _eventStreamCopyTask.ConfigureAwait(false);
231+
}
232+
catch
233+
{
234+
// Ignore
235+
}
229236

230-
Debug.Assert(_nettraceFileStream is not null);
231-
try
232-
{
233-
await _nettraceFileStream.DisposeAsync().ConfigureAwait(false);
234-
}
235-
catch
236-
{
237-
// Ignore
238-
}
237+
Debug.Assert(_nettraceFileStream is not null);
238+
try
239+
{
240+
await _nettraceFileStream.DisposeAsync().ConfigureAwait(false);
241+
}
242+
catch
243+
{
244+
// Ignore
245+
}
239246

240-
Debug.Assert(_eventPipeSession is not null);
241-
try
242-
{
243-
await _eventPipeSession.StopAsync(CancellationToken.None).ConfigureAwait(false);
244-
}
245-
catch
246-
{
247-
// Ignore
248-
}
249-
finally
250-
{
247+
Debug.Assert(_eventPipeSession is not null);
251248
try
252249
{
253-
_eventPipeSession.Dispose();
250+
await _eventPipeSession.StopAsync(CancellationToken.None).ConfigureAwait(false);
254251
}
255252
catch
256253
{
257254
// Ignore
258255
}
256+
finally
257+
{
258+
try
259+
{
260+
_eventPipeSession.Dispose();
261+
}
262+
catch
263+
{
264+
// Ignore
265+
}
266+
}
259267
}
260268
}
261269
finally

src/Ultra.Core/UltraProfilerEventPipe.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ public long TotalFileLength()
130130

131131
public async Task StartProfiling()
132132
{
133-
await _samplerSession.WaitForConnectAndStartSession();
133+
await _samplerSession.WaitForConnect();
134134

135135
await _samplerSession.StartProfiling(_token);
136136
await _clrSession.StartProfiling(_token);

0 commit comments

Comments
 (0)