Clean up reversed server sockets upon exit (#1704)
authorSung Yoon Whang <suwhang@microsoft.com>
Sat, 7 Nov 2020 20:27:17 +0000 (12:27 -0800)
committerGitHub <noreply@github.com>
Sat, 7 Nov 2020 20:27:17 +0000 (12:27 -0800)
src/Tools/Common/ReversedServerHelpers/ReversedServerHelpers.cs
src/Tools/dotnet-counters/CounterMonitor.cs
src/Tools/dotnet-trace/CommandLine/Commands/CollectCommand.cs

index 0f368d89cba00e5298d6ef5c498ed80f1205bd05..ff74a7e3e0dfa938fe3e13559a29f594af299b24 100644 (file)
@@ -96,7 +96,7 @@ namespace Microsoft.Internal.Common.Utils
             return true;
         }
 
-        public void Cleanup()
+        public async void Cleanup()
         {
             if (_childProc != null && !_childProc.HasExited)
             {
@@ -107,6 +107,11 @@ namespace Microsoft.Internal.Common.Utils
                 // if process exited while we were trying to kill it, it can throw IOE 
                 catch (InvalidOperationException) { }
             }
+
+            if (ReversedDiagnosticsClientBuilder.Server != null)
+            {
+                await ReversedDiagnosticsClientBuilder.Server.DisposeAsync();
+            }
         }
     }
 
@@ -117,6 +122,8 @@ namespace Microsoft.Internal.Common.Utils
     {
         private static string GetTransportName(string toolName) => $"{toolName}-{Process.GetCurrentProcess().Id}-{DateTime.Now:yyyyMMdd_HHmmss}.socket";
 
+        public static ReversedDiagnosticsServer Server = null;
+
         // <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.
@@ -129,8 +136,8 @@ namespace Microsoft.Internal.Common.Utils
             }
             // Create and start the reversed server            
             string diagnosticTransportName = GetTransportName(toolName);
-            ReversedDiagnosticsServer server = new ReversedDiagnosticsServer(diagnosticTransportName);
-            server.Start();
+            Server = new ReversedDiagnosticsServer(diagnosticTransportName);
+            Server.Start();
 
             // Start the child proc
             if (!childProcLauncher.Start(diagnosticTransportName))
@@ -139,14 +146,14 @@ namespace Microsoft.Internal.Common.Utils
             }
 
             // Wait for attach
-            IpcEndpointInfo endpointInfo = server.Accept(TimeSpan.FromSeconds(timeoutInSec));
+            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)); 
+               endpointInfo = Server.Accept(TimeSpan.FromSeconds(timeoutInSec));
             }
             return new DiagnosticsClient(endpointInfo.Endpoint);
         }
     }
-}
\ No newline at end of file
+}
index 5bdb84079733fe65c335590273114c79b11d199d..974013ba7fffdedccb51b38691ccb0403060ceaf 100644 (file)
@@ -95,6 +95,7 @@ namespace Microsoft.Diagnostics.Tools.Counters
                 return 0;
             }
 
+            int ret = 0;
             try
             {
                 InitializeCounterList(counters, counter_list);
@@ -104,11 +105,10 @@ namespace Microsoft.Diagnostics.Tools.Counters
                 _renderer = new ConsoleWriter();
                 if (!BuildDiagnosticsClient())
                 {
-                    return 0;
+                    ret = 0;
                 }
-                int ret = await Start();
+                ret = await Start();
                 ProcessLauncher.Launcher.Cleanup();
-                return ret;
             }
             catch (OperationCanceledException)
             {
@@ -119,13 +119,19 @@ namespace Microsoft.Diagnostics.Tools.Counters
                 catch (Exception) {} // Swallow all exceptions for now.
                 
                 console.Out.WriteLine($"Complete");
-                return 1;
+                ret = 1;
+            }
+            finally
+            {
+                ProcessLauncher.Launcher.Cleanup();
             }
+            return ret;
         }
 
 
         public async Task<int> Collect(CancellationToken ct, List<string> counter_list, string counters, IConsole console, int processId, int refreshInterval, CountersExportFormat format, string output, string name)
         {
+            int ret = 1;
             if (!ValidateAndSetProcessId(processId, name))
             {
                 return 0;
@@ -145,6 +151,7 @@ namespace Microsoft.Diagnostics.Tools.Counters
 
                 if (!BuildDiagnosticsClient())
                 {
+                    ProcessLauncher.Launcher.Cleanup();
                     return 0;
                 }
 
@@ -172,15 +179,16 @@ namespace Microsoft.Diagnostics.Tools.Counters
                     _console.Error.WriteLine($"The output format {format} is not a valid output format.");
                     return 0;
                 }
-
-                int ret = await Start();
-                ProcessLauncher.Launcher.Cleanup();
-                return ret;
+                ret = await Start();
             }
             catch (OperationCanceledException)
             {
             }
-            return 1;
+            finally
+            {
+                ProcessLauncher.Launcher.Cleanup();
+            }
+            return ret;
         }
 
         private void InitializeCounterList(string counters, List<string> counterList)
index 2f70022d5e30d005a0736f23785fe415c263ab33..251116f7f2ffbf881df9f899298c3c2861147a05 100644 (file)
@@ -41,6 +41,7 @@ namespace Microsoft.Diagnostics.Tools.Trace
         /// <returns></returns>
         private static async Task<int> Collect(CancellationToken ct, IConsole console, int processId, FileInfo output, uint buffersize, string providers, string profile, TraceFileFormat format, TimeSpan duration, string clrevents, string clreventlevel, string name)
         {
+            int ret = 0;
             try
             {
                 Debug.Assert(output != null);
@@ -141,6 +142,7 @@ namespace Microsoft.Diagnostics.Tools.Trace
                         {
                             ProcessLauncher.Launcher.ChildProc.Kill();
                         }
+                        await ReversedDiagnosticsClientBuilder.Server.DisposeAsync();
                         return ErrorCodes.SessionCreationError;
                     }
                     process = ProcessLauncher.Launcher.ChildProc;
@@ -253,12 +255,13 @@ namespace Microsoft.Diagnostics.Tools.Trace
 
                     if (format != TraceFileFormat.NetTrace)
                         TraceFileFormatConverter.ConvertToFormat(format, output.FullName);
+                    ret = 0;
                 }
             }
             catch (Exception ex)
             {
                 Console.Error.WriteLine($"[ERROR] {ex.ToString()}");
-                return ErrorCodes.TracingError;
+                ret = ErrorCodes.TracingError;
             }
             finally
             {
@@ -270,9 +273,13 @@ namespace Microsoft.Diagnostics.Tools.Trace
                 {
                     ProcessLauncher.Launcher.ChildProc.Kill();
                 }
-            }
 
-            return await Task.FromResult(0);
+                if (ReversedDiagnosticsClientBuilder.Server != null)
+                {
+                    await ReversedDiagnosticsClientBuilder.Server.DisposeAsync();
+                }
+            }
+            return await Task.FromResult(ret);
         }
 
         private static void PrintProviders(IReadOnlyList<EventPipeProvider> providers, Dictionary<string, string> enabledBy)