Bagikan melalui


MDA masuk kembali

Catatan

Artikel ini khusus untuk .NET Framework. Ini tidak berlaku untuk implementasi .NET yang lebih baru, termasuk .NET 6 dan versi yang lebih baru.

reentrancy asisten penelusuran kesalahan terkelola (MDA) diaktifkan saat upaya dilakukan untuk transisi dari kode asli ke kode terkelola dalam kasus ketika peralihan sebelumnya dari kode terkelola ke kode asli tidak dilakukan melalui transisi yang teratur.

Gejala

Tumpukan objek rusak atau kesalahan serius lainnya terjadi saat transisi dari kode asli ke kode terkelola.

Utas yang beralih antara kode asli dan terkelola di kedua arah harus melakukan transisi yang teratur. Namun, titik ekstensibilitas tingkat rendah tertentu dalam sistem operasi, seperti pengendali pengecualian ber-vektor, memungkinkan peralihan dari kode terkelola ke kode asli tanpa melakukan transisi yang teratur. Sakelar ini berada di bawah kendali sistem operasi, bukan di bawah kendali runtime bahasa umum (CLR). Setiap kode asli yang dijalankan di dalam titik ekstensibilitas ini harus menghindari pemanggilan kembali ke kode terkelola.

Penyebab

Titik ekstensibilitas sistem operasi tingkat rendah, seperti pengendali pengecualian ber-vektor, telah diaktifkan saat mengeksekusi kode yang dikelola. Kode aplikasi yang dipanggil melalui titik ekstensibilitas tersebut mencoba memanggil kembali ke kode yang dikelola.

Masalah ini selalu disebabkan oleh kode aplikasi.

Resolusi

Periksa jejak tumpukan untuk utas yang telah mengaktifkan MDA ini. Utas mencoba memanggil secara ilegal ke kode terkelola. Jejak tumpukan harus mengungkapkan kode aplikasi menggunakan titik ekstensibilitas ini, kode sistem operasi yang menyediakan titik ekstensibilitas ini, dan kode terkelola yang diinterupsi oleh titik ekstensibilitas.

Misalnya, Anda akan melihat MDA diaktifkan dalam upaya memanggil kode terkelola dari dalam pengendali pengecualian ber-vektor. Pada tumpukan, Anda akan melihat kode penanganan pengecualian sistem operasi dan beberapa kode terkelola memicu pengecualian seperti DivideByZeroException atau AccessViolationException.

Dalam contoh ini, resolusi yang benar adalah mengimplementasikan pengendali pengecualian ber-vektor sepenuhnya dalam kode yang tidak dikelola.

Efek pada Runtime

MDA ini tidak berpengaruh pada runtime bahasa umum.

Output

MDA melaporkan bahwa masuk kembali secara ilegal sedang dicoba. Periksa tumpukan utas untuk menentukan alasan ini terjadi dan cara memperbaiki masalah. Berikut ini adalah contoh output.

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

Konfigurasi

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

Contoh

Contoh kode berikut menyebabkan AccessViolationException ditampilkan. Pada versi Windows yang mendukung penanganan pengecualian ber-vektor, versi ini akan menyebabkan pengendali pengecualian ber-vektor terkelola dipanggil. Jika MDA reentrancy diaktifkan, MDA akan aktif selama upaya panggilan ke MyHandler dari kode dukungan penanganan pengecualian ber-vektor sistem operasi.

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

Lihat juga