wielobieżność MDA

reentrancy Asystent zarządzanego debugowania (MDA) jest aktywowany, gdy zostanie podjęta próba przejścia z natywnego do kodu zarządzanego w przypadkach, gdy wcześniejsze przełączenie z zarządzanego do kodu natywnego nie zostało wykonane za pomocą uporządkowanego przejścia.

Objawy

Sterty obiektu są uszkodzone lub występują inne poważne błędy podczas przechodzenia z natywnego do zarządzanego kodu.

Wątki, które przełączają się między kodem natywnym i zarządzanym w obu kierunkach, muszą wykonać uporządkowane przejście. Jednak niektóre punkty rozszerzalności niskiego poziomu w systemie operacyjnym, takie jak wektorowana procedura obsługi wyjątków, umożliwiają przełączanie z zarządzanego na natywny kod bez przeprowadzania uporządkowanego przejścia. Te przełączniki są pod kontrolą systemu operacyjnego, a nie pod kontrolą środowiska uruchomieniowego języka wspólnego (CLR). Każdy kod natywny wykonywany wewnątrz tych punktów rozszerzalności musi unikać wywoływania z powrotem do kodu zarządzanego.

Przyczyna

Punkt rozszerzalności systemu operacyjnego niskiego poziomu, taki jak wektorowa procedura obsługi wyjątków, został aktywowany podczas wykonywania kodu zarządzanego. Kod aplikacji wywoływany za pośrednictwem tego punktu rozszerzalności próbuje wywołać z powrotem do kodu zarządzanego.

Ten problem jest zawsze spowodowany przez kod aplikacji.

Rozwiązanie

Sprawdź ślad stosu dla wątku, który aktywował tę usługę MDA. Wątek próbuje nielegalnie wywołać kod zarządzany. Ślad stosu powinien ujawnić kod aplikacji przy użyciu tego punktu rozszerzalności, kodu systemu operacyjnego, który zapewnia ten punkt rozszerzalności, oraz kodu zarządzanego, który został przerwany przez punkt rozszerzalności.

Na przykład usługa MDA zostanie aktywowana podczas próby wywołania kodu zarządzanego z wewnątrz wektorowanej procedury obsługi wyjątków. Na stosie zobaczysz kod obsługi wyjątków systemu operacyjnego i kod zarządzany wyzwalający wyjątek, taki jak lub DivideByZeroExceptionAccessViolationException.

W tym przykładzie prawidłową rozdzielczością jest zaimplementowanie wektorowej procedury obsługi wyjątków całkowicie w kodzie niezarządzanym.

Wpływ na środowisko uruchomieniowe

To MDA nie ma wpływu na CLR.

Dane wyjściowe

MDA zgłasza, że podjęto próbę nielegalnej ponownej próby. Sprawdź stos wątku, aby ustalić, dlaczego tak się dzieje i jak rozwiązać problem. Poniżej przedstawiono przykładowe dane wyjściowe.

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'.  

Konfiguracja

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

Przykład

Poniższy przykład kodu powoduje zgłoszenie elementu AccessViolationException . W wersjach systemu Windows, które obsługują obsługę wektorów wyjątków, spowoduje to wywołanie zarządzanego programu obsługi wyjątków wektorowych. reentrancy Jeśli mdA jest włączona, mdA aktywuje się podczas próby wywołania z MyHandler wektorowego kodu obsługi wyjątków systemu operacyjnego.

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 { }  
    }  
}  

Zobacz też