错误 MSB4166: 子节点过早退出。正在关闭。

35
有时我的构建会出现这个错误。
 0>MSBUILD : error MSB4166: Child node "3" exited prematurely. Shutting down.

这似乎是完全随机的,我无法随意重现。我正在运行VS2010 Win7 x64 MSBuild 4.0,但这个问题似乎与平台和操作系统无关。我并行构建解决方案(/m开关+BuildInParallel=True),我不想禁用此功能,因为我正在编译包含800多个项目的应用程序。有什么办法可以解决它吗?

编辑:当我安装了.NET 4.5开发人员预览版时,MSBuild 4.5中的错误日志记录得到了改进,现在错误字符串看起来像这样:

error MSB4166: Child node "3" exited prematurely. Shutting down. Diagnostic information may be found in files in the temporary files directory named MSBuild_*.failure.txt

我可以在Temp文件夹中找到错误日志文件。以下是MSBuild_*.failure.txt文件的内容:

System.InvalidOperationException: BuildEventArgs has formatted message while serializing!
   at Microsoft.Build.Framework.LazyFormattedBuildEventArgs.WriteToStream(BinaryWriter writer)
   at Microsoft.Build.Framework.BuildMessageEventArgs.WriteToStream(BinaryWriter writer)
   at Microsoft.Build.Shared.LogMessagePacketBase.WriteToStream(INodePacketTranslator translator)
   at Microsoft.Build.BackEnd.NodeEndpointOutOfProcBase.PacketPumpProc()

我也遇到了同样的问题。我还看到与此错误相关的内存不足异常。将其限制为一个同时构建并没有帮助;它仍然会出错:在这里查看截图;当内存消耗超过物理可用内存时,错误就会发生。它曾经几次濒临死亡,然后达到最大值并死亡,带着 Outlook 和 Process Explorer 一起崩溃,提供一个无法启动的 JIT 调试器,并释放 MSBuild.exe 成为一个僵尸进程,占用内存直到我手动杀死它。 - Kevin Vermeer
奇怪的是,我正在使用64位MSBuild在64位Win7笔记本电脑上,具有4GB的物理内存和“无限”的虚拟内存。 MSBuild进程正在使用约1GB的内存(1.5GB峰值)。 - Ludwo
我正在使用32位MSBuild在一台2GB物理内存和同样无限虚拟内存的32位WinXP桌面上。奇怪的是,当物理内存完全用尽时,崩溃就会发生。这就像我没有虚拟内存一样! - Kevin Vermeer
是的,看起来 MSBuild 没有使用虚拟内存 :) - Ludwo
2
但这并不是真的。我已经检查过了,如果有800MB的可用物理内存,它会在这个问题上失败。 - Ludwo
9个回答

14
经过长时间的研究和尝试,我找到了一个对我有效的解决方法。我正在使用带有/m和/p:BuildInParallel=true的msbuild,在CI服务器上构建一直失败。它总是在第二个组件中出现以下错误: error MSB4166: 子节点“3”过早退出。正在关闭。
添加/nodeReuse:false解决了这个问题。 这是一个不错的参考: https://blogs.msdn.microsoft.com/msbuild/2007/04/16/node-reuse-in-multiproc-msbuild/

3
Jenkins甚至停止了结束时对每栋建筑物的冷冻。一举两得。在构建机器上必须使用MSBUILDDISABLENODEREUSE=1-nodeReuse:false - it3xl
一个更短的语法 /nr:false 也在 https://blogs.msdn.microsoft.com/msbuild/2007/04/16/node-reuse-in-multiproc-msbuild/ 中说明。 - Wasabi
请注意,在使用2018年4月之前的MSBuild版本时,即使将标志设置为false,问题仍可能发生:https://github.com/microsoft/msbuild/issues/3140和https://github.com/microsoft/msbuild/pull/3158。 - Carlos Quintero
发现以下相关的开放问题:https://github.com/dotnet/msbuild/issues/455 - Joerg S

