Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>ed69753a3ffbdaa08365252c710d57a64d17f859</Sha>
</Dependency>
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="3.8.0-1.20353.1">
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="3.8.0-1.20361.1">
<Uri>https://github.com/dotnet/roslyn</Uri>
<Sha>09f75b83754732a74e0815976b80ecffd94c0dde</Sha>
<Sha>f24d2c5c98211908ab90d6f1f42e7592411d6058</Sha>
</Dependency>
</ToolsetDependencies>
</Dependencies>
2 changes: 1 addition & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
</MajorVersion>
<MinorVersion>
</MinorVersion>
<MicrosoftNetCompilersToolsetVersion>3.8.0-1.20353.1</MicrosoftNetCompilersToolsetVersion>
<MicrosoftNetCompilersToolsetVersion>3.8.0-1.20361.1</MicrosoftNetCompilersToolsetVersion>
</PropertyGroup>
<PropertyGroup>
<!-- Versions used by several individual references below -->
Expand Down
6 changes: 3 additions & 3 deletions eng/config/PublishData.json
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,12 @@
"vsBranch": "master",
"vsMajorVersion": 16
},
"features/dotnetFormat": {
"features/UsedAssemblyReferences": {
"nugetKind": [ "Shipping", "NonShipping" ],
"version": "3.3.*",
"version": "3.8.*",
"nuget": [ "https://dotnet.myget.org/F/roslyn/api/v2/package" ],
"vsix": [ "https://dotnet.myget.org/F/roslyn/vsix/upload" ],
"channels": [ "dotnetFormat" ],
"channels": [ "UsedAssemblyReferences" ],
"vsBranch": "master",
"vsMajorVersion": 16
},
Expand Down
68 changes: 31 additions & 37 deletions src/Compilers/Core/CommandLine/BuildProtocol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,12 @@ public static BuildRequest Create(RequestLanguage language,
{
Debug.Assert(!string.IsNullOrWhiteSpace(compilerHash), "CompilerHash is required to send request to the build server");

Log("Creating BuildRequest");
Log($"Working directory: {workingDirectory}");
Log($"Temp directory: {tempDirectory}");
Log($"Lib directory: {libDirectory ?? "null"}");
Log($"Compiler hash: {compilerHash}");
Log($@"
Creating BuildRequest
Working directory: {workingDirectory}
Temp directory: {tempDirectory}
Lib directory: {libDirectory ?? null}
Compiler hash: {compilerHash}");

var requestLength = args.Count + 1 + (libDirectory == null ? 0 : 1);
var requestArgs = new List<Argument>(requestLength);
Expand All @@ -108,7 +109,6 @@ public static BuildRequest Create(RequestLanguage language,
for (int i = 0; i < args.Count; ++i)
{
var arg = args[i];
Log($"argument[{i}] = {arg}");
requestArgs.Add(new Argument(ArgumentId.CommandLineArgument, i, arg));
}

Expand All @@ -118,7 +118,7 @@ public static BuildRequest Create(RequestLanguage language,
public static BuildRequest CreateShutdown()
{
var requestArgs = new[] { new Argument(ArgumentId.Shutdown, argumentIndex: 0, value: "") };
return new BuildRequest(BuildProtocolConstants.ProtocolVersion, RequestLanguage.CSharpCompile, GetCommitHash(), requestArgs);
return new BuildRequest(BuildProtocolConstants.ProtocolVersion, RequestLanguage.CSharpCompile, GetCommitHash() ?? "", requestArgs);
}

/// <summary>
Expand All @@ -127,19 +127,17 @@ public static BuildRequest CreateShutdown()
/// The total request size must be less than 1MB.
/// </summary>
/// <returns>null if the Request was too large, the Request otherwise.</returns>
public static async Task<BuildRequest?> ReadAsync(Stream inStream, CancellationToken cancellationToken)
public static async Task<BuildRequest> ReadAsync(Stream inStream, CancellationToken cancellationToken)
{
// Read the length of the request
var lengthBuffer = new byte[4];
Log("Reading length of request");
await ReadAllAsync(inStream, lengthBuffer, 4, cancellationToken).ConfigureAwait(false);
var length = BitConverter.ToInt32(lengthBuffer, 0);

// Back out if the request is > 1MB
if (length > 0x100000)
{
Log("Request is over 1MB in length, cancelling read.");
return null;
throw new ArgumentException("Request is over 1MB in length");
}

cancellationToken.ThrowIfCancellationRequested();
Expand All @@ -150,7 +148,6 @@ public static BuildRequest CreateShutdown()

cancellationToken.ThrowIfCancellationRequested();

Log("Parsing request");
// Parse the request into the Request data structure.
using (var reader = new BinaryReader(new MemoryStream(requestBuffer), Encoding.Unicode))
{
Expand Down Expand Up @@ -182,8 +179,6 @@ public static BuildRequest CreateShutdown()
using (var memoryStream = new MemoryStream())
using (var writer = new BinaryWriter(memoryStream, Encoding.Unicode))
{
// Format the request.
Log("Formatting request");
writer.Write(ProtocolVersion);
writer.Write((uint)Language);
writer.Write(CompilerHash);
Expand All @@ -203,17 +198,12 @@ public static BuildRequest CreateShutdown()
// Back out if the request is > 1 MB
if (memoryStream.Length > 0x100000)
{
Log("Request is over 1MB in length, cancelling write");
throw new ArgumentOutOfRangeException();
throw new ArgumentOutOfRangeException("Request is over 1MB in length");
}

// Send the request to the server
Log("Writing length of request.");
await outStream.WriteAsync(BitConverter.GetBytes(length), 0, 4,
cancellationToken).ConfigureAwait(false);

Log("Writing request of size {0}", length);
// Write the request
memoryStream.Position = 0;
await memoryStream.CopyToAsync(outStream, bufferSize: length, cancellationToken: cancellationToken).ConfigureAwait(false);
}
Expand Down Expand Up @@ -311,8 +301,6 @@ public async Task WriteAsync(Stream outStream,
using (var memoryStream = new MemoryStream())
using (var writer = new BinaryWriter(memoryStream, Encoding.Unicode))
{
// Format the response
Log("Formatting Response");
writer.Write((int)Type);

AddResponseBody(writer);
Expand All @@ -325,16 +313,13 @@ public async Task WriteAsync(Stream outStream,
// Write the length of the response
int length = checked((int)memoryStream.Length);

Log("Writing response length");
// There is no way to know the number of bytes written to
// the pipe stream. We just have to assume all of them are written.
await outStream.WriteAsync(BitConverter.GetBytes(length),
0,
4,
cancellationToken).ConfigureAwait(false);

// Write the response
Log("Writing response of size {0}", length);
memoryStream.Position = 0;
await memoryStream.CopyToAsync(outStream, bufferSize: length, cancellationToken: cancellationToken).ConfigureAwait(false);
}
Expand All @@ -350,14 +335,12 @@ await outStream.WriteAsync(BitConverter.GetBytes(length),
/// <returns></returns>
public static async Task<BuildResponse> ReadAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken))
{
Log("Reading response length");
// Read the response length
var lengthBuffer = new byte[4];
await ReadAllAsync(stream, lengthBuffer, 4, cancellationToken).ConfigureAwait(false);
var length = BitConverter.ToUInt32(lengthBuffer, 0);

// Read the response
Log("Reading response of length {0}", length);
var responseBuffer = new byte[length];
await ReadAllAsync(stream,
responseBuffer,
Expand All @@ -381,7 +364,7 @@ await ReadAllAsync(stream,
case ResponseType.Shutdown:
return ShutdownBuildResponse.Create(reader);
case ResponseType.Rejected:
return new RejectedBuildResponse();
return RejectedBuildResponse.Create(reader);
default:
throw new InvalidOperationException("Received invalid response type from server.");
}
Expand Down Expand Up @@ -505,13 +488,30 @@ protected override void AddResponseBody(BinaryWriter writer) { }

internal sealed class RejectedBuildResponse : BuildResponse
{
public string Reason;

public override ResponseType Type => ResponseType.Rejected;

public RejectedBuildResponse(string reason)
{
Reason = reason;
}

/// <summary>
/// AnalyzerInconsistency has no body.
/// </summary>
/// <param name="writer"></param>
protected override void AddResponseBody(BinaryWriter writer) { }
protected override void AddResponseBody(BinaryWriter writer)
{
WriteLengthPrefixedString(writer, Reason);
}

public static RejectedBuildResponse Create(BinaryReader reader)
{
var reason = ReadLengthPrefixedString(reader);
Debug.Assert(reason is object);
return new RejectedBuildResponse(reason);
}
}

// The id numbers below are just random. It's useful to use id numbers
Expand Down Expand Up @@ -592,14 +592,13 @@ public static void WriteLengthPrefixedString(BinaryWriter writer, string? value)
/// Reads the value of <see cref="CommitHashAttribute.Hash"/> of the assembly <see cref="BuildRequest"/> is defined in
/// </summary>
/// <returns>The hash value of the current assembly or an empty string</returns>
public static string GetCommitHash()
public static string? GetCommitHash()
{
var hashAttributes = typeof(BuildRequest).Assembly.GetCustomAttributes<CommitHashAttribute>();
var hashAttributeCount = hashAttributes.Count();
if (hashAttributeCount != 1)
{
Log($"Error reading CommitHashAttribute. Exactly 1 attribute is required, found {hashAttributeCount}");
return string.Empty;
return null;
}
return hashAttributes.Single().Hash;
}
Expand All @@ -616,21 +615,16 @@ internal static async Task ReadAllAsync(
int totalBytesRead = 0;
do
{
Log("Attempting to read {0} bytes from the stream",
count - totalBytesRead);
int bytesRead = await stream.ReadAsync(buffer,
totalBytesRead,
count - totalBytesRead,
cancellationToken).ConfigureAwait(false);
if (bytesRead == 0)
{
Log("Unexpected -- read 0 bytes from the stream.");
throw new EndOfStreamException("Reached end of stream before end of read.");
}
Log("Read {0} bytes", bytesRead);
totalBytesRead += bytesRead;
} while (totalBytesRead < count);
Log("Finished read");
}
}
}
28 changes: 14 additions & 14 deletions src/Compilers/Server/VBCSCompiler/CompilerRequestHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,27 +96,22 @@ public bool TryCreateCompiler(RunRequest request, out CommonCompiler compiler)

public BuildResponse RunCompilation(RunRequest request, CancellationToken cancellationToken)
{
Log($"CurrentDirectory = '{request.CurrentDirectory}'");
Log($"LIB = '{request.LibDirectory}'");
for (int i = 0; i < request.Arguments.Length; ++i)
{
Log($"Argument[{i}] = '{request.Arguments[i]}'");
}
Log($@"
Run Compilation
CurrentDirectory = '{request.CurrentDirectory}
LIB = '{request.LibDirectory}'");

// Compiler server must be provided with a valid temporary directory in order to correctly
// isolate signing between compilations.
if (string.IsNullOrEmpty(request.TempDirectory))
{
Log($"Rejecting build due to missing temp directory");
return new RejectedBuildResponse();
return new RejectedBuildResponse("Missing temp directory");
}

CommonCompiler compiler;
if (!TryCreateCompiler(request, out compiler))
{
// We can't do anything with a request we don't know about.
Log($"Got request with id '{request.Language}'");
return new RejectedBuildResponse();
return new RejectedBuildResponse($"Cannot create compiler for language id {request.Language}");
}

bool utf8output = compiler.Arguments.Utf8Output;
Expand All @@ -125,11 +120,16 @@ public BuildResponse RunCompilation(RunRequest request, CancellationToken cancel
return new AnalyzerInconsistencyBuildResponse();
}

Log($"****Running {request.Language} compiler...");
Log($"Begin {request.Language} compiler run");
TextWriter output = new StringWriter(CultureInfo.InvariantCulture);
int returnCode = compiler.Run(output, cancellationToken);
Log($"****{request.Language} Compilation complete.\r\n****Return code: {returnCode}\r\n****Output:\r\n{output.ToString()}\r\n");
return new CompletedBuildResponse(returnCode, utf8output, output.ToString());
var outputString = output.ToString();
Log(@$"
End {request.Language} Compilation complete.
Return code: {returnCode}
Output:
{outputString}");
return new CompletedBuildResponse(returnCode, utf8output, outputString);
}
}
}
30 changes: 5 additions & 25 deletions src/Compilers/Server/VBCSCompiler/NamedPipeClientConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ public void Close()
// The client connection failing to close isn't fatal to the server process. It is simply a client
// for which we can no longer communicate and that's okay because the Close method indicates we are
// done with the client already.
var msg = string.Format($"Pipe {LoggingIdentifier}: Error closing pipe.");
CompilerServerLogger.LogException(e, msg);
CompilerServerLogger.LogException(e, $"Pipe {LoggingIdentifier}: Error closing pipe.");
}
}

Expand All @@ -124,14 +123,12 @@ public void Close()
BuildRequest request;
try
{
Log("Begin reading request.");
request = await BuildRequest.ReadAsync(_stream, cancellationToken).ConfigureAwait(false);
ValidateBuildRequest(request);
Log("End reading request.");
}
catch (Exception e)
{
LogException(e, "Error reading build request.");
CompilerServerLogger.LogException(e, "Error reading build request.");
return new ConnectionData(CompletionReason.CompilationNotStarted);
}

Expand All @@ -149,7 +146,7 @@ public void Close()
}
else if (!allowCompilationRequests)
{
return await HandleRejectedRequestAsync(cancellationToken).ConfigureAwait(false);
return await HandleRejectedRequestAsync("Compilation requests not allowed at this time", cancellationToken).ConfigureAwait(false);
}
else
{
Expand Down Expand Up @@ -181,10 +178,8 @@ private async Task<ConnectionData> HandleCompilationRequestAsync(BuildRequest re

try
{
Log("Begin writing response.");
await response.WriteAsync(_stream, cancellationToken).ConfigureAwait(false);
reason = CompletionReason.CompilationCompleted;
Log("End writing response.");
}
catch
{
Expand Down Expand Up @@ -216,9 +211,9 @@ private async Task<ConnectionData> HandleIncorrectHashRequestAsync(CancellationT
return new ConnectionData(CompletionReason.CompilationNotStarted);
}

private async Task<ConnectionData> HandleRejectedRequestAsync(CancellationToken cancellationToken)
private async Task<ConnectionData> HandleRejectedRequestAsync(string reason, CancellationToken cancellationToken)
{
var response = new RejectedBuildResponse();
var response = new RejectedBuildResponse(reason);
await response.WriteAsync(_stream, cancellationToken).ConfigureAwait(false);
return new ConnectionData(CompletionReason.CompilationNotStarted);
}
Expand Down Expand Up @@ -266,29 +261,14 @@ private Task<BuildResponse> ServeBuildRequestAsync(BuildRequest buildRequest, Ca
{
Func<BuildResponse> func = () =>
{
// Do the compilation
Log("Begin compilation");

var request = BuildProtocolUtil.GetRunRequest(buildRequest);
var response = _compilerServerHost.RunCompilation(request, cancellationToken);

Log("End compilation");
return response;
};

var task = new Task<BuildResponse>(func, cancellationToken, TaskCreationOptions.LongRunning);
task.Start();
return task;
}

private void Log(string message)
{
CompilerServerLogger.Log("Client {0}: {1}", _loggingIdentifier, message);
}

private void LogException(Exception e, string message)
{
CompilerServerLogger.LogException(e, string.Format("Client {0}: {1}", _loggingIdentifier, message));
}
}
}
Loading