【问题标题】:error MSB4166: Child node exited prematurely. Shutting down错误 MSB4166:子节点过早退出。关机
【发布时间】:2011-12-16 12:45:12
【问题描述】:

有时我的构建会因此错误而失败。

 0>MSBUILD : error MSB4166: Child node "3" exited prematurely. Shutting down.

它似乎是完全随机的,我无法随意复制它。我正在运行 VS2010 Win7 x64 MSBuild 4.0,但这个问题似乎与平台和操作系统无关。我正在并行构建解决方案(/m switch + 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()

【问题讨论】:

  • 我也遇到了同样的问题。我还看到了与此错误相关的内存不足异常。将其限制为一个同时构建并没有帮助。它仍然出错:See the screenshot here;当内存消耗超过物理可用内存时,就会发生错误。它与死亡进行了几次近距离接触,然后达到最大值并死亡,同时关闭了 Outlook 和进程资源管理器,提供了一个无法启动的 JIT 调试器,并释放 MSBuild.exe 成为坐在内存中的僵尸进程直到我手动杀死它。
  • 奇怪的是,我在具有 4GB 物理和“无限”虚拟 RAM 的 64 位 Win7 笔记本电脑上使用 64 位 MSBuild。 MSBuild 进程正在使用大约 1GB 的 RAM(峰值为 1.5GB)。
  • 我在 32 位 WinXP 桌面上使用 32 位 MSBuild,具有 2GB 物理和类似无限的虚拟 RAM。奇怪的是,当物理 RAM 完全用完时会发生崩溃。就像我的虚拟内存为零!
  • 是的,似乎 MSBuild 没有使用虚拟内存 :)
  • 但事实并非如此。我检查了它,如果它有 800MB 的可用物理内存,它在这个问题上失败了。

标签: multithreading msbuild msbuild-4.0


【解决方案1】:

经过大量时间和研究试图解决这个问题,我找到了一个适合我的解决方案。 我正在使用带有 /m 和 /p:BuildInParallel=true 的 msbuild,并且构建在 CI 服务器中失败。它总是在第二个组件中失败并出现错误:

错误 MSB4166:子节点“3”过早退出。正在关机。

添加 /nodeReuse:false 解决了问题。

这是一个很好的参考: https://blogs.msdn.microsoft.com/msbuild/2007/04/16/node-reuse-in-multiproc-msbuild/

【讨论】:

【解决方案2】:

如交流中讨论的cmets给的问题:

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

我在 32 位 WinXP 桌面上使用 32 位 MSBuild,具有 2GB 物理和类似无限的虚拟 RAM。奇怪的是,当物理 RAM 完全用完时会发生崩溃。就像我的虚拟内存为零! – 凯文维米尔 3 小时前

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

似乎 MSbuild 没有使用虚拟内存。我做了一些测试(启动了一堆程序),似乎 nothing 正在使用虚拟内存。我做了一些搜索,导致我检查

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

发现存在一个限制我的虚拟内存大小系统范围的设置。我曾想象虚拟内存实际上是无限的,或者更准确地说,在 32 位 XP 上,每个进程的虚拟内存为 4 GB。我没有接近这个极限。但是,我的虚拟内存空间被限制为... 0MB。不酷,不管是谁做的。

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

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

【讨论】:

  • @Ludwo - 这是一件好事,这种错误肯定有很多可能的原因,但是您是否尝试过手动设置?
  • 不是虚拟机设置问题。我有 800MB 的可用内存。现在我将检查它是否是由 32 位扩展引起的......
【解决方案3】:

就我而言,答案是更新 Antlr。显然,这只适用于您在项目中使用 Antlr 的情况。

【讨论】:

    【解决方案4】:

    我们得到了同样的 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 重用功能来解决此问题。

    【讨论】:

    • -nodeReuse:false
    【解决方案5】:

    您可能内存不足,导致其中一个构建子进程失败 - 如果您使用 /m:2 将其限制为两个并发构建,它的失败会更少吗? (假设您有 2 个以上的核心)

    或者,如果您可以从另一台机器借用一些 RAM,或者增加交换大小,那么当您在构建机器上安装更多内存时,这种情况发生的频率会降低吗?

    【讨论】:

    • 我只有 2 个核心。我的构建有时会因内存不足异常而失败。我会做一些调查,我会告诉你...
    • 我有很多可用内存,但我又失败了。它应该与 32 位进程内存限制有关,因为我的构建使用超过 2GB 的 RAM。但我不明白这怎么可能,因为我的 MSBuild 进程是 64 位的。
    【解决方案6】:

    也许这是竞争条件的构建等效项?

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

    如果您使用普通的 Reference 标签来依赖于作为构建一部分的另一个项目的输出(而不是 ProjectReference 标签),您可能会遇到通常项目 X 在项目 Y 之前完成的情况(这取决于在项目 X 的​​输出上),但有时它们会同时构建,在这种情况下,当 Y 去寻找 X 的输出时,X 的输出将不存在,导致 Y 失败。我找不到任何关于 MSBuild 在那种情况下给出的错误输出的任何信息(并且现在没有现成的方法来测试它),所以可能不是这样。

    结果的不一致(通常成功,偶尔失败)让我怀疑可能是这样的原因。

    【讨论】:

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

    只是想为那些无法通过此处的其他回复解决此问题的人添加我的案例和解决方案。

    对我来说,这是因为我无意中将 .NET Framework 4.6.1 项目的项目引用添加到了我的一个 .NET Standard 2.0 项目中。在撰写本文时以及 VS 2017 15.9.12 时,您可能几乎没有注意到这是参考文献中解决方案资源管理器中显示的“黄色三角形”符号,表示可能有问题。我有一个包含多个项目的解决方案,在构建解决方案的中间某个地方,它会因“子节点 X 过早退出”而失败,在随机项目上,并且在失败的地方永远不会一致。

    一旦我将错误追溯到有问题的 .NET Framework 4.6.1 引用项目,我将这个 .NET Framework 4.6.1 项目转换为 .NET Standard 2.0,所有这些子节点 X 错误都消失了。

    希望这对阅读的人有所帮助。

    【讨论】:

      猜你喜欢
      • 2020-11-27
      • 2014-11-19
      • 1970-01-01
      • 2016-04-26
      • 2014-09-23
      • 2014-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多