次の方法で共有


invalidOverlappedToPinvoke MDA

Note

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

invalidOverlappedToPinvoke マネージド デバッグ アシスタント (MDA: Managed Debugging Assistant) は、ガベージ コレクション ヒープで作成されていないオーバーラップ ポインターが特定の Win32 関数に渡されるとアクティブになります。

Note

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

現象

クラッシュまたは説明のつかないヒープ破損。

原因

ガベージ コレクション ヒープで作成されていないオーバーラップ ポインターが特定のオペレーティング システム関数に渡されています。

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

Module 機能
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 がアンロードされると、アプリケーション コードがオーバーラップ ポインター用メモリを解放するため、操作終了時に破損が発生します。または、コードによってメモリ リークが発生し、後で問題となります。

解決方法

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>

関連項目