public static async Task <RemoteHostClient> CreateAsync(HostWorkspaceServices services, CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.ServiceHubRemoteHostClient_CreateAsync, KeyValueLogMessage.NoProperty, cancellationToken))
            {
                Logger.Log(FunctionId.RemoteHost_Bitness, KeyValueLogMessage.Create(LogType.Trace, m => m["64bit"] = RemoteHostOptions.IsServiceHubProcess64Bit(services)));

                // let each client to have unique id so that we can distinguish different clients when service is restarted
                var clientId = $"VS ({Process.GetCurrentProcess().Id}) ({Guid.NewGuid()})";

                var hostGroup = new HostGroup(clientId);
                var hubClient = new HubClient("ManagedLanguage.IDE.RemoteHostClient");

                // use the hub client logger for unexpected exceptions from devenv as well, so we have complete information in the log:
                WatsonReporter.InitializeLogger(hubClient.Logger);

                var remoteHostStream = await RequestServiceAsync(services, hubClient, WellKnownServiceHubService.RemoteHost, hostGroup, cancellationToken).ConfigureAwait(false);

                var client = new ServiceHubRemoteHostClient(services, hubClient, hostGroup, remoteHostStream);

                var uiCultureLCID = CultureInfo.CurrentUICulture.LCID;
                var cultureLCID   = CultureInfo.CurrentCulture.LCID;

                bool success = false;
                try
                {
                    // initialize the remote service
                    await client._endPoint.InvokeAsync <string>(
                        nameof(IRemoteHostService.InitializeGlobalState),
                        new object[] { clientId, uiCultureLCID, cultureLCID, TelemetryService.DefaultSession.SerializeSettings() },
                        cancellationToken).ConfigureAwait(false);

                    success = true;
                }
                finally
                {
                    if (!success)
                    {
                        client.Dispose();
                    }
                }

                client.Started();
                return(client);
            }
        }
        private bool CanHandle(string errorId)
        {
            // make sure we have error id, otherwise, we simple don't support
            // this error
            if (errorId == null)
            {
                // record NFW to see who violates contract.
                WatsonReporter.ReportNonFatal(new Exception("errorId is null"));
                return(false);
            }

            // we accept all compiler diagnostics
            if (errorId.StartsWith(_errorCodePrefix))
            {
                return(true);
            }

            return(DiagnosticProvider.IsSupportedDiagnosticId(_projectId, errorId));
        }
        public static async Task <RemoteHostClient?> CreateAsync(Workspace workspace, CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.ServiceHubRemoteHostClient_CreateAsync, cancellationToken))
            {
                // let each client to have unique id so that we can distinguish different clients when service is restarted
                var clientId = CreateClientId(Process.GetCurrentProcess().Id.ToString());

                var hostGroup = new HostGroup(clientId);
                var hubClient = new HubClient("ManagedLanguage.IDE.RemoteHostClient");

                // use the hub client logger for unexpected exceptions from devenv as well, so we have complete information in the log:
                WatsonReporter.InitializeLogger(hubClient.Logger);

                var remoteHostStream = await RequestServiceAsync(workspace, hubClient, WellKnownServiceHubServices.RemoteHostService, hostGroup, cancellationToken).ConfigureAwait(false);

                var client = new ServiceHubRemoteHostClient(workspace, hubClient, hostGroup, remoteHostStream);

                var uiCultureLCID = CultureInfo.CurrentUICulture.LCID;
                var cultureLCID   = CultureInfo.CurrentCulture.LCID;

                bool success = false;
                try
                {
                    // initialize the remote service
                    _ = await client._endPoint.InvokeAsync <string>(
                        nameof(IRemoteHostService.Connect),
                        new object[] { clientId, uiCultureLCID, cultureLCID, TelemetryService.DefaultSession.SerializeSettings() },
                        cancellationToken).ConfigureAwait(false);

                    success = true;
                }
                finally
                {
                    if (!success)
                    {
                        client.Dispose();
                    }
                }

                client.Started();
                return(client);
            }
        }
Example #4
0
        private static void SetGlobalContext(string serializedSession)
        {
            // set global telemetry session
            var session = GetTelemetrySession(serializedSession);

            if (session == null)
            {
                return;
            }

            // set roslyn loggers
            WatsonReporter.SetTelemetrySession(session);

            RoslynLogger.SetLogger(AggregateLogger.Create(new VSTelemetryLogger(session), RoslynLogger.GetLogger()));

            // set both handler as NFW
            FatalError.Handler         = WatsonReporter.Report;
            FatalError.NonFatalHandler = WatsonReporter.Report;
        }
