Megosztás a következőn keresztül:


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

Lásd még