invalidOverlappedToPinvoke MDA

Note

この記事は .NET Framework に固有のものです。 .NET 6 以降のバージョンを含む、.NET の新しい実装には適用されません。

ガベージ コレクション ヒープで作成されなかった重なり合ったポインターが特定の Win32 関数に渡されると、 invalidOverlappedToPinvoke マネージド デバッグ アシスタント (MDA) がアクティブになります。

Note

既定では、この MDA は、プラットフォーム呼び出し呼び出しがコードで定義され、デバッガーが各メソッドの JustMyCode 状態を報告する場合にのみアクティブ化されます。 JustMyCode を理解していないデバッガー (拡張機能のない MDbg.exe など) では、この MDA はアクティブになりません。 構成ファイルを使用し、.mda.config ファイル (<invalidOverlappedToPinvoke enable="true" justMyCode="false"/>) にjustMyCode="false"を明示的に設定することで、これらのデバッガーに対してこの MDA を有効にすることができます。

Symptoms

クラッシュまたは原因不明のヒープの破損。

原因

ガベージ コレクション ヒープで作成されなかった重なり合ったポインターは、特定のオペレーティング システム関数に渡されます。

次の表に、この MDA が追跡する関数を示します。

モジュール Function
HttpApi.dll HttpReceiveHttpRequest
IpHlpApi.dll NotifyAddrChange
kernel32.dll ReadFile
kernel32.dll ReadFileEx
kernel32.dll WriteFile
kernel32.dll WriteFileEx
kernel32.dll ReadDirectoryChangesW
kernel32.dll PostQueuedCompletionStatus
MSWSock.dll ConnectEx
WS2_32.dll WSASend
WS2_32.dll WSASendTo
WS2_32.dll WSARecv
WS2_32.dll WSARecvFrom
MQRT.dll MQReceiveMessage

呼び出しを行う AppDomain がアンロードされる可能性があるため、この状態ではヒープ破損の可能性が高くなります。 AppDomainがアンロードされると、アプリケーション コードは重なっているポインターのメモリを解放し、操作の終了時に破損を引き起こすか、コードによってメモリがリークされ、後で問題が発生します。

Resolution

Overlapped オブジェクトを使用し、Pack メソッドを呼び出して、関数に渡すことができるNativeOverlapped構造体を取得します。 AppDomainがアンロードされた場合、CLR は非同期操作が完了するまで待機してからポインターを解放します。

ランタイムへの影響

この MDA は CLR に影響を与えなくなりました。

アウトプット

この MDA からの出力の例を次に示します。

An overlapped pointer (0x00ea3430) that was not allocated on the GC heap was passed via Pinvoke to the Win32 function 'WriteFile' in module 'KERNEL32.DLL'. If the AppDomain is shut down, this can cause heap corruption when the async I/O completes. The best solution is to pass a NativeOverlapped structure retrieved from a call to System.Threading.Overlapped.Pack(). If the AppDomain exits, the CLR will keep this structure alive and pinned until the I/O completes.

コンフィギュレーション

<mdaConfig>
  <assistants>
    <invalidOverlappedToPinvoke/>
  </assistants>
</mdaConfig>

こちらも参照ください