2011-03-03 7 views
13

Por lo tanto, después de algunos cambios recientes descubrimos que una de nuestras aplicaciones más antiguas a veces falla al apagar. Esto se manifiesta en forma de mensajes de "Error de tiempo de ejecución 216" o en un mensaje de Informe de errores de Windows que indica que la aplicación ha dejado de funcionar. La aplicación ya está emitiendo OutputDebugString -mensajes en todo momento y AFAICT todo nuestro código se ejecuta correctamente hasta su finalización. Se invocan todos los destructores, como todas las secciones de finalización y los destructores de clase, ninguno de los cuales genera excepciones.¿Cómo depurar un bloqueo que solo ocurre al apagar la aplicación? (Delphi)

Además, ni el modo de depuración completa madExcept ni FastMM4 parecen tener algo de lo que quejarse (aunque podría ser una conclusión falsa porque el bloqueo puede ocurrir incluso antes de que se ejecute el código de finalización de esos componentes).

Entonces, ¿qué harías? ¿Dónde comenzarías?


Esta pregunta se supone que es más sobre el enfoque general para esta clase de problemas que sobre el caso específico actualmente estoy haciendo frente así que estoy deliberadamente dejando de lado los detalles. No dude en preguntar si cree que podrían ser relevantes para la elección del enfoque de depuración y los agregaré más adelante.

+4

Hay un error de VCL que se manifiesta como AV en el cierre. Está relacionado con la destrucción de formularios por parte del "Propietario". Lo soluciono cerrando formularios explícitamente en el archivo .dpr después de 'Application.Run'. Si deja que 'Application' haga el cierre por usted, puede haber problemas con las referencias obsoletas. –

+0

@David: Eso suena interesante. ¿Tienes un número de control de calidad para eso? Sin embargo, a excepción del formulario principal, estoy creando todos los formularios en el código con el formulario principal respectivo como el propietario. ¿El problema del que está hablando se aplica también en ese caso? –

+0

si confía en la destrucción de la Aplicación para reducir todo lo demás, entonces podría aplicarse el error del que estoy hablando. Intenta poner un 'MainForm.Free' en tu archivo .dpr. Miraré el número de control de calidad. –

Respuesta

2

Es probable que tenga un problema con el puntero. Algún evento o método está tratando de ejecutarse en un objeto que ya no existe.

+0

Sí, eso es lo que implica el "Error de tiempo de ejecución 216" más o menos, pero la pregunta era ¿cómo harías para rastrear ese problema? –

+0

Si puede reproducirlo de manera confiable, entonces puede usar el depurador (necesitará Debug DCU) para determinar dónde sucede. Desafortunadamente, creo que es probable que tenga un rastro de pila bastante inútil en el momento en que se plantea. –

+0

@David: la "reproducción confiable" del problema sigue siendo un problema: diría que ocurre aproximadamente el 60% del tiempo. Y aún no he podido determinar la diferencia entre las sesiones de trabajo y las que no. De hecho, ya pensé que había solucionado el problema un par de veces para que volviera a funcionar un par de sesiones más tarde ... –

3

Bueno, el Runtime error 216 es un problema de memoria (Access violation), parece que se refiere a algún objeto que no existe en ese momento.

Emarcadero escribe:

Las aplicaciones que utilizan los SysUtils mapa de clases mayoría de los errores de tiempo de ejecución de las excepciones, que permiten su aplicación para resolver el error sin necesidad de terminar

¿trató de establecer un breackpoint a la finalización sección de Sysutils?

Lo intentaría con un Allocation/Memory Profiler, no estoy seguro de que encuentre la línea de código de error, pero esto puede mostrarle algunas partes de su código donde ocurren problemas de memoria.

5

¿Está utilizando paquetes de tiempo de ejecución? He visto problemas similares antes. Si comparte compartimentos globales o interfaces a través de límites de paquetes, debe asegurarse de que todas las referencias a las clases que pertenecen a un determinado paquete se limpien antes de descargar el paquete; de lo contrario, tratarán de hacer llamadas virtuales en la memoria que ya no es válida.

+0

Oh, sí, no solo los paquetes de tiempo de ejecución sino también las COM-DLL (es decir, los complementos) que dependen de estos paquetes (al igual que el host EXE). No preguntes No lo haría de nuevo de esta manera hoy, pero ha estado funcionando impecablemente durante más de 10 años ... Sin embargo, revisaré todas las referencias a algunos de los singleton globales. Eso sí suena prometedor ... –

+2

"funcionando impecablemente durante más de 10 años" ¿Qué ha cambiado? Esa es probablemente la forma en que atacaría este problema. –

+0

Touché! ;) Ese es casi lo suficientemente bueno para una respuesta aceptada. :-P –

12

Un error de tiempo de ejecución 216 significa que tiene una Av (infracción de acceso) y SysUtils ya ha dejado de traducir esos errores a excepciones.

Primer intento: compilar con DCU de depuración y buscar en el sistema de la unidad donde se produce el error, establecer un punto de interrupción allí. con suerte, puede atraparlo en el depurador y trabajar desde allí.

Es probable que tenga un error de memoria (puntero colgante, referencia nula, etc. uso de cadena s constante en una unidad ya finalizada) y el mejor truco es verificar las finalizaciones después de que finalice sysutils. Puede hacer esto construyendo WITH debug dcu's, estableciendo el punto de ruptura hasta la finalización en sysutils y comenzando a recorrer el código hasta que ocurra el error.

2

"Error de tiempo de ejecución 216" es de Windows, no del controlador de excepciones Delphi. Descubrí que se debe a un código que se ejecuta en las secciones de inicialización y finalización de las unidades, que se ejecutan antes de que el controlador de excepciones Delphi se active. Particularmente. Los objetos COM que deben descargarse a través del código de finalización que se ejecuta después de que la aplicación Delphi ha finalizado provocarán este y otros errores similares. Entonces revisa eso.

MNG

+3

No exactamente: vea en el sistema de la unidad: función MapToRunError asigna el código de error NT STATUS_ACCESS_VIOLATION a ErrCode: = 216. –

+0

Gracias por el comentario, independientemente de que esto ocurra antes o después de que se haya inicializado el manejador de excepción de la aplicación Delphi predeterminado. Las unidades se cargan en función de la cláusula uses antes de iniciar la aplicación Delphi, se descargan después de que la aplicación finaliza, la sección de inicialización y finalización se ejecuta al cargar y descargar la unidad y el código que se ejecuta no es manejado por el manejador de excepciones de la aplicación Delphi. Es por eso que obtienes un críptico "error de tiempo de ejecución 216" o 217 y ningún mensaje de excepción "violación de acceso a E .. @ 'etc. – user643124

+1

Esto no es cierto; el 216 es del Delphi RTL, después de que el mecanismo de manejo de excepciones fuera desenganchado.Es la manera Delphi de decir que hay un AV. El 216 no es de Windows. –

2

Al igual que otros dijeron: 216 significa AV después de SysUtils fue apagado. Por lo general, lo único que se apaga después de SysUtils (y tiene la posibilidad de elevar AV) - es la unidad del sistema. Específicamente: administrador de memoria.

Por lo tanto, el error en tiempo de ejecución 216 en el cierre generalmente significa error de memoria error en su aplicación.

Eso puede ser muy fácil de resolver: simplemente habilite el modo de depuración completo en el administrador de memoria o use un administrador de memoria de depuración. A veces, sin embargo, puede ser muy difícil de encontrar. Pero primero puedes comenzar con el modo de depuración de MM.

Ver this article.

Cuestiones relacionadas