Compartilhar via


reentrância MDA

O reentrancy Assistente de depuração gerenciada (MDA) é ativado quando é feita uma tentativa de fazer a transição de código nativo para gerenciado em casos onde um switch antes do código gerenciado para nativo não foi executado por meio de uma transição ordenada.

Sintomas

O objeto está corrompida ou outros erros graves que ocorrem durante a transição de código nativo para gerenciado.

Segmentos que alternar entre códigos nativos e gerenciados em qualquer direção devem realizar uma transição ordenada. Entretanto, certos pontos de extensibilidade de baixo nível do sistema operacional, como, por exemplo, o manipulador de exceção em vetor, permitem switches de gerenciado para código nativo, sem executar uma transição ordenada. Essas opções estão sob controle do sistema operacional, em vez de sob o controle de tempo de execução (CLR) de idioma comum. Qualquer código nativo que é executado dentro desses pontos de extensibilidade deve evitar retornar a chamada para código gerenciado.

Causa

Um ponto de extensibilidade do sistema operacional de nível inferior, como, por exemplo, o manipulador de exceção em vetor, tenha ativado durante a execução de código gerenciado. O código do aplicativo é invocado por esse ponto de extensibilidade é a tentativa de chamada de retorno no código gerenciado.

Sempre, esse problema é causado pelo código do aplicativo.

Resolução

Examine o rastreamento de pilha para o segmento que ativou este MDA. O thread está tentando chamar código gerenciado ilegalmente. O rastreamento de pilha deve revelar o código do aplicativo usando o ponto de extensibilidade, o código do sistema operacional que fornece o ponto de extensibilidade e o código gerenciado que foi interrompido pelo ponto de extensibilidade.

Por exemplo, você verá o MDA ativado na tentativa de chamar código gerenciado a partir de dentro de um manipulador de exceção em vetor. Na pilha, você verá a código e algum código gerenciado, acionando uma exceção, como de manipulação de exceção do sistema operacional um DivideByZeroException ou um AccessViolationException.

Neste exemplo, a resolução correta é implementar o manipulador de exceção em vetor completamente em código não gerenciado.

Efeito sobre o tempo de execução.

Este MDA não tem efeito sobre o CLR.

Saída

O MDA relata que reentrância ilegal está sendo tentada. Examine a pilha do thread para determinar por que isso está acontecendo e como corrigir o problema. A seguir é exemplo de saída.

Additional Information: Attempting to call into managed code without 
transitioning out first.  Do not attempt to run managed code inside 
low-level native extensibility points. Managed Debugging Assistant 
'Reentrancy' has detected a problem in 'D:\ConsoleApplication1\
ConsoleApplication1\bin\Debug\ConsoleApplication1.vshost.exe'.

Configuração

<mdaConfig>
  <assistants>
    <reentrancy />
  </assistants>
</mdaConfig>

Exemplo

O código a seguir faz com que o exemplo um AccessViolationException ser acionada. Em versões do Windows que oferecem suporte a manipulação de exceção em vetor, isso fará com que o manipulador de exceção em vetor gerenciada a ser chamado. Se o reentrancy MDA estiver ativado, o MDA será ativado durante a tentativa chamada para MyHandler partir do sistema operacional de exceção em vetor lidando com código de suporte.

using System;
public delegate int ExceptionHandler(IntPtr ptrExceptionInfo);

public class Reenter 
{
    public static ExceptionHandler keepAlive;

    [System.Runtime.InteropServices.DllImport("kernel32", ExactSpelling=true, 
        CharSet=System.Runtime.InteropServices.CharSet.Auto)]
    public static extern IntPtr AddVectoredExceptionHandler(int bFirst, 
        ExceptionHandler handler);

    static int MyHandler(IntPtr ptrExceptionInfo) 
    {
        // EXCEPTION_CONTINUE_SEARCH
        return 0;
    }
    void Run() {}

    static void Main() 
    {
        keepAlive = new ExceptionHandler(Reenter.MyHandler);
        IntPtr ret = AddVectoredExceptionHandler(1, keepAlive);
        try 
        {
            // Dispatch on null should AV.
            Reenter r = null; 
            r.Run();
        } 
        catch { }
    }
}

Consulte também

Conceitos

Diagnosticar erros com assistentes de depuração gerenciada