Skip to content
代码片段 群组 项目
提交 e5e5e609 编辑于 作者: Sam Harwell's avatar Sam Harwell 提交者: GitHub
浏览文件

Merge pull request #21152 from heejaechang/dontcrash2

replaced crash to NFW. it will now show info bar and throw cancellati…
No related branches found
No related tags found
无相关合并请求
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.VisualStudio.LanguageServices.Implementation
{
/// <summary>
/// Mock to make test project build
/// </summary>
internal class WatsonReporter
{
public static void Report(string description, Exception exception, Func<IFaultUtility, int> callback)
{
// do nothing
}
public interface IFaultUtility
{
void AddProcessDump(int pid);
void AddFile(string fullpathname);
}
}
}
\ No newline at end of file
using System;
namespace Microsoft.VisualStudio.LanguageServices.Implementation
{
/// <summary>
/// Mock to make test project build
/// </summary>
internal class WatsonReporter
{
public static void Report(string description, Exception exception, Func<IFaultUtility, int> callback)
{
// do nothing
}
public interface IFaultUtility
{
void AddProcessDump(int pid);
void AddFile(string fullpathname);
}
}
// Mock resource to make test project build
internal static class ServicesVSResources
{
public const string Unfortunately_a_process_used_by_Visual_Studio_has_encountered_an_unrecoverable_error_We_recommend_saving_your_work_and_then_closing_and_restarting_Visual_Studio = "";
}
}
......@@ -8,9 +8,10 @@
using System.Threading.Tasks;
using StreamJsonRpc;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Extensions;
using Microsoft.CodeAnalysis.Remote;
using Roslyn.Utilities;
using Microsoft.VisualStudio.LanguageServices.Implementation;
using Roslyn.Utilities;
namespace Microsoft.VisualStudio.LanguageServices.Remote
{
......@@ -23,9 +24,6 @@ internal class JsonRpcClient : IDisposable
private readonly JsonRpc _rpc;
private readonly CancellationToken _cancellationToken;
private JsonRpcDisconnectedEventArgs _debuggingLastDisconnectReason;
private string _debuggingLastDisconnectCallstack;
public JsonRpcClient(
Stream stream, object callbackTarget, bool useThisAsCallback, CancellationToken cancellationToken)
{
......@@ -55,7 +53,10 @@ public async Task InvokeAsync(string targetName, params object[] arguments)
// cancellation exception here. if any exception is thrown unrelated to cancellation, then we will rethrow
// the exception
_cancellationToken.ThrowIfCancellationRequested();
throw;
// this is to make us not crash. we should remove this once we figure out
// what is causing this
ThrowOwnCancellationToken();
}
}
......@@ -74,7 +75,11 @@ public async Task<T> InvokeAsync<T>(string targetName, params object[] arguments
// cancellation exception here. if any exception is thrown unrelated to cancellation, then we will rethrow
// the exception
_cancellationToken.ThrowIfCancellationRequested();
throw;
// this is to make us not crash. we should remove this once we figure out
// what is causing this
ThrowOwnCancellationToken();
return Contract.FailWithReturn<T>("can't reach here");
}
}
......@@ -88,6 +93,33 @@ public Task<T> InvokeAsync<T>(string targetName, IEnumerable<object> arguments,
return Extensions.InvokeAsync(_rpc, targetName, arguments, funcWithDirectStreamAsync, _cancellationToken);
}
public void Dispose()
{
OnDisposed();
_rpc.Dispose();
}
protected void StartListening()
{
// due to this issue - https://github.com/dotnet/roslyn/issues/16900#issuecomment-277378950
// _rpc need to be explicitly started
_rpc.StartListening();
}
protected virtual void OnDisposed()
{
// do nothing
}
// these are for debugging purpose. once we find out root cause of the issue
// we will remove these.
private static JsonRpcDisconnectedEventArgs s_debuggingLastDisconnectReason;
private static string s_debuggingLastDisconnectCallstack;
private JsonRpcDisconnectedEventArgs _debuggingLastDisconnectReason;
private string _debuggingLastDisconnectCallstack;
private bool ReportUnlessCanceled(Exception ex, CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
......@@ -95,16 +127,46 @@ private bool ReportUnlessCanceled(Exception ex, CancellationToken cancellationTo
return true;
}
// save extra info using NFW
ReportExtraInfoAsNFW(ex);
s_debuggingLastDisconnectReason = _debuggingLastDisconnectReason;
s_debuggingLastDisconnectCallstack = _debuggingLastDisconnectCallstack;
// make it to explicitly crash to get better info
FatalError.Report(ex);
// send NFW to figure out why this is happening
ReportExtraInfoAsNFW(ex);
GC.KeepAlive(_debuggingLastDisconnectReason);
GC.KeepAlive(_debuggingLastDisconnectCallstack);
return Contract.FailWithReturn<bool>("shouldn't be able to reach here");
return true;
}
private static bool s_reported = false;
/// <summary>
/// Show info bar and throw its own cancellation exception until
/// we figure out this issue.
/// https://devdiv.visualstudio.com/DevDiv/_workitems/edit/453544
///
/// the issue is basically we are getting unexpected exception from InvokeAsync
/// and we don't know exactly why that is happening.
/// </summary>
private void ThrowOwnCancellationToken()
{
if (CodeAnalysis.PrimaryWorkspace.Workspace != null && !s_reported)
{
// do not report it multiple times
s_reported = true;
// use info bar to show warning to users
CodeAnalysis.PrimaryWorkspace.Workspace.Services.GetService<IErrorReportingService>()?.ShowGlobalErrorInfo(
ServicesVSResources.Unfortunately_a_process_used_by_Visual_Studio_has_encountered_an_unrecoverable_error_We_recommend_saving_your_work_and_then_closing_and_restarting_Visual_Studio);
}
// create its own cancellation token and throw it
using (var ownCancellationSource = new CancellationTokenSource())
{
ownCancellationSource.Cancel();
ownCancellationSource.Token.ThrowIfCancellationRequested();
}
}
private void ReportExtraInfoAsNFW(Exception ex)
......@@ -150,25 +212,6 @@ private void ReportExtraInfoAsNFW(Exception ex)
});
}
public void Dispose()
{
OnDisposed();
_rpc.Dispose();
}
protected void StartListening()
{
// due to this issue - https://github.com/dotnet/roslyn/issues/16900#issuecomment-277378950
// _rpc need to be explicitly started
_rpc.StartListening();
}
protected virtual void OnDisposed()
{
// do nothing
}
protected virtual void OnDisconnected(object sender, JsonRpcDisconnectedEventArgs e)
{
// do nothing
......
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册