releaseHandleFailed MDA
The releaseHandleFailed depuração de assistente (MDA) é ativado é notificar os desenvolvedores gerenciado quando o ReleaseHandle método de uma classe derivada de SafeHandle ou CriticalHandle Retorna false.
Sintomas
recurso ou vazamentos de memória.Se o ReleaseHandle método da classe que deriva de SafeHandle ou CriticalHandle Falha, e em seguida, o recurso encapsulado pela classe talvez não tenham sido liberado ou limpo.
Causa
Os usuários devem fornecer a implementação do ReleaseHandle Se eles criarem classes que derivam de método SafeHandle ou CriticalHandle; Assim, as circunstâncias são específicas para recursos individuais. No entanto, sistema autônomo requisitos são:
SafeHandle e CriticalHandle tipos de representam invólucros em torno de recursos vitais do processo. Um perda de memória poderia tornar o processo inutilizável ao longo do time.
The ReleaseHandle método não deve falhar executar sua função. Depois que o processo adquire como um recurso, ReleaseHandle é a única maneira versão-lo. Portanto, falha significa vazamentos de recurso.
Qualquer falha que ocorre durante a execução de ReleaseHandle, impedir o versão do recurso, é um bug na implementação das ReleaseHandle método propriamente dito. É responsabilidade do programador para garantir que o contrato seja cumprido, mesmo que o código chama o código criado por alguém para executar sua função.
Resolução
O código que usa o específicoSafeHandle (ou CriticalHandle) tipo notificação MDA gerado deve ser revisado, procurando por locais onde o valor do identificador bruto é extraído das SafeHandle e copiadas em outro lugar. Essa é a causa comum de falhas em SafeHandle ou CriticalHandle implementações, como o uso do valor bruto alça em seguida, é não rastreado pelo tempo de execução. Se a cópia de alça brutos subseqüentemente estiver fechada, ele pode fazer com que um posterior ReleaseHandle telefonar para falha porque o fechar é tentado no mesmo identificador, que agora é inválido.
Há várias maneiras em que a duplicação de identificador incorreto pode ocorrer:
Procure chamadas para o DangerousGetHandle método. Chamadas para este método devem ser excessivamente raras e qualquer um que você encontrar devem ficar entre chamadas para o DangerousAddRef e DangerousRelease métodos. Esses métodos último especifique a região de código em que o valor do identificador bruto pode ser usado com segurança.Fora dessa região, ou se a contagem de referência nunca é incrementada em primeiro lugar, o valor do identificador pode ser invalidado a qualquer momento por uma telefonar para Dispose ou Close em outro thread. Uma vez, todos os usos de DangerousGetHandle foram controladas para baixo, você deve seguir o caminho que leva o identificador não processado para garantir que não é entregue a alguns componente eventualmente chamará CloseHandle ou outro método nativo baixo nível que lançara o identificador.
Certifique-se de que o código é usado para inicializar o SafeHandle com um identificador válido bruto valor possui o identificador. Se formar um SafeHandle ao redor de uma alça de seu código não é proprietário sem configuração o ownsHandle parâmetro para false no construtor base, ambos os SafeHandle e o proprietário do controle realmente pode tentar fechar o identificador, entrelinhamento a um erro em ReleaseHandle Se a SafeHandle perde a corrida.
Quando um SafeHandle é empacotado entre domínios de aplicativo, confirme o SafeHandle derivação que está sendo usada foi marcada sistema autônomo serializável. Raramente onde uma classe derivada de SafeHandle foi feita serializável, deve implementar o ISerializable interface ou usar uma das outras técnicas para controlar manualmente o processo de serialização e desserialização. Isso é necessário porque a ação de serialização padrão é criar um clone bit a bit do valor incluso alça brutos, resultando em dois SafeHandle pensando que eles próprios o mesmo identificador de instâncias. Ambos tentará telefonar ReleaseHandle no mesmo identificador em algum momento. O segundo SafeHandle Para fazer isso irá falhar. O curso correto de ação ao serializar um SafeHandle é chamar o DuplicateHandle função ou uma função semelhante para o seu tipo de identificador nativo fazer uma cópia do identificador legal distintas. Se o tipo de identificador não oferece suporte a isso e o SafeHandle Digite a disposição do texto que não puderem ser tornado serializável.
É possível controlar onde um identificador está sendo fechado no início, entrelinhamento a uma falha quando o ReleaseHandle método é chamado por fim, colocando um ponto de interrupção do depurador na rotina nativa usada para versão a alça, por exemplo o CloseHandle função. Isso pode não ser possível para cenários de carga ou mesmo médias testes funcionais devido ao tráfego intenso com que essas rotinas freqüentemente lidam.Pode ser útil para instrumentar o código que chama o método versão nativa, para capturar a identidade do chamador, ou, possivelmente, um rastreamento de pilha completa e o valor do identificador sendo lançado.O valor do identificador pode ser comparado com o valor informado por este MDA.
Observe que alguns tipos de identificador nativo, sistema autônomo todos sistema autônomo Win32 manipula que pode ser liberado via o CloseHandle eles funcionarão, compartilham o mesmo espaço para nome do identificador. Uma versão incorreta do tipo de um identificador pode causar problemas com o outro.Por exemplo, fechar acidentalmente um identificador de eventos do Win32 duas vezes pode levar a um identificador de arquivo aparentemente não relacionados que está sendo fechado prematuramente.Isso acontece quando o identificador é liberado e o valor do identificador se torna disponível para ser usado controlar outro recurso, possivelmente de outro tipo.Se isso acontece e é seguido por uma segunda versão errada, a alça de um segmento não relacionado pode ser invalidada.
Efeito sobre o tempo de execução
Este MDA não tem efeito sobre o CLR.
Saída
Uma mensagem indicando que um SafeHandle ou um CriticalHandle Falha ao liberar o identificador corretamente. Por exemplo:
"A SafeHandle or CriticalHandle of type 'MyBrokenSafeHandle'
failed to properly release the handle with value 0x0000BEEF. This
usually indicates that the handle was released incorrectly via
another means (such as extracting the handle using DangerousGetHandle
and closing it directly or building another SafeHandle around it."
Configuração
<mdaConfig>
<assistants>
<releaseHandleFailed/>
</assistants>
</mdaConfig>
Exemplo
A seguir é um exemplo de código que pode ativar o releaseHandleFailed MDA.
bool ReleaseHandle()
{
// Calling the Win32 CloseHandle function to release the
// native handle wrapped by this SafeHandle. This method returns
// false on failure, but should only fail if the input is invalid
// (which should not happen here). The method specifically must not
// fail simply because of lack of resources or other transient
// failures beyond the user’s control. That would make it unacceptable
// to call CloseHandle as part of the implementation of this method.
return CloseHandle(handle);
}
Consulte também
Conceitos
Diagnosticar erros com assistentes de depuração gerenciadas
Visão geral do empacotamento interop