Exception in dotnet-counter does not crash the app
authorAndrew Au <andrewau@microsoft.com>
Thu, 30 May 2019 18:52:30 +0000 (11:52 -0700)
committerAndrew Au <cshung@gmail.com>
Thu, 30 May 2019 21:21:16 +0000 (14:21 -0700)
src/Tools/dotnet-counters/CounterMonitor.cs

index ffda06f9da12aa34b10370c0e79251330ded0877..c57f1936e67467255b30911af1c39f2deb650e6f 100644 (file)
@@ -6,6 +6,7 @@ using Microsoft.Diagnostics.Tools.RuntimeClient;
 using System;
 using System.Collections.Generic;
 using System.CommandLine;
+using System.Diagnostics;
 using System.IO;
 using System.Text;
 using System.Threading;
@@ -159,46 +160,62 @@ namespace Microsoft.Diagnostics.Tools.Counters
                 providerString = sb.ToString();
             }
 
+            var shouldExit = new ManualResetEvent(false);
             var terminated = false;
 
             Task monitorTask = new Task(() => {
-                var configuration = new SessionConfiguration(
-                    circularBufferSizeMB: 1000,
-                    outputPath: "",
-                    providers: Trace.Extensions.ToProviders(providerString));
-
-                var binaryReader = EventPipeClient.CollectTracing(_processId, configuration, out _sessionId);
-                EventPipeEventSource source = new EventPipeEventSource(binaryReader);
-                writer.InitializeDisplay();
-                source.Dynamic.All += Dynamic_All;
-                source.Process();
-                terminated = true; // This indicates that the runtime is done. We shoudn't try to talk to it anymore.
+                try
+                {
+                    var configuration = new SessionConfiguration(
+                        circularBufferSizeMB: 1000,
+                        outputPath: "",
+                        providers: Trace.Extensions.ToProviders(providerString));
+
+                    var binaryReader = EventPipeClient.CollectTracing(_processId, configuration, out _sessionId);
+                    EventPipeEventSource source = new EventPipeEventSource(binaryReader);
+                    writer.InitializeDisplay();
+                    source.Dynamic.All += Dynamic_All;
+                    source.Process();
+                }
+                catch (Exception ex)
+                {
+                    Console.Error.WriteLine($"[ERROR] {ex.ToString()}");
+                }
+                finally
+                {
+                    terminated = true; // This indicates that the runtime is done. We shouldn't try to talk to it anymore.
+                    shouldExit.Set();
+                }
             });
 
-            Task commandTask = new Task(() =>
+            monitorTask.Start();
+            while(true)
             {
-                while(true)
+                while (true)
                 {
-                    while (!Console.KeyAvailable) { }
-                    ConsoleKey cmd = Console.ReadKey(true).Key;
-                    if (cmd == ConsoleKey.Q)
-                    {
-                        break;
-                    }
-                    else if (cmd == ConsoleKey.P)
+                    if (shouldExit.WaitOne(250))
                     {
-                        pauseCmdSet = true;
+                        return 0;
                     }
-                    else if (cmd == ConsoleKey.R)
+                    if (Console.KeyAvailable)
                     {
-                        pauseCmdSet = false;
+                        break;
                     }
                 }
-            });
-
-            monitorTask.Start();
-            commandTask.Start();
-            await commandTask;
+                ConsoleKey cmd = Console.ReadKey(true).Key;
+                if (cmd == ConsoleKey.Q)
+                {
+                    break;
+                }
+                else if (cmd == ConsoleKey.P)
+                {
+                    pauseCmdSet = true;
+                }
+                else if (cmd == ConsoleKey.R)
+                {
+                    pauseCmdSet = false;
+                }
+            }
 
             if (!terminated)
             {
@@ -206,10 +223,14 @@ namespace Microsoft.Diagnostics.Tools.Counters
                 {
                     EventPipeClient.StopTracing(_processId, _sessionId);    
                 }
-                catch (System.IO.EndOfStreamException) {} // If the app we're monitoring exits abruptly, this may throw in which case we just swallow the exception and exit gracefully.
+                catch (EndOfStreamException ex)
+                {
+                    // If the app we're monitoring exits abruptly, this may throw in which case we just swallow the exception and exit gracefully.
+                    Debug.WriteLine($"[ERROR] {ex.ToString()}");
+                } 
             }
             
-            return 0;
+            return await Task.FromResult(0);
         }
     }
 }