应用程序崩溃并显示“ .NET Runtime 内部错误”

127
我们有一个应用程序是针对.NET 4.0编写的,在周末发生了崩溃,导致以下信息记录在事件日志中:
Application: PnrRetrieverService.exe Framework Version: v4.0.30319 Description: The process was terminated due to an internal error in the .NET Runtime at IP 791F9AAA (79140000) with exit code 80131506.
这是在安装Windows Server 2003 R2 Standard Edition的服务器上发生的。尝试谷歌搜索此错误并没有找到任何相关的内容。例如,这不是在VS Studio中发生的,而是在生产服务器上发生的。当服务最终重新启动后,就再也没有出现过问题。
如何诊断.NET Runtime中的故障?

1
如果这是第一次出现此错误,则我会调查最近几天到一周内发生的任何变化。 - Tony Abrams
18个回答

140

使用退出代码80131506。

这是一个讨厌的 ExecutionEngineException 错误。从 .NET 4.0 开始,此异常会立即终止程序。其通用原因是垃圾回收堆状态的损坏,而这种损坏又不可避免地由非托管代码引起。导致此异常抛出的确切代码位置没有帮助,损坏通常在检测到损坏之前就已发生。

找到导致此问题的确切原因将会很困难。请检查您的服务是否使用任何非托管代码。如果没有明显的候选项,则可能涉及环境问题,如行为异常的恶意软件扫描器。如果此问题频繁重现,则应怀疑硬件问题,例如软RAM错误。


3
我曾经遇到过SQL CE 3.5的问题,导致堆损坏,引起ntdll.dll异常和.NET运行时错误。 - Phil
4
它们被列在 SDK 头文件 CorError.h 中。 - Hans Passant
2
你是怎么知道它们被列在CorError.h中的? - Yeonho
6
使用此 Err.exe 工具 http://www.microsoft.com/en-au/download/details.aspx?id=985 来查找十六进制错误代码(如 80131506)的含义以及包含它们的头文件。 - Jeremy Thompson
2
@HansPassant,我认为问题的意图是“在世界上所有文件中,您如何知道CorError.h是一个值得查看的文件?” - bacar
显示剩余2条评论

44
x64 .Net 4 的并发垃圾回收实现中存在一个错误,如下面的微软 KB 条目所述:

在垃圾回收期间发生 ExecutionEngineException

你应该首先进行深度 minidump 探索,以确保问题发生在垃圾回收期间。
崩溃后,可以在事件日志中的 Windows 错误报告条目中找到 Minidump 位置。 然后,尽情享受 WinDbg 吧!
关于使用 <gcConcurrent/> 配置元素的最新文档,以禁用并发或(在 .NET 4 及更高版本中)后台垃圾回收,请查看 此处

1
谢谢您的评论 - 这是我长期以来一直遇到的问题的解决方案! - lenniep
2
你真是救星,这正是我们的问题所在。另外,你也可以在Visual Studio中打开minidump文件,如果需要,设置符号路径,然后进行调试。这告诉我们错误发生在clr.dll!WKS::gc_heap::mark_object_simple()。我相信WinDbg非常强大,但如果你只是验证错误源,使用VS就足够了。 - Tim
应用程序崩溃了,但我在C:\Temp\CrashDump文件夹中没有找到任何迷你转储。那里有一些其他的崩溃转储,我们可以找到几天前崩溃的转储。你知道为什么没有崩溃转储吗?错误消息和退出代码完全相同。 - Jeffrey Zhao
1
这正是我一直在寻找的... 应用程序崩溃事件包含了指令指针,但如果没有转储,对我来说毫无用处。从未想过要寻找后续事件。谢谢! - laindir
2
对于处于相同情况的其他人来说,配置Windows错误报告以在崩溃时执行完整堆转储可能很有用:https://msdn.microsoft.com/en-us/library/windows/desktop/bb787181(v=vs.85).aspx - laindir
好的,我得到了相同的错误。之后使用WinDbg打开转储文件,调用堆栈中的最后一行是:clr!JIT_ChkCastClassSpecial + 0x10。有什么想法吗? - QtRoS

11

我曾经在.NET运行时中遇到“内部错误”,后来发现这是由于我的代码中存在漏洞所导致的;不要认为仅仅因为在.NET运行时中出现了“内部错误”,就不存在你的代码作为根本原因的漏洞。在指责他人之前,一定要始终始终怀疑自己的代码。

