// <summary> // Starts the child process and returns the diagnostics client once the child proc connects to the reversed diagnostics pipe. // The callee needs to resume the diagnostics client at appropriate time. // </summary> public static DiagnosticsClient Build(ProcessLauncher childProcLauncher, string toolName, int timeoutInSec) { if (!childProcLauncher.HasChildProc) { throw new InvalidOperationException("Must have a valid child process to launch."); } // Create and start the reversed server string diagnosticTransportName = GetTransportName(toolName); ReversedDiagnosticsServer server = new ReversedDiagnosticsServer(diagnosticTransportName); server.Start(); // Start the child proc if (!childProcLauncher.Start(diagnosticTransportName)) { throw new InvalidOperationException("Failed to start dotnet-counters."); } // Wait for attach IpcEndpointInfo endpointInfo = server.Accept(TimeSpan.FromSeconds(timeoutInSec)); // If for some reason a different process attached to us, wait until the expected process attaches. while (endpointInfo.ProcessId != childProcLauncher.ChildProc.Id) { endpointInfo = server.Accept(TimeSpan.FromSeconds(timeoutInSec)); } return(new DiagnosticsClient(endpointInfo.Endpoint)); }
public async Task <DiagnosticsClientHolder> Build(CancellationToken ct, int processId, string portName, bool showChildIO, bool printLaunchCommand) { if (ProcessLauncher.Launcher.HasChildProc) { // Create and start the reversed server string diagnosticTransportName = GetTransportName(_toolName); ReversedDiagnosticsServer server = new ReversedDiagnosticsServer(diagnosticTransportName); server.Start(); // Start the child proc if (!ProcessLauncher.Launcher.Start(diagnosticTransportName, ct, showChildIO, printLaunchCommand)) { throw new InvalidOperationException($"Failed to start '{ProcessLauncher.Launcher.ChildProc.StartInfo.FileName} {ProcessLauncher.Launcher.ChildProc.StartInfo.Arguments}'."); } IpcEndpointInfo endpointInfo; try { // Wait for attach endpointInfo = server.Accept(TimeSpan.FromSeconds(_timeoutInSec)); // If for some reason a different process attached to us, wait until the expected process attaches. while (endpointInfo.ProcessId != ProcessLauncher.Launcher.ChildProc.Id) { endpointInfo = server.Accept(TimeSpan.FromSeconds(_timeoutInSec)); } } catch (TimeoutException) { Console.Error.WriteLine("Unable to start tracing session - the target app failed to connect to the diagnostics port. This may happen if the target application is running .NET Core 3.1 or older versions. Attaching at startup is only available from .NET 5.0 or later."); throw; } return(new DiagnosticsClientHolder(new DiagnosticsClient(endpointInfo.Endpoint), endpointInfo, server)); } else if (!string.IsNullOrEmpty(portName)) { ReversedDiagnosticsServer server = new ReversedDiagnosticsServer(portName); server.Start(); string fullPort = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? portName : Path.GetFullPath(portName); Console.WriteLine($"Waiting for connection on {fullPort}"); Console.WriteLine($"Start an application with the following environment variable: DOTNET_DiagnosticPorts={fullPort}"); IpcEndpointInfo endpointInfo = await server.AcceptAsync(ct); return(new DiagnosticsClientHolder(new DiagnosticsClient(endpointInfo.Endpoint), endpointInfo, fullPort, server)); } else { return(new DiagnosticsClientHolder(new DiagnosticsClient(processId))); } }