diff --git a/src/Microsoft.Diagnostics.NETCore.Client/Microsoft.Diagnostics.NETCore.Client.csproj b/src/Microsoft.Diagnostics.NETCore.Client/Microsoft.Diagnostics.NETCore.Client.csproj index bac47ff0f0..1f5414270e 100644 --- a/src/Microsoft.Diagnostics.NETCore.Client/Microsoft.Diagnostics.NETCore.Client.csproj +++ b/src/Microsoft.Diagnostics.NETCore.Client/Microsoft.Diagnostics.NETCore.Client.csproj @@ -37,6 +37,7 @@ + diff --git a/src/Tools/dotnet-dump/Dumper.cs b/src/Tools/dotnet-dump/Dumper.cs index 8f2407c1d9..f9b0362b57 100644 --- a/src/Tools/dotnet-dump/Dumper.cs +++ b/src/Tools/dotnet-dump/Dumper.cs @@ -31,32 +31,14 @@ public Dumper() { } - public int Collect(TextWriter stdOutput, TextWriter stdError, int processId, string output, bool diag, bool crashreport, DumpTypeOption type, string name) + public int Collect(TextWriter stdOutput, TextWriter stdError, int processId, string output, bool diag, bool crashreport, DumpTypeOption type, string name, string diagnosticPort) { - Console.WriteLine(name); - if (name != null) + if (CommandUtils.ResolveProcessForAttach(processId, name, diagnosticPort, string.Empty, out int resolvedProcessId)) { - if (processId != 0) - { - Console.WriteLine("Can only specify either --name or --process-id option."); - return -1; - } - processId = CommandUtils.FindProcessIdWithName(name); - if (processId < 0) - { - return -1; - } + processId = resolvedProcessId; } - - if (processId == 0) + else { - Console.Error.WriteLine("ProcessId is required."); - return -1; - } - - if (processId < 0) - { - Console.Error.WriteLine($"The PID cannot be negative: {processId}"); return -1; } @@ -103,7 +85,21 @@ public int Collect(TextWriter stdOutput, TextWriter stdError, int processId, str } else { - DiagnosticsClient client = new(processId); + DiagnosticsClient client; + if (!string.IsNullOrEmpty(diagnosticPort)) + { + IpcEndpointConfig diagnosticPortConfig = IpcEndpointConfig.Parse(diagnosticPort); + if (!diagnosticPortConfig.IsConnectConfig) + { + Console.WriteLine("dotnet-dump only supports connect mode to a runtime."); + return -1; + } + client = new DiagnosticsClient(diagnosticPortConfig); + } + else + { + client = new DiagnosticsClient(processId); + } DumpType dumpType = DumpType.Normal; switch (type) diff --git a/src/Tools/dotnet-dump/Program.cs b/src/Tools/dotnet-dump/Program.cs index f097f28d4e..c6b1276ea8 100644 --- a/src/Tools/dotnet-dump/Program.cs +++ b/src/Tools/dotnet-dump/Program.cs @@ -28,7 +28,7 @@ private static Command CollectCommand() { Command command = new(name: "collect", description: "Capture dumps from a process") { - ProcessIdOption, OutputOption, DiagnosticLoggingOption, CrashReportOption, TypeOption, ProcessNameOption + ProcessIdOption, OutputOption, DiagnosticLoggingOption, CrashReportOption, TypeOption, ProcessNameOption, DiagnosticPortOption }; command.SetAction((parseResult, ct) => Task.FromResult(new Dumper().Collect( @@ -39,7 +39,8 @@ private static Command CollectCommand() diag: parseResult.GetValue(DiagnosticLoggingOption), crashreport: parseResult.GetValue(CrashReportOption), type: parseResult.GetValue(TypeOption), - name: parseResult.GetValue(ProcessNameOption)))); + name: parseResult.GetValue(ProcessNameOption), + diagnosticPort: parseResult.GetValue(DiagnosticPortOption)))); return command; } @@ -82,6 +83,12 @@ private static Command CollectCommand() DefaultValueFactory = _ => Dumper.DumpTypeOption.Full }; + private static readonly Option DiagnosticPortOption = + new("--diagnostic-port", "--dport") + { + Description = "The path to a diagnostic port to be used. Must be a runtime connect port." + }; + private static Command AnalyzeCommand() { Command command = new(