2011-02-27 17 views
26

Nuestra aplicación experimenta la rara y fatal System.AccessViolationException. Vemos esto ya que hemos configurado el evento AppDomain.CurrentDomain.UnhandledException para registrar la excepción.buscando la causa de System.AccessViolationException

Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. 
    at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 
    at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 
    at System.Windows.Forms.Application.Run(Form mainForm) 
    at Bootstrap.Run() in e:\build-dir\src\Bootstrap.cs:line 25 

La excepción en sí no parece contener más información que el mensaje "Intento de leer o escribir en la memoria protegida. Esto es a menudo una indicación de que otra memoria está dañada."

  • ¿Qué pasos podemos tomar ahora para llegar a la causa del problema?
  • ¿Hay alguna manera de determinar la dirección ilegal o el valor del puntero que causó el bloqueo?
  • ¿Podemos averiguar qué código de biblioteca nativa estaba causando el problema?
  • ¿Hay más depuración/rastreo que podamos habilitar?

ACTUALIZACIÓN

  • Podría esto ser causado por el uso no-hilo anterior de la API de Windows Forms?
+1

¿Ha intentado ejecutar este con un depurador asociado, también con suficientes símbolos cargados para dar una pila de llamadas útil? –

Respuesta

5

Lo que está experimentando es el equivalente exacto a "El programa ha tenido un problema y ahora se cerrará", excepto que está siendo capturado por el tiempo de ejecución de .NET, en lugar del sistema operativo.

Al observar el seguimiento de la pila, no está siendo activado por su código, lo que me hace pensar que proviene de un hilo de trabajo generado por una biblioteca que está utilizando o un control personalizado.

La única manera de rastrear algo como esto sería ejecutar las bibliotecas nativas bajo un depurador, que debería atrapar la violación de acceso antes de que salte a la capa CLR. Esto puede ser fácil o difícil.

Si el código nativo es su propio proyecto, la forma más fácil de configurar esto es poner el proyecto .NET y el proyecto C++ en la misma solución, y asegurarse de que el proyecto .NET hace referencia al proyecto C++ . Si publica más detalles sobre su entorno, es posible que pueda dar consejos más específicos.

+1

No es un hilo de trabajo, esto muere en el hilo de la interfaz de usuario principal. Nota Application.Run() –

+1

De acuerdo con el comentario de Hans. Obtenemos informes de esto muy ocasionalmente en las máquinas de los usuarios en .NET Reflector: Application.Run() arroja una AccessViolationException, pero no tenemos idea de por qué. Es muy raro y nunca lo hemos visto en casa, así que nunca hemos podido depurarlo. Me encantaría tener una idea tangible de lo que está pasando mal para poder al menos dirigir a los usuarios hacia alguna información útil, pero, por desgracia, hasta ahora me han negado. –

3

El seguimiento de la pila apunta a datos incorrectos en el parámetro MSG del mensajero de envío nativo. ¿Has intentado cargar los símbolos de Microsoft y verificar los parámetros de ese rastro de pila?

Sin conocer los controles en su interfaz de usuario ni en los eventos a los que se ha conectado, será difícil determinar cuál es exactamente el problema.

2

Tuve un problema similar y, a diferencia de @BartRead, consistentemente. Para mí, algunos códigos de CLI funcionaban bien en una aplicación de formularios de Windows simple, pero cuando los incluía en un ecosistema de plugin larager (multiproceso), los mensajes necesitaban ser ejecutados con Application.Run o Application.DoEvents. Si tiene acceso al código que se está generando, la mejor opción (lo que funcionó para mí) fue comentar cada vez más fragmentos del código sin dejar de mantener la funcionalidad. Resultó que no tenía GC :: Alloc'd callback/delegate y mientras estaba inmovilizado y aún referenciado había sido movido en la memoria o directamente marcado para la recopilación.

si usa GC Alloc, ¡asegúrese de limpiarlo después de usted!

1

tuve este problema al ejecutar un procedimiento almacenado utilizando ADO. este error tenía dos causas:

  1. cadena de conexión incorrecta.
  2. parámetro de tipo miss-match (pasando de una larga para db-int32 o largo a nvarchar (10), que es más corto)
Cuestiones relacionadas