virtualCERCall MDA

注意

本文特定于 .NET Framework。 它不适用于 .NET 的较新版本实现,包括 .NET 6 及更高版本。

virtualCERCall 托管调试助手 (MDA) 作为警告被激活,指示某个受约束的执行区域 (CER) 调用关系图中的调用站点引用了虚拟目标,即对非最终虚拟方法的虚拟调用或使用接口的调用。 公共语言运行时 (CLR) 无法只凭中间语言和元数据分析预测这些调用的目标方法。 因此无法将调用树准备为 CER 关系图的一部分,且无法阻止该子树中的线程中止。 此 MDA 警告以下情况:一旦计算调用目标所需的附加信息在运行时已知,则可能需要使用对 PrepareMethod 方法的显式调用来扩展 CER。

症状

线程中止或应用程序域卸载时 CER 不运行。

原因

CER 包含对无法自动准备的虚拟方法的调用。

解决方法

为该虚拟方法调用 PrepareMethod

对运行时的影响

此 MDA 对 CLR 无任何影响。

输出

Method 'MethodWithCer', while executing within a constrained execution region, makes a call
at IL offset 0x0024 to 'VirtualMethod', which is virtual and cannot be prepared automatically
at compile time. The caller must ensure this method is prepared explicitly at
runtime before entering the constrained execution region.
method name="VirtualMethod"
declaringType name="VirtualCERCall+MyClass"
  declaringModule name="mda"
    callsite name="MethodWithCer" offset="0x0024"

Configuration

<mdaConfig>
  <assistants>
    <VirtualCERCall />
  </assistants>
</mdaConfig>

示例

class MyClass
{
    [ReliabilityContract(Consistency.MayCorruptProcess, CER.None)]
    virtual void VirtualMethod()
    {
        ...
    }
}

class MyDerivedClass : MyClass
{
    [ReliabilityContract(Consistency.MayCorruptProcess, CER.None)]
    override void VirtualMethod()
    {
        ...
    }
}

void MethodWithCer(MyClass object)
{
    RuntimeHelpers.PrepareConstrainedRegions();
    try
    {
        ...
    }
    finally
    {
        // Start of the CER.

        // Cannot tell at analysis time whether object is a MyClass
        // or a MyDerivedClass, so we do not know which version of
        // VirtualMethod we are going to call.
        object.VirtualMethod();
    }
}

请参阅