Compartilhar via


MDA virtualCERCall

Observação

Este artigo é específico para aplicativos .NET Framework. Ele não se aplica a implementações mais recentes do .NET, incluindo o .NET 6 e versões posteriores.

O MDA (assistente para depuração gerenciada) virtualCERCall é ativado como um aviso, indicando que um site de chamada em um gráfico de chamadas da CER (região de execução restrita) se refere a um destino virtual, ou seja, uma chamada virtual a um método virtual não final ou uma chamada usando uma interface. O CLR (Common Language Runtime) não pode prever o método de destino dessas chamadas pela análise de metadados e de linguagem intermediária apenas. Como resultado, a árvore de chamadas não pode ser preparada como parte do gráfico da CER e as anulações de thread nessa subárvore não podem ser bloqueadas automaticamente. Esse MDA avisa sobre casos em que uma CER talvez precise ser estendida usando chamadas explícitas ao método PrepareMethod depois que as informações adicionais necessárias para calcular o destino de chamada são conhecidas em tempo de execução.

Sintomas

As CERs não são executadas quando um thread é anulado ou um domínio do aplicativo é descarregado.

Causa

Uma CER contém uma chamada a um método virtual que não pode ser preparado automaticamente.

Resolução

Chame PrepareMethod para o método virtual.

Efeito sobre o runtime

Esse MDA não tem efeito sobre o CLR.

Saída

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"

Configuração

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

Exemplo

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

Confira também