4

如在评论交流中所讨论的:

奇怪的是,我正在使用64位MSBuild在64位Win7笔记本电脑上,物理内存为4GB,虚拟内存“无限制”。MSBuild进程正在使用约1GB的内存(峰值为1.5GB)。-Ludwo 4小时前

我正在使用32位MSBuild在32位WinXP桌面上,物理内存为2GB,虚拟内存同样无限制。奇怪的是,当物理内存完全用完时就会崩溃。就像我没有虚拟内存一样!-Kevin Vermeer 3小时前

是的,看来MSBuild似乎没有使用虚拟内存:)-Ludwo 2小时前

似乎确实是MSBuild没有使用虚拟内存。我进行了一些测试(启动一堆程序),似乎没有任何东西使用虚拟内存。我进行了一些搜索,发现需要检查:

Control Panel -> System -> Advanced -> Performance -> Advanced -> Virtual Memory

我发现存在一个设置限制了系统范围内的虚拟内存大小。我原本认为虚拟内存应该是无限的,或者更准确地说,在32位XP中每个进程可使用4GB。但实际上我没有接近这个极限。然而,我的虚拟内存空间被限制为...0MB。不管是谁或是什么让它变成这样都不太好。

我将其更改为分配至少1024 MB和最多4096 MB的虚拟内存。我在Process Explorer中添加了“虚拟大小”列,与“系统提交”图表一起展示,现在我使用的内存超过了物理RAM条可用的数量。

这解决了我的问题。不幸的是,每当尝试进行任何内存分页时,我的系统几乎停滞不前,但这总比崩溃好。我重新启用了并行构建;它会在我还有剩余RAM时并行化并大量使用CPU(对于大多数文件来说是正确的),当我没有RAM时则会降至1%的CPU使用率。完成这些文件后,速度就会恢复。


@Ludwo - 这是一件好事,这种错误可能有很多可能的原因,但你尝试手动设置了吗? - Kevin Vermeer
这不是虚拟机设置问题。我有800MB的可用内存。现在我将检查是否是由32位扩展引起的... - Ludwo

2

对于我的情况,答案是更新Antlr。显然,这仅适用于您的项目中使用了Antlr。


2
如果有人遇到这个错误,其他答案都不起作用,那么对我来说,唯一可靠的解决方法是设置 -maxCpuCount:1 (-m:1) (MSBuild命令行参考)。

这是在Debian 10 (buster)上使用dotnet core 6.0.300时的情况。

另外,供参考:如果有人不知道如何在使用dotnet cli时应用MSBuild标志,可以将它们附加到许多内部使用MSBuild的命令(1)后面(使用-/),例如:

# shell
dotnet restore "example/example.csproj" -maxCpuCount:1
dotnet build "example/example.csproj" /maxCpuCount:1 /nodeReuse:false

(1) 异常似乎是将其他dotnet *命令组合在一起的命令,例如dotnet run;大部分内容可以在dotnet build参考文档中找到。


