2013-10-03 119 views
21

我有一个长期运行的.NET 4.5应用程序随机崩溃,留下了我在问题标题中提到的消息。这个问题在3个不同的机器和2个不同的系统(2008 R2和2012)上复制。应用程序不使用任何不安全/非托管组件,它是纯粹的托管.NET,唯一不受管理的东西是CLR本身。.NET 4.5:.NET运行时的内部错误(80131506)/禁用并发的GC

下面是我从转储中提取的坠机现场的堆栈跟踪:

clr.dll!MethodTable::GetCanonicalMethodTable() 
clr.dll!SVR::CFinalize::ScanForFinalization() - 0x1a31b bytes 
clr.dll!SVR::gc_heap::mark_phase() + 0x328 bytes 
clr.dll!SVR::gc_heap::gc1() + 0x95 bytes 
clr.dll!SVR::gc_heap::garbage_collect() + 0x16e bytes 
clr.dll!SVR::gc_heap::gc_thread_function() + 0x3e bytes  
clr.dll!SVR::gc_heap::gc_thread_stub() + 0x77 bytes  
kernel32.dll!BaseThreadInitThunk() + 0x1a bytes  
ntdll.dll!RtlUserThreadStart() + 0x21 bytes  

这个问题非常类似于讨论here的人,所以我想这个话题在建议的解决方案,但他们没有帮助:

  • 我已经尝试安装this修补程序,但它不会对我的任何机器上安装(KB2640103不适,或阻止另一个条件您的计算机上),这实际上有道理,是的因为我使用4.5,而不是4.0。

  • 我试过禁用并发GC和/或启用服务器GC。现在我的app.config相关的部分看起来像这样:

    <?xml version="1.0"?> 
    <configuration>   
        <runtime> 
         <gcConcurrent enabled="false"/> 
         <gcServer enabled="true" /> 
        </runtime> 
    <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/> </startup></configuration> 
    

虽然奇怪的是我仍然觉得在这个过程中转储多个GC相关的线程。除了发生在崩溃的一个,有7个线程与以下堆栈跟踪:

ntdll.dll!NtWaitForSingleObject() + 0xa bytes 
KERNELBASE.dll!WaitForSingleObjectEx() + 0x9a bytes  
clr.dll!CLREventBase::WaitEx() + 0x13f bytes 
clr.dll!CLREventBase::WaitEx() + 0xf7 bytes  
clr.dll!CLREventBase::WaitEx() + 0x78 bytes  
clr.dll!SVR::t_join::join() + 0xd8 bytes 
clr.dll!SVR::gc_heap::scan_dependent_handles() + 0x65 bytes  
clr.dll!SVR::gc_heap::mark_phase() + 0x347 bytes 
clr.dll!SVR::gc_heap::gc1() + 0x95 bytes 
clr.dll!SVR::gc_heap::garbage_collect() + 0x16e bytes 
clr.dll!SVR::gc_heap::gc_thread_function() + 0x3e bytes  
clr.dll!SVR::gc_heap::gc_thread_stub() + 0x77 bytes  
kernel32.dll!BaseThreadInitThunk() + 0x1a bytes  
ntdll.dll!RtlUserThreadStart() + 0x21 bytes  

这让我想知道如果我能以某种方式搞砸了禁用并发GC(这是我真正所列出的配置为)。

我认为这包括了我迄今为止设法找到的东西。我真的可以用一些帮助来解决这个问题。

+4

GC堆上的托管对象的对象头已损坏,无法再找到该类型的方法表。您总是先查找与之互操作的非托管代码以查看原因:修改gc config并不能解决问题 –

+0

也许在终结器中存在问题?你可以​​尝试在终结器中设置断点或将它们注释掉 – DSway

+0

'scan_dependent_handles':依赖句柄最近被添加到CLR 4.0?)。也许这是CLR的一个真正的bug。 – usr

回答

3