希望你有日志记录、异常/堆栈跟踪信息可以指引你从哪里开始查找,或者你可以重复系统崩溃前的状态。


你代码中的那些 bug,它们是在完全托管的代码中出现的,还是涉及到非托管的代码? - Evgeniy Berezovsky

8

最新版本的.NET 4代码在WinXP上出现了完全相同的错误。检查之前的构建 - 现在它们也崩溃了!好吧,不是我的问题 :)。这里/上面的建议都没有帮助。

同样问题的更近期报告(2018-05-09):应用程序崩溃并显示退出代码80131506

A:我们收到了类似的错误,但我们认为这是由Citrix内存优化器引起的。解决方法是在发生问题的主机上强制重新生成.Net核心库:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.exe update /force

根本原因仍未知(机器没有更新且使用很少),但对我而言这行得通了


8

6
经过多年在许多应用程序中解决这个问题,看起来微软终于承认这是 .NET 4 CLR 中的一个 bug 导致了这种情况http://support.microsoft.com/kb/2640103
我以前一直通过强制垃圾收集器在服务器模式下运行(在 app.config 中启用 gcServer="true")来“修复”它,正如 Think Before Coding 链接的微软文章所述。这实质上迫使应用程序中的所有线程在收集期间暂停,消除了其他线程访问 GC 操作内存的可能性。我很高兴发现,我多年来徒劳地寻找我的代码或其他第三方非托管库中的“bug”,只是因为该 bug 存在于微软的代码中,而不是我的代码。

1
你收到的HotFix文件版本号是多少?KB中列出的版本号是4.0.30319.526,但我已经有了4.0.30319.18052。是否仍需要此HotFix或已被包含在Windows更新中? - Automate
1
当我运行 HotFix exe 时,我收到“KB2640103 不适用,或被计算机上的其他条件阻止。” - Automate

4

2
在我的情况下,当磁盘空间不足时,.NET无法在Windows虚拟内存中分配内存,导致了这个异常。
在事件日志中,我看到了这个错误:
应用程序弹出窗口:Windows - 虚拟内存最小值过低:您的系统虚拟内存不足。Windows正在增加您的虚拟内存分页文件的大小。在此过程中,某些应用程序的内存请求可能会被拒绝。
之前的错误是:
C:磁盘已满或接近容量。您可能需要删除一些文件。

1

我不确定这对每个人都有帮助,但我可以通过运行以下代码来解决这个问题:

devenv.exe /ResetSettings 

...在路径{Visual_Studio_root}\Common7\Ide

我的事件日志中出现了以下错误,而且VS一直崩溃和重启:

Faulting application name: devenv.exe, version: 14.0.25123.0, time stamp: 0x56f22f32
Faulting module name: clr.dll, version: 4.7.2115.0, time stamp: 0x59af88f2
Exception code: 0xc0000005
Fault offset: 0x0015f90e
Faulting process id: 0x3a7c
Faulting application start time: 0x01d353463eaf0c36
Faulting application path: C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe
Faulting module path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Report Id: a232f984-6e80-4f61-9003-e18a035c8f93
Faulting package full name: 
Faulting package-relative application ID: 

这对我也起作用了。背景:我将一个中等大小的解决方案(大约25个项目)转换为.NET Core SDK,由几乎空白的 Web 应用程序项目担任前端,替换了转换前的旧 WAP。显然,一些持久设置与新项目中 IISExpress 的期望发生了冲突。 - Tomas Aschan

1
在我的情况下,问题是由于web.config中的重复绑定重定向引起的。更多信息在这里
我认为这是因为NuGet修改了绑定重定向,但例如它看起来像这样:
  <dependentAssembly>
    <assemblyIdentity name="Lucene.Net" publicKeyToken="85089178b9ac3181"/>
    <bindingRedirect oldVersion="0.0.0.0-2.9.4.0" newVersion="3.0.3.0"/>
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed"/>
    <bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0"/>
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
    <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.0.0.0"/>
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="Lucene.Net" publicKeyToken="85089178b9ac3181"/>
    <bindingRedirect oldVersion="0.0.0.0-2.9.4.0" newVersion="3.0.3.0"/>
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed"/>
    <bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0"/>
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
    <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.0.0.0"/>
  </dependentAssembly>

删除所有重复项解决了问题。


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