共用方式為


invalidOverlappedToPinvoke MDA

注意

本文專屬於 .NET Framework。 它不適用於較新的 .NET 實作,包括 .NET 6 和更新版本。

當不是在記憶體回收堆積上建立的重疊指標傳遞至特定的 Win32 函式時,就會啟動 invalidOverlappedToPinvoke Managed 偵錯助理 (MDA)。

注意

根據預設,只有在程式碼中定義了平台叫用呼叫,而且偵錯工具報告每一個方法的 JustMyCode 狀態時,才會啟用這個 MDA。 不了解 JustMyCode (例如 MDbg.exe 沒有副檔名) 的偵錯工具,不會啟動此 MDA。 使用組態檔和在 .mda.config 檔案 (<invalidOverlappedToPinvoke enable="true" justMyCode="false"/>) 中明確設定 justMyCode="false",可針對這些偵錯工具啟用此 MDA。

徵兆

當機或無法解釋的堆積損毀。

原因

不是在記憶體回收堆積建立的重疊指標,會傳遞給特定的作業系統函式。

下表會顯示這個 MDA 追蹤的函式。

模組 函式
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>

另請參閱