我从我过去的经验中吸取了应用的经验。如果一个异常不能处理直到终结器级别,并且如果它发生了,那么这可能会导致应用程序崩溃。

GC上的配置做任何事情之前..

一个快速检查...... 是否使用任务并行库如果是,请确保您正确处理异常。如果来自不同线程的异常未处理,它将一直持续到Finalizer,然后崩溃应用程序。有几种方法可以很好地处理它们。处理“聚合”异常是一种方式(我们曾经解决!)。

http://msdn.microsoft.com/en-us/library/dd537614.aspx

我没有50分加注释,所以将其作为一个答案...

+0

这个问题的确在我启用了一个使用TPL的组件之后才开始发生,但我认为这里没有出现未处理的异常。原因是:1.对任务执行的所有回调函数都包含在try-catch块中; 2.我订阅了AppDomain.Current.UnhandledException,并在此任务异常+终结器案例中触发了AFAIR; 3.我不明白它是如何破坏托管堆的,这似乎是在这里发生的。 – HellBrick

+0

1)你是否说AppDomain.Current.UnhandledException被触发?这意味着一些未处理的事情,记录并获取更多数据。 2)终结者的例外是致命的。 3)在你的dump分析'!threads'中检查Finalizer线程和!pe你应该看到异常。如果是这样的话:) ..让我知道.. – SridharVenkat

+0

我的意思是我有一个AppDomain.Current.UnhandledException处理程序,但它不会在我的应用程序中触发,即使它应该是如果它是一个简单的终结器异常(我我刚刚通过以下测试应用程序对此进行了双重检查:[http://pastebin.com/9EgzBZQA](http://pastebin.com/9EgzBZQA))。还是未处理的任务异常以其他方式传播,但不包括将它们从终结器中抛出?关于转储探索的建议:稍后我会尝试它们,首先我需要研究它们对于他们来说意味着什么=)(这整个转储对我来说是新的) – HellBrick

0

解决方案,帮助我:卸载.NET 4.5.1,安装4.0 ,安装提到的修补程序,安装4.5.1回来。

0

我刚刚与微软完成了一次对话,因为我已经能够重现一个类似的问题。

在我的情况下,它是.NET运行时的一个错误,它与混合动态类型和非动态代码有关。我不确定在您的情况下是否也存在这种情况,但您可能想尝试以下某种方法:

  • 在Windows 8.1(最新更新)上运行代码。显然,Windows 8.1比其他版本的Windows有更新的.NET版本。
  • 如果您使用AssemblyBuilder(与我一样),请尝试将其更改为Run模式,而不是RunAndCollect
  • 将运行时更改为x86或x64,然后重试;你也可以像你已经尝试过的那样使用并发GC设置。
  • 我们的问题正在解决,因为我们说话,这基本上意味着会有一个窗口更新照顾它。也许这也是一个简单的等待的选择;我不期望花太长时间,因为这对很多程序来说都非常重要。
0

我意识到这是一个老帖子,但我遇到了相同的问题的任择议定书。点atlaste取得:

将运行时更改为x86或x64,然后再试一次;你也可以像你已经尝试过的那样使用并发GC设置。

对我来说是关键。我的所有项目都被设置为任何CPU除了一个(巧合地是作为控制台应用程序项目的应用程序的入口点)。该项目已设置为x86。一旦我将其更改为任何CPU应用程序都正确运行。

0

我们在我们的.NET 4.5桌面应用程序 - 网页刮板中遇到了同样的问题。它在重负荷下随机坠毁。所以我们一直在寻找方法来找出几个月的原因:我们已经尝试了一切!禁用并发GC,将其设置为服务器模式以及许多其他解决方法,直到我们意识到因模块发生崩溃而发生崩溃。它使用了一些非托管资源,并且之后没有清除它们:(所以我们为PhantomJS集成创建了一个独立的控制台应用程序,现在我们从网络刮板执行这个控制台应用程序,然后杀死它,这需要更多时间但不会再发生崩溃!

相关问题