Compartilhar via


MDA invalidOverlappedToPinvoke

Observação

Este artigo é específico para aplicativos .NET Framework. Ele não se aplica a implementações mais recentes do .NET, incluindo o .NET 6 e versões posteriores.

O MDA (Assistente de Depuração Gerenciado) de invalidOverlappedToPinvoke é ativado quando um ponteiro sobreposto que não foi criado no heap de coleta de lixo é passado para funções específicas do Win32.

Observação

Por padrão, esse MDA é ativado somente se a chamada de invocação de plataforma é definida no seu código e o depurador relata o status de JustMyCode de cada método. Um depurador que não entende JustMyCode (tal como MDbg.exe sem nenhuma extensão) não ativará esse MDA. Esse MDA pode ser habilitado para esses depuradores usando um arquivo de configuração e configurando justMyCode="false" explicitamente no (<invalidOverlappedToPinvoke enable="true" justMyCode="false"/> do arquivo .mda.config).

Sintomas

Falhas ou corrupção de heap inexplicáveis.

Causa

Um ponteiro sobreposto que não foi criado no heap de coleta de lixo é passado para as funções de sistema operacional específicas.

A tabela a seguir mostra as funções que esse MDA acompanha.

Módulo Função
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

O potencial de corrupção de heap é alto para essa condição porque o AppDomain fazendo a chamada pode ser descarregado. Se o AppDomain for descarregado, o código do aplicativo liberará a memória para o ponteiro sobreposto causando corrupção quando a operação for concluída ou então o código causará perda de memória, resultando em problemas mais tarde.

Resolução

Use um objeto Overlapped, chamando o método Pack para obter uma estrutura NativeOverlapped que pode ser passada para a função. Se o AppDomain for descarregado, o CLR aguardará até que a operação assíncrona seja concluída antes de liberar o ponteiro.

Efeito sobre o runtime

Esse MDA não teve efeito sobre o CLR.

Saída

A seguir temos um exemplo de saída desse 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.

Configuração

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

Confira também