提交 cd0e5e85 编写于 作者: C Charles Stoner 提交者: Jared Parsons

Catch and report FileNotFoundException loading compiler assemblies

上级 3ae0bc44
// 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;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
......@@ -20,7 +18,6 @@
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Debugging;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Test.Utilities;
......@@ -9057,7 +9054,31 @@ public void CompilingCodeWithMultipleInvalidPreProcessorSymbolsShouldErrorOut()
// warning CS2029: Invalid value for '/define'; '5' is not a valid identifier
Diagnostic(ErrorCode.WRN_DefineIdentifierRequired).WithArguments("5"));
}
[WorkItem(406649, "https://devdiv.visualstudio.com/DevDiv/_workitems?id=406649")]
[ConditionalFact(typeof(IsEnglishLocal))]
public void MissingCompilerAssembly()
{
var dir = Temp.CreateDirectory();
var cscPath = dir.CopyFile(typeof(Csc).Assembly.Location).Path;
// Missing Microsoft.CodeAnalysis.CSharp.dll.
var result = ProcessUtilities.Run(cscPath, arguments: "/nologo /t:library unknown.cs", workingDirectory: dir.Path);
Assert.Equal(1, result.ExitCode);
Assert.Equal(
$"Could not load file or assembly '{typeof(CSharpCompilation).Assembly.FullName}' or one of its dependencies. The system cannot find the file specified.",
result.Output.Trim());
// Missing System.Collections.Immutable.dll.
dir.CopyFile(typeof(Compilation).Assembly.Location);
dir.CopyFile(typeof(CSharpCompilation).Assembly.Location);
result = ProcessUtilities.Run(cscPath, arguments: "/nologo /t:library unknown.cs", workingDirectory: dir.Path);
Assert.Equal(1, result.ExitCode);
Assert.Equal(
$"Could not load file or assembly '{typeof(ImmutableArray).Assembly.FullName}' or one of its dependencies. The system cannot find the file specified.",
result.Output.Trim());
}
public class QuotedArgumentTests
{
private void VerifyQuotedValid<T>(string name, string value, T expected, Func<CSharpCommandLineArguments, T> getValue)
......
// 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;
using System.IO;
using Microsoft.CodeAnalysis.CommandLine;
using Roslyn.Utilities;
using System;
namespace Microsoft.CodeAnalysis.CSharp.CommandLine
{
public class Program
{
public static int Main(string[] args)
=> Main(args, Array.Empty<string>());
{
try
{
return MainCore(args);
}
catch (FileNotFoundException e)
{
// Catch exception from missing compiler assembly.
// Report the exception message and terminate the process.
Console.WriteLine(e.Message);
return CommonCompiler.Failed;
}
}
public static int Main(string[] args, string[] extraArgs)
=> DesktopBuildClient.Run(args, extraArgs, RequestLanguage.CSharpCompile, Csc.Run, new DesktopAnalyzerAssemblyLoader());
private static int MainCore(string[] args)
=> DesktopBuildClient.Run(args, RequestLanguage.CSharpCompile, Csc.Run, new DesktopAnalyzerAssemblyLoader());
public static int Run(string[] args, string clientDir, string workingDir, string sdkDir, string tempDir, TextWriter textWriter, IAnalyzerAssemblyLoader analyzerLoader)
=> Csc.Run(args, new BuildPaths(clientDir: clientDir, workingDir: workingDir, sdkDir: sdkDir, tempDir: tempDir), textWriter, analyzerLoader);
......
......@@ -128,14 +128,14 @@ public static async Task<BuildRequest> ReadAsync(Stream inStream, CancellationTo
cancellationToken.ThrowIfCancellationRequested();
// Read the full request
var responseBuffer = new byte[length];
await ReadAllAsync(inStream, responseBuffer, length, cancellationToken).ConfigureAwait(false);
var requestBuffer = new byte[length];
await ReadAllAsync(inStream, requestBuffer, length, cancellationToken).ConfigureAwait(false);
cancellationToken.ThrowIfCancellationRequested();
Log("Parsing request");
// Parse the request into the Request data structure.
using (var reader = new BinaryReader(new MemoryStream(responseBuffer), Encoding.Unicode))
using (var reader = new BinaryReader(new MemoryStream(requestBuffer), Encoding.Unicode))
{
var protocolVersion = reader.ReadUInt32();
var language = (RequestLanguage)reader.ReadUInt32();
......
......@@ -508,7 +508,7 @@ public virtual int Run(TextWriter consoleOutput, CancellationToken cancellationT
}
}
internal int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, CancellationToken cancellationToken)
private int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, CancellationToken cancellationToken)
{
Debug.Assert(!Arguments.IsScriptRunner);
......
......@@ -4,6 +4,7 @@
using System;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;
namespace Microsoft.CodeAnalysis.CompilerServer
{
......@@ -25,8 +26,18 @@ public static int Main(string[] args)
CompilerServerLogger.LogException(ex, "Error loading application settings");
}
var controller = new DesktopBuildServerController(appSettings);
return controller.Run(args);
try
{
var controller = new DesktopBuildServerController(appSettings);
return controller.Run(args);
}
catch (TypeInitializationException ex) when (ex.InnerException is FileNotFoundException)
{
// Assume FileNotFoundException was the result of a missing
// compiler assembly. Log the exception and terminate the process.
CompilerServerLogger.LogException(ex, "File not found");
return CommonCompiler.Failed;
}
}
}
}
......@@ -3,20 +3,15 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CommandLine;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.Win32;
using Roslyn.Test.Utilities;
using Xunit;
using System.Xml;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CommandLine;
using Moq;
namespace Microsoft.CodeAnalysis.CompilerServer.UnitTests
{
......@@ -112,7 +107,7 @@ public CompilerServerUnitTests()
#region Helpers
private IEnumerable<KeyValuePair<string, string>> AddForLoggingEnvironmentVars(IEnumerable<KeyValuePair<string, string>> vars)
private static IEnumerable<KeyValuePair<string, string>> AddForLoggingEnvironmentVars(IEnumerable<KeyValuePair<string, string>> vars)
{
vars = vars ?? new KeyValuePair<string, string>[] { };
if (!vars.Where(kvp => kvp.Key == "RoslynCommandLineLogFile").Any())
......@@ -162,13 +157,7 @@ private static void CheckForBadShared(string arguments)
}
}
public Process StartProcess(string fileName, string arguments, string workingDirectory = null)
{
CheckForBadShared(arguments);
return ProcessUtilities.StartProcess(fileName, arguments, workingDirectory);
}
private ProcessResult RunCommandLineCompiler(
private static ProcessResult RunCommandLineCompiler(
string compilerPath,
string arguments,
string currentDirectory,
......@@ -182,7 +171,7 @@ public Process StartProcess(string fileName, string arguments, string workingDir
additionalEnvironmentVars: AddForLoggingEnvironmentVars(additionalEnvironmentVars));
}
private ProcessResult RunCommandLineCompiler(
private static ProcessResult RunCommandLineCompiler(
string compilerPath,
string arguments,
TempDirectory currentDirectory,
......@@ -1408,5 +1397,41 @@ public async Task Bug1024619_02()
await serverData.Verify(connections: 2, completed: 2).ConfigureAwait(true);
}
}
[WorkItem(406649, "https://devdiv.visualstudio.com/DevDiv/_workitems?id=406649")]
[Fact]
public void MissingCompilerAssembly_CompilerServer()
{
var dir = Temp.CreateDirectory();
var workingDirectory = dir.Path;
var serverExe = dir.CopyFile(CompilerServerExecutable).Path;
dir.CopyFile(typeof(System.Collections.Immutable.ImmutableArray).Assembly.Location);
// Missing Microsoft.CodeAnalysis.dll launching server.
var result = ProcessUtilities.Run(serverExe, arguments: $"-pipename:{GetUniqueName()}", workingDirectory: workingDirectory);
Assert.Equal(1, result.ExitCode);
// Exception is logged rather than written to output/error streams.
Assert.Equal("", result.Output.Trim());
}
[WorkItem(406649, "https://devdiv.visualstudio.com/DevDiv/_workitems?id=406649")]
[WorkItem(19213, "https://github.com/dotnet/roslyn/issues/19213")]
[Fact(Skip = "19213")]
public async Task MissingCompilerAssembly_CompilerServerHost()
{
var host = new TestableCompilerServerHost((request, cancellationToken) =>
{
throw new FileNotFoundException();
});
using (var serverData = ServerUtil.CreateServer(compilerServerHost: host))
{
var request = new BuildRequest(1, RequestLanguage.CSharpCompile, new BuildRequest.Argument[0]);
var compileTask = ServerUtil.Send(serverData.PipeName, request);
var response = await compileTask;
Assert.Equal(BuildResponse.ResponseType.Completed, response.Type);
Assert.Equal(0, ((CompletedBuildResponse)response).ReturnCode);
await serverData.Verify(connections: 1, completed: 1).ConfigureAwait(true);
}
}
}
}
......@@ -5,12 +5,9 @@
using Microsoft.CodeAnalysis.CommandLine;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Moq;
......
......@@ -3,9 +3,6 @@
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Roslyn.Utilities;
using Microsoft.CodeAnalysis.CommandLine;
namespace Microsoft.CodeAnalysis.CSharp.CommandLine
......
......@@ -2,20 +2,11 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.IO.Pipes;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static Microsoft.CodeAnalysis.CommandLine.CompilerServerLogger;
using static Microsoft.CodeAnalysis.CommandLine.NativeMethods;
using System.Reflection;
using System.Security.AccessControl;
using System.Security.Cryptography;
namespace Microsoft.CodeAnalysis.CommandLine
{
......@@ -37,7 +28,7 @@ internal DesktopBuildClient(RequestLanguage language, CompileFunc compileFunc, I
_analyzerAssemblyLoader = analyzerAssemblyLoader;
}
internal static int Run(IEnumerable<string> arguments, IEnumerable<string> extraArguments, RequestLanguage language, CompileFunc compileFunc, IAnalyzerAssemblyLoader analyzerAssemblyLoader)
internal static int Run(IEnumerable<string> arguments, RequestLanguage language, CompileFunc compileFunc, IAnalyzerAssemblyLoader analyzerAssemblyLoader)
{
var client = new DesktopBuildClient(language, compileFunc, analyzerAssemblyLoader);
var clientDir = AppContext.BaseDirectory;
......@@ -45,7 +36,7 @@ internal static int Run(IEnumerable<string> arguments, IEnumerable<string> extra
var workingDir = Directory.GetCurrentDirectory();
var tempDir = BuildServerConnection.GetTempPath(workingDir);
var buildPaths = new BuildPaths(clientDir: clientDir, workingDir: workingDir, sdkDir: sdkDir, tempDir: tempDir);
var originalArguments = BuildClient.GetCommandLineArgs(arguments).Concat(extraArguments).ToArray();
var originalArguments = GetCommandLineArgs(arguments).ToArray();
return client.RunCompilation(originalArguments, buildPaths).ExitCode;
}
......
......@@ -8290,6 +8290,29 @@ End Module
parsedArgs.Errors.Verify(Diagnostic(ERRID.ERR_InvalidSwitchValue).WithArguments("langversion", "1000").WithLocation(1, 1))
End Sub
<WorkItem(406649, "https://devdiv.visualstudio.com/DevDiv/_workitems?id=406649")>
<ConditionalFact(GetType(IsEnglishLocal))>
Public Sub MissingCompilerAssembly()
Dim dir = Temp.CreateDirectory()
Dim vbcPath = dir.CopyFile(GetType(Vbc).Assembly.Location).Path
' Missing Microsoft.CodeAnalysis.VisualBasic.dll.
Dim result = ProcessUtilities.Run(vbcPath, arguments:="/nologo /t:library unknown.vb", workingDirectory:=dir.Path)
Assert.Equal(1, result.ExitCode)
Assert.Equal(
$"Could not load file or assembly '{GetType(VisualBasicCompilation).Assembly.FullName}' or one of its dependencies. The system cannot find the file specified.",
result.Output.Trim())
' Missing System.Collections.Immutable.dll.
dir.CopyFile(GetType(Compilation).Assembly.Location)
dir.CopyFile(GetType(VisualBasicCompilation).Assembly.Location)
result = ProcessUtilities.Run(vbcPath, arguments:="/nologo /t:library unknown.vb", workingDirectory:=dir.Path)
Assert.Equal(1, result.ExitCode)
Assert.Equal(
$"Could not load file or assembly '{GetType(ImmutableArray).Assembly.FullName}' or one of its dependencies. The system cannot find the file specified.",
result.Output.Trim())
End Sub
Private Function MakeTrivialExe(Optional directory As String = Nothing) As String
Return Temp.CreateFile(directory:=directory, prefix:="", extension:=".vb").WriteAllText("
Class Program
......
// 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;
using System.IO;
using Microsoft.CodeAnalysis.CommandLine;
using Roslyn.Utilities;
using System;
namespace Microsoft.CodeAnalysis.VisualBasic.CommandLine
{
public class Program
{
public static int Main(string[] args)
=> Main(args, Array.Empty<string>());
{
try
{
return MainCore(args);
}
catch (FileNotFoundException e)
{
// Catch exception from missing compiler assembly.
// Report the exception message and terminate the process.
Console.WriteLine(e.Message);
return CommonCompiler.Failed;
}
}
public static int Main(string[] args, string[] extraArgs)
=> DesktopBuildClient.Run(args, extraArgs, RequestLanguage.VisualBasicCompile, Vbc.Run, new DesktopAnalyzerAssemblyLoader());
private static int MainCore(string[] args)
=> DesktopBuildClient.Run(args, RequestLanguage.VisualBasicCompile, Vbc.Run, new DesktopAnalyzerAssemblyLoader());
public static int Run(string[] args, string clientDir, string workingDir, string sdkDir, string tempDir, TextWriter textWriter, IAnalyzerAssemblyLoader analyzerLoader)
=> Vbc.Run(args, new BuildPaths(clientDir: clientDir, workingDir: workingDir, sdkDir: sdkDir, tempDir: tempDir), textWriter, analyzerLoader);
......
......@@ -13,7 +13,7 @@ public static class AppDomainUtils
public static AppDomain Create(string name = null, string basePath = null)
{
name = name ?? "Custtom AppDomain";
name = name ?? "Custom AppDomain";
basePath = basePath ?? Path.GetDirectoryName(typeof(AppDomainUtils).Assembly.Location);
lock (s_lock)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册