c# - memoria - encontrar la causa de System.AccessViolationException
catch accessviolationexception (4)
Nuestra aplicación experimenta la rara excepción System.AccessViolationException. Los vemos como hemos configurado el evento AppDomain.CurrentDomain.UnhandledException para registrar la excepción.
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í misma no parece contener más información que el mensaje "Se intentó leer o escribir en la memoria protegida. Esto suele indicar que otra memoria está dañada".
- ¿Qué pasos podemos tomar ahora para llegar a la causa del problema?
- ¿Hay alguna forma de determinar la dirección ilegal o el valor del puntero que causó el bloqueo?
- ¿Podemos averiguar qué código de biblioteca nativo estaba causando el problema?
- ¿Hay más depuración / seguimiento que podamos habilitar?
ACTUALIZAR
- ¿Podría deberse a un uso anterior no seguro para subprocesos de la API de WinForms?
El seguimiento de la pila apunta a datos erróneos en el parámetro MSG del mensajero de envío nativo. ¿Ha intentado cargar los símbolos de Microsoft y comprobar los parámetros de ese seguimiento de pila?
Sin conocer los controles de tu interfaz de usuario y los eventos a los que te has conectado, será difícil determinar cuál es exactamente el problema.
Lo que está experimentando es el equivalente exacto a "El programa ha experimentado un problema y ahora se cerrará", excepto que el tiempo de ejecución de .NET lo está detectando, en lugar del sistema operativo.
Al observar el seguimiento de la pila, su código no lo activa, lo que me hace pensar que proviene de un subproceso de trabajo generado por una biblioteca que está usando o un control personalizado.
La única manera de rastrear algo como esto sería ejecutar las bibliotecas nativas bajo un depurador, lo que debería interceptar la infracción de acceso antes de que aparezca en la capa CLR. Esto puede ser fácil o difícil.
Si el código nativo es su propio proyecto, entonces la forma más fácil de configurar esto es colocar el proyecto .NET y el proyecto C ++ en la misma solución, y asegurarse de que el proyecto .NET haga referencia al proyecto C ++. Si publica más detalles sobre su entorno, es posible que pueda darle consejos más específicos.
Tuve este problema al ejecutar un procedimiento almacenado utilizando ADO. este error tuvo dos causas:
- Mala cadena de conexión.
- tipo de parámetro miss-match (que pasa en largo para db-int32 o long para nvarchar (10) que es más corto)
Tuve un problema similar y, a diferencia de @BartRead, consistentemente. Para mí, algo de código CLI funcionaba bien en una aplicación de formularios de Windows simple, pero cuando lo puse en un ecosistema de plugin larager (multiproceso), los mensajes debían activarse con Application.Run o Application.DoEvents. Si tiene acceso al código que se está bombeando, la mejor apuesta (lo que funcionó para mí) fue comentar más y más partes del código sin dejar de mantener la funcionalidad. Resultó que no tenía GC :: Asignado una devolución de llamada / delegado y, mientras que el número de pines y todavía referenciado se había movido en la memoria o se había marcado directamente para su recopilación.
Si usa GC Alloc, asegúrese de limpiar después de usted mismo.