wielobieżność MDA
Uwaga
Ten artykuł jest specyficzny dla programu .NET Framework. Nie ma zastosowania do nowszych implementacji platformy .NET, w tym .NET 6 i nowszych wersji.
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 przejście z zarządzanego do kodu natywnego nie zostało wykonane za pomocą uporządkowanego przejścia.
Objawy
Sterta obiektu jest uszkodzona 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 kodu zarządzanego na natywny 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 macierzysty 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 wektorowana 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ć kod zarządzany.
Ten problem jest zawsze spowodowany kodem 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 zapewniającego 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 poziomu programu obsługi wyjątków wektorowych. 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
Ta usługa MDA nie ma wpływu na CLR.
Wyjście
MdA zgłasza, że podejmowana jest próba nielegalnej ponownej reentrancy. 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'.
Konfigurowanie
<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ądzanej procedury obsługi wyjątków wektorowych. reentrancy
Jeśli mdA jest włączona, mdA aktywuje się podczas próby wywołania z MyHandler
wektorowanego 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 { }
}
}