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"

配置

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

Example

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();
    }
}

另请参阅