【问题标题】:Crash in GC finalizer thread, what's the problem with "DestroyScout"?GC 终结器线程崩溃,“DestroyScout”有什么问题?
【发布时间】:2022-06-15 21:09:28
【问题描述】:

我正面临一个 .Net 服务器应用程序,它几乎每周都会因“GC 终结器线程”中的问题而崩溃,更确切地说是在“mscorlib.dll ...~DestroyScout()”的第 798 行,根据 Visual Studio。
Visual Studio 还尝试打开文件“DynamicILGenerator.gs”。我没有这个文件,但我找到了那个文件的一个版本,其中第 798 行确实在析构函数或 DestroyScout 内(不管这可能意味着什么)。

我的 Visual Studio 环境中有以下信息:

线程:

Not Flagged >   5892    0   Worker Thread   GC Finalizer Thread mscorlib.dll!System.Reflection.Emit.DynamicResolver.DestroyScout.~DestroyScout

调用栈:

    [Managed to Native Transition]  
>   mscorlib.dll!System.Reflection.Emit.DynamicResolver.DestroyScout.~DestroyScout() Line 798   C#
[Native to Managed Transition]  
kernel32.dll!@BaseThreadInitThunk@12()  Unknown
ntdll.dll!__RtlUserThreadStart()    Unknown
ntdll.dll!__RtlUserThreadStart@8()  Unknown

Locals(无法确定 $exception 对象是否正确):

+       $exception  {"Exception of type 'System.ExecutionEngineException' was thrown."} System.ExecutionEngineException
    this    Cannot obtain value of the local variable or argument because it is not available at this instruction pointer,
            possibly because it has been optimized away.    System.Reflection.Emit.DynamicResolver.DestroyScout
    Stack objects   No CLR objects were found in the stack memory range of the current frame.   

“DynamicILGenerator.cs”的源代码,提到DestroyScout类(注释中提到了第798行):

    private class DestroyScout
    {
        internal RuntimeMethodHandleInternal m_methodHandle;

        [System.Security.SecuritySafeCritical]  // auto-generated
        ~DestroyScout()
        {
            if (m_methodHandle.IsNullHandle())
                return;

            // It is not safe to destroy the method if the managed resolver is alive.
            if (RuntimeMethodHandle.GetResolver(m_methodHandle) != null)
            {
                if (!Environment.HasShutdownStarted &&
                    !AppDomain.CurrentDomain.IsFinalizingForUnload())
                {
                    // Somebody might have been holding a reference on us via weak handle.
                    // We will keep trying. It will be hopefully released eventually.
                    GC.ReRegisterForFinalize(this);
                }
                return;
            }

            RuntimeMethodHandle.Destroy(m_methodHandle); // <===== line 798
        }
    }

观察窗口 (m_methodHandle):

m_methodHandle  Cannot obtain value of the local variable or argument because 
                it is not available at this instruction pointer,
                possibly because it has been optimized away.
                System.RuntimeMethodHandleInternal

一般转储模块信息:

Dump Summary
------------
Dump File:  Application_Server2.0.exe.5296.dmp : C:\Temp_Folder\Application_Server2.0.exe.5296.dmp
Last Write Time:    14/06/2022 19:08:30
Process Name:   Application_Server2.0.exe : C:\Runtime\Application_Server2.0.exe
Process Architecture:   x86
Exception Code: 0xC0000005
Exception Information:  The thread tried to read from or write to a virtual address
                        for which it does not have the appropriate access.
Heap Information:   Present

System Information
------------------
OS Version: 10.0.14393
CLR Version(s): 4.7.3920.0

Modules
-------
Module Name                                           Module Path   Module Version
-----------                                           -----------   --------------
...
clr.dll     C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll       4.7.3920.0
...

注意:转储到达 Windows-Server 2016 计算机上,我正在我的 Windows-10 环境中调查转储(不要误会OS Version 在转储摘要中)!

有人有想法吗?

【问题讨论】:

  • 对我来说,这似乎是多线程场景中的竞争条件,其中多个线程处理同一个对象句柄
  • 竞争条件?在我无法访问的某个来源中?有什么方法可以解决这个问题(这是一个已知的错误,是否可以跟踪它的进展,...)?
  • 再看一遍,我认为它与多线程无关,但它显然看起来像一个错误是的。在析构函数中重新注册 this 以完成最终确定可能会导致 GC 再次调用析构函数.. 这是什么?这是在 C# 中销毁对象的奇怪逻辑,等到所有弱引用都放弃了它们的句柄。我不知道,抱歉评论
  • 您是否尝试过使用较新版本的 .NET Framework? ExecutionEngineException 对我来说可能是某种损坏的内存,它恰好只在最终确定时才出现。您使用的是unsafe 还是 PInvoke?

标签: c# dump windows-server-2016


猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多