Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 10-03-2011
LoPiTaL LoPiTaL is offline
Miembro
 
Registrado: abr 2009
Posts: 168
Poder: 16
LoPiTaL Va por buen camino
Bloque Finalization no se ejecuta

Hola a todos!
Os cuento el problemita de esta semana:
tengo una unit con sus respectivos bloques initialization y finalization.
El bloque initialization se ejecuta correctamente, pero el finalization no lo ejecuta.
Usando la vista completa de la CPU, y viendo lo que ejecuta en ASM, veo que en la parte "initialization" se compara un contador con cero y se decrementa. Si valía cero, ejecuta las instrucciones de este bloque.
Después en la parte "finalization" se hace la operación inversa. Se incrementa y si vale cero, se ejecutan las instrucciones.
En mi programa, veo que entra varias veces a la parte de initialization (decrementando varias veces dicho contador) pero sólo una en la parte finalization (por tanto, no ejecuta nada salvo incrementar el contador).
¿Qué está ocurriendo? ¿Por qué no ejecuta la parte del finalization?

Un saludo,
LoPiTaL
Responder Con Cita
  #2  
Antiguo 10-03-2011
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
¿Qué código es el que tienes ahí? ¿Has probado a colocar puntos de ruptura en la sección de finalización? ¿El compilador te los da como válidos? ¿No se detiene el programa en ellos?

No está de más mencionar qué versión de Delphi estás utilizando.

Saludos.
Responder Con Cita
  #3  
Antiguo 10-03-2011
LoPiTaL LoPiTaL is offline
Miembro
 
Registrado: abr 2009
Posts: 168
Poder: 16
LoPiTaL Va por buen camino
Hola y gracias por la respuesta,
En el finalization tengo sencillamente:
Código:
if assigned(VariableGlobalUsadaSóloEnElPas)
  FreeAndNil(VariableGlobalUsadaSóloEnElPas)
El compilador me lo detecta como instrucciones válidas y me deja poner puntos de ruptura y todo. De hecho, si pongo un punto de ruptura en el if, el programa se detiene ahí, pero (aún cuando en la ventana de Inspect el if devolvería True) no se ejecuta el FreeAndNil, ya que aunque en el código fuente parece que se haya detenido en el if, realmente se detiene antes de hacer la comprobación del contador que he comentado anteriormente.
De hecho, ha sido cuando lo he detenido ahí y he visto qué hacía la CPU, cuando he visto lo del contador y tal.

Estoy usando Delphi 2010.

Un saludo,
LoPiTaL
Responder Con Cita
  #4  
Antiguo 10-03-2011
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
¡Ah! Entonces SÍ ejecuta la sección de finalización, sólo que no entra al If que mencionas.

Lo primero que salta a la vista es que si usas FreeAndNil no necesitas comprobar que la variable sea diferente de Nil. Es decir, si dentro de ese If solamente tienes la llamada a FreeAndNil, el If sobra (FreeAndNil admite punteros con valor de Nil, no haciendo nada si fuese el caso).

¿Sería mucho problema poner el código real completo de las secciones Initialization y Finalization de esa unidad?

¿Cómo compruebas el valor de la variable objeto? Detenido el programa en el punto de ruptura del If (o del FreeAndNil en caso de que quites el If), si agregas una entrada a la lista Watches "Variable = Nil", ¿qué valor se muestra ahí?
Responder Con Cita
  #5  
Antiguo 10-03-2011
LoPiTaL LoPiTaL is offline
Miembro
 
Registrado: abr 2009
Posts: 168
Poder: 16
LoPiTaL Va por buen camino
El código exactamente es el que te he descrito, sólo cambia el nombre de la variable. No tengo nada más.

En la imagen os muestro el CPU View de toda la parte de finalization:



donde he remarcado en verde el incremento del contador (previamente había sido decrementado por el initialization) y su comparación con cero; en marrón la comparación del if y en naranja la ejecución del FreeAndNil.

Estaría perfecto si a la dirección $DD6D0C (donde tengo el punto de ruptura) entrase tantas veces como a entrado a la parte de initialization, porque incrementaría las mismas veces el contador, y al final la comparación haría que no saltase. Pero sólo llega ahí una única vez, mientras que al initialization entra varias, por eso nunca llega a hacer la comparación del if.

He probado también a quitar el if, pero su comportamiento es el mismo (era de esperar, dado que nunca había llegado a ejecutar dicho if).

¿Alguna idea?
Un saludo,
LoPiTaL
Responder Con Cita
  #6  
Antiguo 10-03-2011
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Gracias por estos últimos datos, LoPiTal. Delphi 7 genera un código similar, donde también se incluye el contador interno que mencionas.

El compilador transforma estas secciones Initialization y Finalization en una especie de procedimientos, añadiendo una primera instrucción que disminuye e incrementa el contador, respectivamente.

Si compilas con la opción "Use debug DCUs", podrás seguirle la pista a esas ejecuciones desde los procedimientos InitUnits y FinalizeUnits de la unidad System.pas (salvo que no estén presentes en Delphi 2010). Ahora comprendo el problema, pero no la causa, ya que, como dices, parece existir una disparidad entre las inicializaciones y las finalizaciones.

Una pregunta, ¿tu aplicación utiliza paquetes de tiempo de ejecución o DLLs hechas en Delphi?

Te recomiendo reducir de tamaño la aplicación al tiempo de probar este comportamiento, hasta encontrar qué unidad o paquete está desencadenando el problema.

Saludos.

Al González.
Responder Con Cita
  #7  
Antiguo 11-03-2011
LoPiTaL LoPiTaL is offline
Miembro
 
Registrado: abr 2009
Posts: 168
Poder: 16
LoPiTaL Va por buen camino
Cita:
Una pregunta, ¿tu aplicación utiliza paquetes de tiempo de ejecución o DLLs hechas en Delphi?
Sí, concretamente paquetes de tiempo de ejecución. La aplicación está compilada con la opción "Build with Runtime Packages" activada y cargo dinámicamente algunos paquetes.

Es por esto que no puedo ver los Memory Leaks haciendo ReportMemoryLeaksOnShutdown:=True

Mañana intentaré reproducir el error con una aplicación más sencilla, a ver si reaparece.
Un saludo,
LoPiTaL
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Orden de initialization y finalization mauro_med Varios 0 24-04-2008 00:30:32
con breakpoint ejecuta y sin el no lo ejecuta. pacuuy Varios 1 16-12-2007 13:41:43
type needs finalization henrygale Varios 2 13-02-2007 16:49:44
Bloque de Registros Morphine SQL 5 13-01-2006 15:15:56
bloque de registro Manuel Firebird e Interbase 1 13-11-2003 15:48:28


La franja horaria es GMT +2. Ahora son las 21:56:28.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi