다음을 통해 공유


invalidOverlappedToPinvoke MDA

invalidOverlappedToPinvoke MDA(관리 디버깅 도우미)는 가비지 수집 힙에서 만들어지지 않은 중첩 포인터가 특정 Win32 함수에 전달될 때 활성화됩니다.

참고참고

기본적으로 P/Invoke 호출이 코드에 정의되어 있고 디버거가 각 메서드의 JustMyCode 상태를 보고하는 경우에만 이 MDA가 활성화됩니다(방법: 내 코드만 한 단계씩 실행 참조).확장자가 없는 MDbg.exe와 같은 JustMyCode를 이해하지 못하는 디버거는 이 MDA를 활성화하지 못합니다.구성 파일을 사용하고 .mda.config 파일에서 명시적으로 justMyCode="false"를 설정하여(<invalidOverlappedToPinvoke enable="true" justMyCode="false"/>) 이 MDA를 이러한 디버거에 대해 활성화할 수 있습니다.

증상

충돌 또는 설명할 수 없는 힙 손상이 발생합니다.

원인

가비지 수집 힙에서 만들어지지 않은 중첩 포인터는 특정 운영 체제 함수에 전달됩니다.

다음 표에서는 이 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이 언로드되면 응용 프로그램 코드에서 중첩 포인터에 대한 메모리를 해제하여 작업이 완료될 때 손상을 발생시키거나 해당 코드에서 메모리를 누수하여 나중에 장애가 발생합니다.

해결 방법

함수에 전달할 수 있는 NativeOverlapped 구조를 가져오려면 Pack 메서드를 호출하는 Overlapped 개체를 사용합니다. AppDomain이 언로드되면 CLR은 포인터를 해제하기 전에 비동기 작업이 완료될 때까지 기다립니다.

런타임 효과

이 MDA는 CLR에 아무런 영향을 주지 않습니다.

Output

다음은 이 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>

참고 항목

참조

MarshalAsAttribute

개념

관리 디버깅 도우미를 사용하여 오류 진단

Interop 마샬링