Pergunta

Eu tenho um aplicativo que parece lançar exceções apenas após o programa ter sido fechado. E é muito inconsistente. (Todos nós sabemos como erros divertido inconsistentes são ...)

Meu palpite é que há um erro durante o processo de limpeza. Mas estes memória de leitura / gravação erros parecem indicar algo de errado no meu uso de código "inseguro" (ponteiros?).

O que eu estou em interessado é o que é o melhor método para depurar estas situações?
Como você depurar um programa que já fechou
Estou à procura de um ponto de partida para quebrar um problema maior.

Esses erros parecem apresentar-se de diversas formas (algumas tempo de execução, alguns depuração):

1: .NET-BroadcastEventWindow.2.0.0.0.378734a.0:  Application.exe - Application Error
The instruction at "0x03b4eddb" referenced memory at "0x00000004". The memory could not be "written". 2: Application.vshost.exe - Application Error
The instruction at "0x0450eddb" referenced memory at "0x00000004". The memory could not be "written". 3: Application.vshost.exe - Application Error
The instruction at "0x7c911669" referenced memory at "0x00000000". The memory could not be "read". 4: Application.vshost.exe - Application Error
The instruction at "0x7c910ed4" referenced memory at "0xfffffff8". The memory could not be "read".
Foi útil?

Solução

Se seu aplicativo é multi-threaded você poderia estar recebendo erros de threads de trabalho que não são devidamente terminais e tentando acessar objetos descartados.

Outras dicas

Eu tive esse problema usando o componente AcrobarReader COM. Cada agora e, em seguida, após a saída do aplicativo eu tinha "Application.vshost.exe - Erro de aplicativo" "memória não pôde ser lida". GC.Collect () e WaitForPendingFinalizers () não ajuda.

Meu google-fu me levam a esta página: http://support.microsoft.com/kb / 826220 . Eu modifiquei o método 3 para o meu caso.

processo Usando o explorador eu achei que AcroPDF.dll não é liberado antes da última linha na função principal. Então, aqui vêm as chamadas de API.

DLLImports (DLLImport está em System.Runtime.InteropServices namespace):

<DllImport("kernel32.dll", EntryPoint:="GetModuleHandle", _
       SetLastError:=True, CharSet:=CharSet.Auto, _
       CallingConvention:=CallingConvention.StdCall)> _
Public Overloads Shared Function GetModuleHandle(ByVal sLibName As String) As IntPtr
End Function

<DllImport("kernel32.dll", EntryPoint:="FreeLibrary", _
    SetLastError:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Overloads Shared Function FreeLibrary(ByVal hMod As IntPtr) As Integer
End Function

E, em seguida, antes da saída do aplicativo:

Dim hOwcHandle As IntPtr = GetModuleHandle("AcroPDF.dll")
If Not hOwcHandle.Equals(IntPtr.Zero) Then
    FreeLibrary(hOwcHandle)
    Debug.WriteLine("AcroPDF.dll freed")
End If

Este procedimento pode ser modificado por qualquer outra dll mal-comportados. Só espero que não introduz novos bugs.

Eu vi plently de erros como esta recentemente. Meus problemas foram releated à forma como o CRT (C Runtime) intereacting com o .NET runtime limpa um processo de fechamento. Meu aplicativo é complicada pelo fato de que é C ++, mas permite que suplementos para a cheia, alguns que são escritos em C #.

Para depurar isso, eu acho que você vai precisar usar depuração nativa. Visual Studio (conjunto de depuração de modo misto) ou WinDbg. Olhe para cima como usar o servidor de símbolos públicos da Microsoft para baixar PDBs para os componentes do Windows -. Você vai necessidade esses símbolos

Muitos dos nossos problemas foram com suporte ao cliente (terrível) COM do .NET. Eu digo terrível, uma vez que não faz referência a contar corretamente (sem um monte de trabalho no final do colaborador). objectos COM não estavam a ser referenciado-contadas para baixo a zero até lixo recolha foi feito. Isso muitas vezes configuração estranha problemas de tempo durante o desligamento -. Com objetos sendo limpo por muito tempo depois que eles deveriam ter sido

A palavra extravagante para "inconsistente" é "não-determinista." E o que acontece não-determinística no ambiente .NET? Objeto destruição.

Quando isso aconteceu comigo, o culpado foi na classe que eu escrevi para embrulhar as chamadas inseguras para uma API externa. Eu coloquei o código de limpeza em destrutor da classe, esperando o código a ser chamado quando o objeto saiu do escopo. Mas isso não é como a destruição de objeto funciona em .NET, Quando um objeto sai do escopo, ele é colocado na fila do finalizador, e seu destruidor não obter chamado até o finalizador fica em torno a ele. Não pode fazer isso até depois das termina programa. Se isso acontecer, o resultado será muito parecido com o que você está descrevendo aqui.

Uma vez eu fiz a minha classe implementar IDisposable, e explicitamente chamado Dispose() sobre o objeto quando eu terminei com ele, o problema foi embora. (Outra vantagem de implementar IDisposable é que você pode instanciar o objeto no início de um bloco using e estar confiante de que Dispose () terá quando as folhas do código do bloco.)

tentar isso para forçar o erro acontecer enquanto estiver sob o controle do programa

   //set as many statics as you can to null;
   GC.Collect();
   GC.WaitForPendingFinalizers();
} //exit main

O erro parou de aparecer depois de usar o código sugerido:

GC.Collect(); 
GC.WaitForPendingFinalizers(); 
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top