【问题标题】:MSBuild v14 compiles a semantically incorrect assembly under some rare circumstancesMSBuild v14 在极少数情况下会编译语义不正确的程序集
【发布时间】:2016-09-24 05:38:46
【问题描述】:

在构建环境更新后,我们的一项冒烟测试在 TeamCity 中中断。调查发现,来自同一个源代码,

  • C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe 生成正确的二进制文件
  • C:\Program Files (x86)\MSBuild\14.0\bin\MSBuild.exe 生成不正确的二进制文件

什么时候发生

  • 使用“params object[]”
  • 只传递一个值,而不是显式地包装在一个数组中
  • 使用了命名参数
  • 与方法签名中的顺序不同

重现它的示例代码

static void Main(string[] args)
{
    var customerId = Guid.NewGuid();

    // Produces buggy code when compiled with MSBuild v14
    TestMethodWithParams(args: customerId, whatever: "foo");

    //All the calls below result correct behavior, regardless of the version of MSBuild, order and naming of parameters
    TestMethodWithParams("foo", customerId);
    TestMethodWithParams(whatever: "foo", args: customerId);

    TestMethodWithParams(args: new object[] { customerId }, whatever: "foo");
    TestMethodWithParams("foo", new object[] { customerId });
    TestMethodWithParams(whatever: "foo", args: new object[] {customerId});
}

private static void TestMethodWithParams(string whatever, params object[] args)
{
    Console.WriteLine("args: '{0}'", args);
}

究竟发生了什么

不正确的版本只是吞下了单个参数,传递的是null。反编译代码显示差异:

在正确的二进制文件中:

Guid guid = Guid.NewGuid();
Program.TestMethodWithParams("foo", new object[]
{
    guid
});

在不正确的二进制文件中:

Guid guid = Guid.NewGuid();
object obj;
Program.TestMethodWithParams("foo", new object[]
{
    obj // <- this is and will always be null
});

如何解决

当我们将单个参数包装到一个对象数组中时,问题就消失了。另一种选择是不使用命名参数,和/或确保参数的出现顺序在调用和签名中是相同的。

但是:主要问题是我们无法恢复到较旧的 MSBuild (...),并且检查整个代码库(以及检查 NuGet 包中的每一个二进制文件)并不是一件容易的事和有效的解决方案。此外,这种错误可能会在以后的任何时候意外地重新引入代码库。所以最好的解决方案可能是以某种方式修复 MSBuild。

有没有人经历过这样的事情?可能是 MSBuild 中的错误?想法?

【问题讨论】:

  • 你可能想在这里提出问题:github.com/dotnet/roslyn
  • 看来我也可以复制这个。我同意@jessehouwing,你应该在 GitHub 上提出问题。
  • 在这里创建了一个问题:github.com/dotnet/roslyn/issues/11576
  • 关于这里的错误和问题的一个注释:MSBuild 实际上并不生成二进制文件,它只是运行编译器 csc.exe。您为 MSBuild.exe 指向的两条路径将具有不同版本的 csc.exe,实际错误(如果有)所在的位置。这个问题在其他方面很好,当您讨论 MSBuild 版本时,您可能会看到一些有趣的表情。如果您要获取 MSBuild 日志,您会看到不同的编译器路径,这对于错误报告来说更加清晰。
  • 保持你的 VS 版本更新,这个错误肯定在更新 1 或更新 2 中得到修复,因为我没有看到它的迹象,并且错误修复可以追溯到 2015 年 8 月 6 日。

标签: c# compilation msbuild binary roslyn


【解决方案1】:

正如我在 GitHub 问题上已经提到的,我相信这是最初报告为 #4197 并在 Roslyn 1.1 中修复的错误。

【讨论】:

    【解决方案2】:

    感谢您提供的所有信息和建议。您分享了帮助我们追踪此问题的详细信息。原来安装“Microsoft Build Tools 2015 with Update 2”解决了我们的问题。

    再次感谢大家。 /大卫

    【讨论】:

      猜你喜欢
      • 2021-06-26
      • 1970-01-01
      • 1970-01-01
      • 2011-11-02
      • 1970-01-01
      • 1970-01-01
      • 2021-02-23
      • 1970-01-01
      • 2010-11-04
      相关资源
      最近更新 更多