vícenásobný přístup MDA
Poznámka:
Tento článek je specifický pro rozhraní .NET Framework. Nevztahuje se na novější implementace .NET, včetně .NET 6 a novějších verzí.
Pomocník reentrancy
spravovaného ladění (MDA) se aktivuje při pokusu o přechod z nativního na spravovaný kód v případech, kdy se předchozí přechod ze spravovaného na nativní kód neprováděl prostřednictvím seřazeného přechodu.
Příznaky
Halda objektu je poškozena nebo dochází k jiným vážným chybám při přechodu z nativního na spravovaný kód.
Vlákna, která přepínají mezi nativním a spravovaným kódem v obou směrech, musí provést pořádekový přechod. Některé body rozšiřitelnosti nízké úrovně v operačním systému, jako je například vektorová obslužná rutina výjimek, však umožňují přepínače ze spravovaného do nativního kódu bez provedení řaděného přechodu. Tyto přepínače jsou pod kontrolou operačního systému, nikoli pod kontrolou CLR (Common Language Runtime). Jakýkoli nativní kód, který se spouští uvnitř těchto bodů rozšiřitelnosti, se musí vyhnout volání zpět do spravovaného kódu.
Příčina
Bod rozšiřitelnosti operačního systému nízké úrovně, například obslužná rutina vektorové výjimky, se aktivoval při spouštění spravovaného kódu. Kód aplikace, který je vyvolán prostřednictvím tohoto bodu rozšiřitelnosti, se pokouší volat zpět do spravovaného kódu.
Tento problém je vždy způsoben kódem aplikace.
Rozlišení
Zkontrolujte trasování zásobníku pro vlákno, které aktivovalo toto MDA. Vlákno se pokouší neoprávněně volat do spravovaného kódu. Trasování zásobníku by mělo odhalit kód aplikace pomocí tohoto bodu rozšiřitelnosti, kód operačního systému, který poskytuje tento bod rozšiřitelnosti, a spravovaný kód, který byl přerušen bodem rozšiřitelnosti.
Zobrazí se například mda aktivovaná při pokusu o volání spravovaného kódu z obslužné rutiny vektorové výjimky. V zásobníku uvidíte kód zpracování výjimek operačního systému a nějaký spravovaný kód, který aktivuje výjimku, jako DivideByZeroException je například nebo AccessViolationException.
V tomto příkladu je správné rozlišení implementovat vektorovanou obslužnou rutinu výjimky zcela v nespravovaném kódu.
Vliv na modul runtime
Tento mdA nemá žádný vliv na CLR.
Výstup
MdA hlásí, že došlo k pokusu o nelegální opětovné zadání. Prozkoumejte zásobník vlákna a zjistěte, proč k tomu dochází a jak problém opravit. Následuje ukázkový výstup.
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'.
Konfigurace
<mdaConfig>
<assistants>
<reentrancy />
</assistants>
</mdaConfig>
Příklad
Následující příklad kódu způsobí AccessViolationException vyvolání. Ve verzích Windows, které podporují zpracování vektorových výjimek, to způsobí volání obslužné rutiny spravované vektorové výjimky. reentrancy
Pokud je mdA povolená, MDA se aktivuje během pokusu o MyHandler
volání z vektorového kódu zpracování výjimek operačního systému.
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 { }
}
}