From a1f5b0aa5744be15baafb276cd22a62ffdca3dd2 Mon Sep 17 00:00:00 2001 From: Konstantin Gukov Date: Mon, 14 Jun 2021 11:55:17 +0200 Subject: [PATCH] Do not stop powershell when can't create telemetry mutex. Currently powershell crashes if there's no space on the disk with the following error: ``` Error: failed to execute "pwsh": Process terminated. The type initializer for 'Microsoft.PowerShell.Telemetry.ApplicationInsightsTelemetry' threw an exception. at System.Environment.FailFast(System.String, System.Exception) at Microsoft.PowerShell.UnmanagedPSEntry.Start(System.String[], Int32) at Microsoft.PowerShell.ManagedPSEntry.Main(System.String[]) System.TypeInitializationException: The type initializer for 'Microsoft.PowerShell.Telemetry.ApplicationInsightsTelemetry' threw an exception. ---> System.IO.IOException: The system cannot open the device or file specified. : 'CreateUniqueUserId' at System.Threading.Mutex.CreateMutexCore(Boolean initiallyOwned, String name, Boolean& createdNew) at System.Threading.Mutex..ctor(Boolean initiallyOwned, String name) at Microsoft.PowerShell.Telemetry.ApplicationInsightsTelemetry.GetUniqueIdentifier() in /PowerShell/src/System.Management.Automation/utils/Telemetry.cs:line 802 at Microsoft.PowerShell.Telemetry.ApplicationInsightsTelemetry..cctor() in /PowerShell/src/System.Management.Automation/utils/Telemetry.cs:line 548 --- End of inner exception stack trace --- at Microsoft.PowerShell.Telemetry.ApplicationInsightsTelemetry.SendPSCoreStartupTelemetry(String mode) in /PowerShell/src/System.Management.Automation/utils/Telemetry.cs:line 656 at Microsoft.PowerShell.ConsoleHost.Start(String bannerText, String helpText) in /PowerShell/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs:line 248 at Microsoft.PowerShell.UnmanagedPSEntry.Start(String[] args, Int32 argc) in /PowerShell/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs:line 99 ``` This exception is thrown from Mutex ctor and isn't properly handled. This change fixes it. --- .../utils/Telemetry.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/System.Management.Automation/utils/Telemetry.cs b/src/System.Management.Automation/utils/Telemetry.cs index 3ff3c908867..b00a472922e 100644 --- a/src/System.Management.Automation/utils/Telemetry.cs +++ b/src/System.Management.Automation/utils/Telemetry.cs @@ -835,29 +835,30 @@ private static Guid GetUniqueIdentifier() // Multiple processes may start simultaneously so we need a system wide // way to control access to the file in the case (although remote) when we have - // simulataneous shell starts without the persisted file which attempt to create the file. - using (var m = new Mutex(true, "CreateUniqueUserId")) + // simultaneous shell starts without the persisted file which attempt to create the file. + try { // TryCreateUniqueIdentifierAndFile shouldn't throw, but the mutex might + using var m = new Mutex(true, "CreateUniqueUserId"); + m.WaitOne(); try { - m.WaitOne(); if (TryCreateUniqueIdentifierAndFile(uuidPath, out id)) { return id; } } - catch (Exception) - { - // Any problem in generating a uuid will result in no telemetry being sent. - // Try to send the failure in telemetry, but it will have no unique id. - s_telemetryClient.GetMetric(_telemetryFailure, "Detail").TrackValue(1, "mutex"); - } finally { m.ReleaseMutex(); } } + catch (Exception) + { + // Any problem in generating a uuid will result in no telemetry being sent. + // Try to send the failure in telemetry, but it will have no unique id. + s_telemetryClient.GetMetric(_telemetryFailure, "Detail").TrackValue(1, "mutex"); + } // something bad happened, turn off telemetry since the unique id wasn't set. CanSendTelemetry = false;