Excepciones lanzadas (errores encontrados) después de la finalización del programa

StackOverflow https://stackoverflow.com/questions/182622

  •  06-07-2019
  •  | 
  •  

Pregunta

Tengo una aplicación que parece lanzar excepciones solo después de que el programa se ha cerrado. Y es muy inconsistente. (Todos sabemos lo divertidos que son los errores inconsistentes ...)

Supongo que hay un error durante el proceso de limpieza. Pero estos errores de lectura / escritura en la memoria parecen indicar que algo está mal en mi " inseguro " uso de código (punteros?).

Lo que me interesa es cuál es el mejor método para depurar estas situaciones.
¿Cómo depurar un programa que ya se ha cerrado?
Estoy buscando un punto de partida para resolver un problema mayor.

Estos errores parecen presentarse de varias formas (tiempo de ejecución, depuración):

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".
¿Fue útil?

Solución

Si su aplicación tiene varios subprocesos, es posible que reciba errores de subprocesos de trabajo que no finalizan correctamente e intentan acceder a los objetos desechados.

Otros consejos

Tuve este problema al usar el componente COM AcrobarReader. De vez en cuando, después de salir de la aplicación, tenía "Application.vshost.exe - Error de aplicación" " memoria no se pudo leer " ;. GC.Collect () y WaitForPendingFinalizers () no ayudaron.

Mi google-fu me lleva a esta página: http://support.microsoft.com/kb / 826220 . Modifiqué el método 3 para mi caso.

Usando el explorador de procesos, descubrí que AcroPDF.dll no se publica antes de la última línea en la función Principal. Entonces, aquí vienen las llamadas a la API.

DLLImports (DLLImport está en el espacio de nombres System.Runtime.InteropServices):

<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

Y luego, antes de salir de la aplicación:

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

Este procedimiento puede modificarse para cualquier otro dll mal comportamiento. Solo espero que no presente ningún error nuevo.

He visto muchos errores como este recientemente. Mis problemas se relacionaron con la forma en que el CRT (C Runtime) que interactúa con el .NET runtime limpia un proceso de cierre. Mi aplicación es complicada por el hecho de que es C ++, pero permite cargar complementos COM, algunos de los cuales están escritos en C #.

Para depurar esto, creo que necesitará utilizar la depuración nativa. Visual Studio (configurado para depuración en modo mixto) o WinDbg. Consulte cómo usar el servidor de símbolos públicos de Microsoft para descargar PDB para componentes de Windows: ne< esos símbolos.

Muchos de nuestros problemas fueron con el soporte de clientes COM de .NET (horrible). Digo horrible, ya que no hace referencia al recuento correctamente (sin mucho trabajo por parte del desarrollador). Los objetos COM no se referenciaban a cuenta regresiva hasta cero hasta que se realizara la recolección de basura. Esto a menudo genera problemas de tiempo extraños durante el apagado: los objetos COM se limpian mucho después de lo que deberían haber sido.

Una palabra más elegante para "inconsistente" es "no determinista". ¿Y qué sucede de manera no determinista en el entorno .NET? Destrucción de objetos.

Cuando esto me sucedió, el culpable estaba en la clase que escribí para ajustar las llamadas inseguras a una API externa. Puse el código de limpieza en el destructor de la clase, esperando que se invoque el código cuando el objeto salga del alcance. Pero no es así como funciona la destrucción de objetos en .NET. Cuando un objeto se sale del alcance, se coloca en la cola del finalizador y no se llama a su destructor hasta que el finalizador lo alcanza. Es posible que no lo haga hasta que finalice el programa. Si esto sucede, el resultado se parecerá mucho a lo que está describiendo aquí.

Una vez que hice que mi clase implementara IDisposable , y explícitamente llamé Dispose () en el objeto cuando terminé con él, el problema desapareció. (Otra ventaja de implementar IDisposable es que puede crear una instancia de su objeto al comienzo de un bloque usando y estar seguro de que Dispose () se obtendrá cuando el código abandone el bloque).

intente esto para forzar el error mientras está bajo el control del programa

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

El error dejó de aparecer después de usar el código sugerido:

GC.Collect(); 
GC.WaitForPendingFinalizers(); 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top