MDA újraküldése
Feljegyzés
Ez a cikk a .NET-keretrendszer vonatkozik. Ez nem vonatkozik a .NET újabb implementációira, beleértve a .NET 6-os és újabb verzióit.
A reentrancy
felügyelt hibakeresési segéd (MDA) akkor aktiválódik, amikor kísérletet tesznek a natív kódról a felügyelt kódra való áttérésre olyan esetekben, amikor a felügyelt kódról a natív kódra való korábbi váltás nem történt meg rendezett áttűnéssel.
Hibajelenségek
Az objektum halom sérült, vagy más súlyos hibák történnek, amikor natív kódról felügyelt kódra vált.
A natív és a felügyelt kód között mindkét irányban kapcsoló szálaknak rendezett átmenetet kell végrehajtaniuk. Az operációs rendszer bizonyos alacsony szintű bővíthetőségi pontjai, például a vektoros kivételkezelő azonban lehetővé teszik a felügyelt kódról a natív kódra való váltást rendezett átmenet nélkül. Ezek a kapcsolók az operációs rendszer felügyelete alatt állnak, nem pedig a közös nyelvi futtatókörnyezet (CLR) vezérlése alatt. A bővíthetőségi pontokon belül végrehajtott natív kódoknak kerülniük kell a felügyelt kódba való visszahívást.
Ok
Egy alacsony szintű operációsrendszer-bővíthetőségi pont, például a vektoros kivételkezelő aktiválva lett a felügyelt kód végrehajtása során. A bővíthetőségi ponton keresztül meghívott alkalmazáskód visszahívást kísérel meg felügyelt kódba.
Ezt a problémát mindig az alkalmazáskód okozza.
Resolution (Osztás)
Vizsgálja meg az MDA-t aktiváló szál veremkövetését. A szál illegálisan próbál betárcsázást kezdeményezni a felügyelt kódba. A verem nyomkövetésének meg kell jelennie az alkalmazás kódjának ezzel a bővíthetőségi ponttal, a bővíthetőségi pontot biztosító operációs rendszer kódjának és a bővíthetőségi pont által megszakított felügyelt kódnak.
Az MDA például aktiválva lesz, amikor megkísérel meghívni egy felügyelt kódot egy vektoros kivételkezelőből. A veremen megjelenik az operációs rendszer kivételkezelő kódja és néhány felügyelt kód, amely kivételt vált ki, például egy DivideByZeroException vagy egy AccessViolationException.
Ebben a példában a helyes megoldás a vektoros kivételkezelő teljes implementálása nem felügyelt kódban.
Effektus a futtatókörnyezetre
Ez az MDA nincs hatással a CLR-re.
Hozam
Az MDA jelentése szerint illegális újrapróbálkozott. Vizsgálja meg a szál veremét, és állapítsa meg, hogy ez miért történik, és hogyan háríthatja el a problémát. A következő mintakimenet.
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'.
Konfiguráció
<mdaConfig>
<assistants>
<reentrancy />
</assistants>
</mdaConfig>
Példa
Az alábbi példakód egy AccessViolationException dobást okoz. A windowsos verziókban, amelyek támogatják a vektoros kivételkezelést, ez a felügyelt vektoros kivételkezelő meghívását eredményezi. Ha az reentrancy
MDA engedélyezve van, az MDA aktiválódik az operációs rendszer vektoros kivételkezelési támogatási kódjából kezdeményezett hívás MyHandler
során.
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 { }
}
}