¿Cuáles son algunas de las técnicas para solucionar problemas de infracción de acceso muy intermitente en un dispositivo con Windows Mobile?

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

Pregunta

Tengo una gran aplicación Compact Frameworks V2.0 que en la mayoría de los casos funciona muy bien. En ciertos dispositivos, aproximadamente una vez al día, un usuario recibe un Error nativo 0xC0000005 que no se detecta con el bloque estándar de prueba / captura administrado.

Mi aplicación se sincroniza con el servidor a través de llamadas ASMX a intervalos fijos. El problema parece ocurrir durante la sincronización. Existe una lógica de negocios considerable además de la llamada ASMX que ocurre en el momento de la sincronización, pero el 98% de eso es código administrado. He revisado todas mis bibliotecas P / Invokes y las aplicaciones nativas de C ++ y, en este momento, tengo un 95% de certeza de que el problema no está allí.

Dado que esto solo ocurre en ciertos dispositivos y con muy poca frecuencia (menos de una vez al día) es muy difícil aislarlo. He implementado mi código y parece que ocurre en lugares aleatorios dentro de la aplicación, por lo que sospecho que algo está corrompiendo la memoria.

Cualquier comentario sobre cómo solucionar este problema aún más sería apreciado.

¿Fue útil?

Solución 2

Mi manejo de excepciones de C ++ nativo no incluía una excepción asíncrona y, por lo tanto, no detectaba excepciones de infracción de acceso.

Esto puede / no puede ser útil para mi problema, pero puede ser útil para otros.

El uso del modificador / EHa como se documenta en este enlace permitirá detectar este tipo de excepciones:

http://msdn.microsoft.com/en-us/library /1deeycx5.aspx

Otros consejos

Un 0xC0000005 es una infracción de acceso, por lo que algo intenta leer o escribir en una dirección a la que no tiene derechos de acceso. Estas tienden a ser realmente difíciles de encontrar y la experiencia es una de las mejores herramientas (bueno, el depurador de Platform Builder también es muy útil, pero es una vía totalmente independiente de depuración y requiere experiencia que probablemente no tenga o que ya tendría lo intenté). Me parece que el registro tiende a ser menos útil que la codificación sustractiva: eliminar P / invocar llamadas con llamadas gestionadas de forma simulada siempre que sea posible.

Las infracciones de acceso en las aplicaciones administradas suelen ocurrir por uno de estos motivos:

  • P / Invoca una API nativa que pasa en un identificador a un objeto administrado y la API nativa usa ese identificador. Si obtiene una colección y compactación mientras la API nativa se está ejecutando, el objeto administrado puede moverse y el puntero se vuelve inválido.
  • Usted P / Invoca algo con un búfer que es demasiado pequeño o más pequeño que el tamaño que pasa y la API supera una lectura o escritura
  • Un puntero (IntPtr, etc.) que pasa a una llamada P / Invoke no es válido (-1 o 0) y el nativo no lo está comprobando antes de usarlo
  • P / Invoca una llamada nativa y el código nativo se queda sin memoria (generalmente virtual) y no está verificando las asignaciones fallidas y lee / escribe en una dirección no válida
  • Utiliza un GCHandle que no está inicializado o que de alguna manera está apuntando a un objeto ya finalizado y recolectado (por lo que no está apuntando a un objeto, está apuntando a una dirección donde un objeto solía estar)
  • Su aplicación usa un identificador para algo que se invalidó por un estado de suspensión / activación. Esto es más esotérico pero ciertamente ocurre. Por ejemplo, si está ejecutando una aplicación desde una tarjeta de almacenamiento, la aplicación completa no se carga en la RAM. Las piezas en uso son pagadas por demanda para su ejecución. Todo esto está muy bien. Ahora, si apaga el dispositivo, todos los controladores se apagarán. Cuando enciende la copia de seguridad, muchos dispositivos simplemente vuelven a montar los dispositivos de almacenamiento. Cuando su aplicación necesita una página de demanda en más programas, ya no está donde estaba y muere. Un comportamiento similar puede ocurrir con las bases de datos en tiendas montadas. Si tiene un identificador abierto en la base de datos, es posible que, después de un ciclo de suspensión / activación, el identificador de conexión ya no sea válido.

Notarás la tendencia aquí de que casi todos estos son P / Invokes y eso no es un accidente. Es bastante difícil obtener el código administrado para hacer esto por sí solo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top