2
最初的回答:无
我们遇到了同样的msbuild错误,在日志文件中有以下内容:
UNHANDLED EXCEPTIONS FROM PROCESS 10260:
=====================
05/01/2019 18:41:55
System.IO.IOException: Pipe is broken.
  at System.IO.Pipes.PipeStream.WinIOError(Int32 errorCode)
  at System.IO.Pipes.PipeStream.BeginWriteCore(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
  at System.IO.Pipes.PipeStream.WriteCore(Byte[] buffer, Int32 offset, Int32 count)
  at System.IO.Pipes.PipeStream.Write(Byte[] buffer, Int32 offset, Int32 count)
  at Microsoft.Build.BackEnd.NodeEndpointOutOfProcBase.RunReadLoop(Stream localReadPipe, Stream localWritePipe, ConcurrentQueue`1 localPacketQueue, AutoResetEvent localPacketAvailable, AutoResetEvent localTerminatePacketPump)
===================

我们通过设置环境变量MSBUILDDISABLENODEREUSE=1来禁用msbuild-node重用功能,解决了这个问题。"最初的回答"

1
或者 -nodeReuse:false - it3xl

1

也许这就是构建等效于竞态条件的情况?

http://blogs.msdn.com/b/msbuild/archive/2007/04/26/building-projects-in-parallel.aspx

如果您在依赖于另一个项目的输出的情况下,使用普通的Reference标签代替ProjectReference标签,那么通常情况下,X项目会先于依赖其输出的Y项目完成构建。但是偶尔它们会并行构建,在这种情况下,当Y项目需要查找X项目的输出时,X项目的输出可能还不存在,导致Y项目失败。我无法找到MSBuild在这种情况下会输出什么样的错误信息(目前也没有可用的测试方法),所以这可能不是原因。

尽管如此,结果的不一致性(通常成功,偶尔失败)让我怀疑类似这样的问题很可能是原因。


不,我有很多项目在多个解决方案中。我使用合并任务来合并解决方案,并在每次构建之前创建一个大的解决方案,以便能够并行构建所有项目。在合并解决方案任务中,如果可能的话,我将所有引用转换为项目引用。因此,在解决方案合并后,我的项目文件会像您链接文章中的示例2所描述的那样更新。 - Ludwo
+1给你的答案,因为你间接地向我解释了为什么只有一个MSBuild实例处于活动状态,而其他实例处于空闲状态。在讨论中,我找到了这个错误的链接。它在v4.0之后的未来MSBuild版本中得到了修复。我必须将我的项目分成较小的部分以提高msbuild性能:( - Ludwo
@Ludwo - 如果有帮助的话,我在找到并修复这个问题时有8个项目在我的解决方案中。它们分为大约800个文件和16000行代码;其中约40%包含在一个项目中。 - Kevin Vermeer
谢谢!所以当这个大项目首次编译时,所有其他依赖项目都在等待它,这是正常的。 - Ludwo

1

你的内存可能不足,导致构建子进程之一失败 - 如果使用 /m:2 限制为两个并发构建,它是否会更少失败?(假设你有超过2个核心)

或者,如果你可以从另一台机器借用一些RAM,或增加交换空间,在构建机器上安装更多内存时,它是否会更少发生?


我只有两个核心。我的构建有时会因为内存不足异常而失败。我将进行一些调查,然后告诉你... - Ludwo
我有很多空闲的内存,但我的构建失败了。这可能与32位进程内存限制有关,因为我的构建正在使用超过2GB的RAM。但我不明白这是如何可能的,因为我的MSBuild进程是64位的。 - Ludwo

0

我想分享一下我的情况和解决方案,希望能帮助那些无法通过其他回答解决此问题的人。

对我来说,问题出在我不小心将一个.NET Framework 4.6.1项目的项目引用添加到了我的一个.NET Standard 2.0项目中。截至本文撰写时,在VS 2017 15.9.12中,您可能只会在您的引用中看到一个“黄色三角形”符号,表明有些地方可能出了问题。我有一个包含多个项目的解决方案,在构建解决方案的过程中,它会在随机的项目上失败,并且从未在哪里失败过。

一旦我追踪到问题是由.NET Framework 4.6.1引用的项目引起的,我就将这个.NET Framework 4.6.1项目转换为.NET Standard 2.0,所有这些Child Node X错误都消失了。

希望这能帮助到任何阅读此文的人。


0

我能够通过在Visual Studio命令提示符中执行以下命令来解决这个问题。

gacutil /i "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\Microsoft.Build.Framework.dll"
gacutil /i "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\Microsoft.Build.dll"
gacutil /i "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\Microsoft.Build.Engine.dll"
gacutil /i "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\Microsoft.Build.Conversion.Core.dll"
gacutil /i "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\Microsoft.Build.Tasks.Core.dll"
gacutil /i "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\Microsoft.Build.Utilities.Core.dll"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接