// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
namespace Microsoft.CodeAnalysis.CommandLine
{
/// <summary>
/// This trace listener is useful in environments where we don't want a dialog but instead want
/// to exit with a reliable stack trace of the failure. For example during a bootstrap build where
/// the assert dialog would otherwise cause a Jenkins build to timeout.
/// </summary>
internal sealed class ExitingTraceListener : TraceListener
{
internal ICompilerServerLogger Logger { get; }
internal ExitingTraceListener(ICompilerServerLogger logger)
{
Logger = logger;
}
public override void Write(string message)
{
Exit(message);
}
public override void WriteLine(string message)
{
Exit(message);
}
internal static void Install(ICompilerServerLogger logger)
{
Trace.Listeners.Clear();
Trace.Listeners.Add(new ExitingTraceListener(logger));
}
private void Exit(string originalMessage)
{
var builder = new StringBuilder();
builder.AppendLine($"Debug.Assert failed with message: {originalMessage}");
builder.AppendLine("Stack Trace");
var stackTrace = new StackTrace();
builder.AppendLine(stackTrace.ToString());
var message = builder.ToString();
Logger.Log(message);
// Use FailFast so that the process fails rudely and goes through
// windows error reporting (on Windows at least). This will allow our
// CI environment to capture crash dumps for future investigation
Environment.FailFast(message);
}
}
}
|