Example #5
0
        private void ReportExtraInfoAsNFW(Exception ex)
        {
            WatsonReporter.Report("RemoteHost Failed", ex, u =>
            {
                try
                {
                    // we will record dumps for all service hub processes
                    foreach (var p in Process.GetProcessesByName("ServiceHub.RoslynCodeAnalysisService32"))
                    {
                        // include all remote host processes
                        u.AddProcessDump(p.Id);
                    }

                    // include all service hub logs as well
                    var logPath = Path.Combine(Path.GetTempPath(), "servicehub", "logs");
                    if (Directory.Exists(logPath))
                    {
                        // attach all log files that are modified less than 1 day before.
                        var now    = DateTime.UtcNow;
                        var oneDay = TimeSpan.FromDays(1);

                        foreach (var file in Directory.EnumerateFiles(logPath, "*.log"))
                        {
                            var lastWrite = File.GetLastWriteTimeUtc(file);
                            if (now - lastWrite > oneDay)
                            {
                                continue;
                            }

                            u.AddFile(file);
                        }
                    }
                }
                catch
                {
                    // ignore issue
                }

                // 0 means send watson
                return(0);
            });
        }
Example #6
0
        protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress <ServiceProgressData> progress)
        {
            await base.InitializeAsync(cancellationToken, progress).ConfigureAwait(true);

            await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

            _componentModel = (IComponentModel) await GetServiceAsync(typeof(SComponentModel)).ConfigureAwait(true);

            cancellationToken.ThrowIfCancellationRequested();
            Assumes.Present(_componentModel);

            // Fetch the session synchronously on the UI thread; if this doesn't happen before we try using this on
            // the background thread then we will experience hangs like we see in this bug:
            // https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?_a=edit&id=190808 or
            // https://devdiv.visualstudio.com/DevDiv/_workitems?id=296981&_a=edit
            var telemetrySession = TelemetryService.DefaultSession;

            WatsonReporter.InitializeFatalErrorHandlers(telemetrySession);

            // Ensure the options persisters are loaded since we have to fetch options from the shell
            _componentModel.GetExtensions <IOptionPersister>();

            _workspace = _componentModel.GetService <VisualStudioWorkspace>();
            _workspace.Services.GetService <IExperimentationService>();

            RoslynTelemetrySetup.Initialize(this, telemetrySession);

            InitializeColors();

            // load some services that have to be loaded in UI thread
            LoadComponentsInUIContextOnceSolutionFullyLoadedAsync(cancellationToken).Forget();

            _solutionEventMonitor = new SolutionEventMonitor(_workspace);

            TrackBulkFileOperations();
        }
            private void OnStatusChanged(object sender, bool started)
            {
                if (started)
                {
                    return;
                }

                Contract.ThrowIfNull(_shutdownCancellationTokenSource);

                if (_shutdownCancellationTokenSource.IsCancellationRequested)
                {
                    lock (_gate)
                    {
                        // RemoteHost has been disabled
                        _remoteClientTask = null;
                    }
                }
                else
                {
                    lock (_gate)
                    {
                        // save last remoteHostClient
                        s_lastRemoteClientTask = _remoteClientTask;

                        // save NoOpRemoteHostClient to remoteClient so that all RemoteHost call becomes
                        // No Op. this basically have same effect as disabling all RemoteHost features
                        _remoteClientTask = Task.FromResult <RemoteHostClient?>(new RemoteHostClient.NoOpClient(_workspace));
                    }

                    // s_lastRemoteClientTask info should be saved in the dump
                    // report NFW when connection is closed unless it is proper shutdown
                    WatsonReporter.Report(new Exception("Connection to remote host closed"), WatsonSeverity.Critical);

                    RemoteHostCrashInfoBar.ShowInfoBar(_workspace);
                }
            }
Example #8
0
 static ServiceBase()
 {
     WatsonReporter.InitializeFatalErrorHandlers();
 }
Example #9
0
 static VisualStudioWorkspace()
 {
     WatsonReporter.InitializeFatalErrorHandlers();
 }
Example #10
0
 public void UnregisterUnexpectedExceptionLogger(TraceSource logger)
 => WatsonReporter.UnregisterLogger(logger);
Example #11
0
 public static void ReportNonFatalWatsonWithServiceHubLogs(Exception ex, string message)
 {
     WatsonReporter.Report(message, ex, AddServiceHubLogFiles, WatsonSeverity.Critical);
 }