Ir al contenido


Foto

[RESUELTO] Error al salir del programa


  • Por favor identifícate para responder
25 respuestas en este tema

#1 luk2009

luk2009

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.040 mensajes
  • LocationSanto Domingo

Escrito 10 enero 2011 - 01:09

Siguiendo con el tema de este hilo. El problema que me daba durante la ejecucion del programa, ahora solo me lo da al cerrar el programa. Aparentemente es un problema con los componentes zeos.
Imagen Enviada

Aqui les dejo la imagen y mientras me gustaria saber como manejar esta excepcion para que no me de error cuando cierro el programa. Luego les pondre una imagen de la linea del componente zeos donde se sale el programa.






  • 0

#2 luk2009

luk2009

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.040 mensajes
  • LocationSanto Domingo

Escrito 10 enero 2011 - 03:37



delphi
  1. function TZIBEventAlerter.GetPlainDriver: IZInterbasePlainDriver;
  2. begin
  3.   Result := (FConnection.DbcConnection as IZInterbase6Connection).GetPlainDriver;
  4. end;
  5.  
  6. { TIBEventThread }


Esta es la linea que se resalta cuando salgo del programa y estoy en delphi. Alguien menos ciego que yo, podria decirme que significa esto.

  • 0

#3 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 10 enero 2011 - 03:49

Hola luk2009,
Tu ya sabes que no uso Zeos, pero intentaré darte algo de ayuda.

¿Por casualidad no liberas algún componente? ¿Podrías poner el código que tienes en el OnClose y/o OnCloseQuery?

Habría que realizar una traza para ver que línea de tu código provoca esa excepción... Lo más lógico, por el error que comentas y la línea de código, es pensar que haces uso de un TZIBEventAlerter el cual fue liberado.

Sin ver tu código está difícil la cosa.

Saludos,
  • 0

#4 luk2009

luk2009

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.040 mensajes
  • LocationSanto Domingo

Escrito 10 enero 2011 - 07:47

Gracias Delphius por tomarte el tiempo de responder.

Tengo un boton que es que utilizo para cerrar la aplicacion y tiene el siguiente codigo:


delphi
  1. procedure TFRMactivasred.salidaClick(Sender: TObject);
  2. var
  3.   f: TForm;
  4.   begin
  5.   f := Dialogs.CreateMessageDialog('REALMENTE DESEA SALIR', dialogs.mtConfirmation, dialogs.mbOKCancel);
  6.   f.Color := clBlue;
  7.   f.Font.Color := clLime;
  8.   if f.ShowModal = mrOk then
  9.     BEGIN
  10.     Timermonitoreo.Enabled:=false;
  11.     DMmonitorenred.ZConmonred.Disconnect;
  12.     Application.Terminate;
  13.     END;
  14.  
  15.   end;


Esto es lo mismo que tiene el onclosequery.


  • 0

#5 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 10 enero 2011 - 07:59

.........Esto es lo mismo que tiene el onclosequery.


¿Y porque repites el código?, si lo tienes en el evento OnCloseQuery, solo deberías necesitar eso:



delphi
  1. procedure TFRMactivasred.salidaClick(Sender: TObject);
  2. var
  3.   f: TForm;
  4. begin
  5.   f := Dialogs.CreateMessageDialog('REALMENTE DESEA SALIR', dialogs.mtConfirmation, dialogs.mbOKCancel);
  6.   f.Color := clBlue;
  7.   f.Font.Color := clLime;
  8.   if f.ShowModal = mrOk then
  9.     close;
  10. end;



Salud OS
  • 0

#6 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 10 enero 2011 - 08:04

Hola luk2009,

Esto es lo mismo que tiene el onclosequery.


Umm, si por "esto es lo mismo" te refieres a que ese código está repetido en el OnCloseQuery entonces el error es evidente, o al menos infiero por donde va los tiros.

Fíjate en la línea:



delphi
  1. DMmonitorenred.ZConmonred.Disconnect; 



Si es como yo lo entiendo, y esa misma instrucción está en el OnCloseQuery, entonces ese Zconmonred en su método Disconnect libera algo de la memoria. De ser cierto, ante la pulsación del botón y la confirmación del diálogo entonces se libera el objeto.

Luego, al dispararse el evento OnCloseQuery se vuelve a ejecutar las mismas instrucciones... por tanto al volver a confirmar, se intentará volver a liberar un objeto que fue liberado. Conclusión: un AccessViolation.  ;)

La solución pasaría por hacer que el botón dispare el OnCloseQuery y no repetir el código.

Ahora bien si yo he entendido mal, te pediría que te explicases mejor y nos brindaras más información.

Saludos,
  • 0

#7 luk2009

luk2009

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.040 mensajes
  • LocationSanto Domingo

Escrito 10 enero 2011 - 08:07

Gracias Egostar, eso pensaba yo, pero entonces despues que le doy ok, me repite el mismo cuadro y tengo que vover a darle ok para cerrar el programa.
  • 0

#8 luk2009

luk2009

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.040 mensajes
  • LocationSanto Domingo

Escrito 10 enero 2011 - 08:09

Delphius dejame probar lo que indicas y te aviso
  • 0

#9 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 10 enero 2011 - 08:11

Gracias Egostar, eso pensaba yo, pero entonces despues que le doy ok, me repite el mismo cuadro y tengo que vover a darle ok para cerrar el programa.


Pues, mas fácil, quita todo el código del botón y sólo deja el Close; en el evento OnCloseQuery se hará todo.

Salud OS
  • 0

#10 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 10 enero 2011 - 08:16

Sólo para complementar, en el evento OnCloseQuery necesitas validar si deseas que se termine o no la aplicación, de otra forma no hará caso de la pregunta "REALMENTE DESEA SALIR"



delphi
  1.   if f.ShowModal = mrOk then
  2.     Application.Terminate
  3.   else CanClose := false;



Salud OS
  • 0

#11 luk2009

luk2009

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.040 mensajes
  • LocationSanto Domingo

Escrito 10 enero 2011 - 08:22

Egostar, eso mismo habia hecho y tienes razon el onclosequery se encarga de todo.

Delphius la verdad es que no he liberado el evento TZIBEventAlerter en ningun lado, pero leyendo lo que me indicaste he comentado la linea:


delphi
  1. DMmonitorenred.ZConmonred.Disconnect;



y con esto el error desaparecio. Mi duda ahora es si es que al no haber liberado el eventalerter al intentar disconectarme me salta el error.
Que problemas puede tener el no hacer la desconexion.

por ahora no hay error y ademas tengo menos codigo. gracias a los dos
  • 0

#12 luk2009

luk2009

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.040 mensajes
  • LocationSanto Domingo

Escrito 10 enero 2011 - 08:28

Sólo para complementar, en el evento OnCloseQuery necesitas validar si deseas que se termine o no la aplicación, de otra forma no hará caso de la pregunta "REALMENTE DESEA SALIR"



delphi
  1.   if f.ShowModal = mrOk then
  2.     Application.Terminate
  3.   else CanClose := false;



Salud OS


talvez ese era el problema de porque no funcionaba el boton solo, porque en el onclosequery lo tengo como indicas, pero en el boton no estaba completo. gracias de nuevo.
  • 0

#13 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 10 enero 2011 - 09:07

Hola luk2009,

El asunto es que ese método Disconnect libera algo. Tu no liberas en forma explícita, pero dentro de ese componente Zeos, algo se libera cuando se ejecuta el método. De ese modo, cuando primero se ejecuta el código de botón se libera y luego, cuando se ejecutaba el evento OnCloseQuery y se confirmaba se volvía a intentar a liberar el mismo... y como ya había sido liberado es que se recibe el Access Violation.

La solución, como te habíamos comentado pasaba por hacer que el botón invocase a Close y dejar el código a evento OnCloseQuery que hiciera el trabajo.

Saludos,
  • 0

#14 luk2009

luk2009

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.040 mensajes
  • LocationSanto Domingo

Escrito 10 enero 2011 - 09:31

Te entiendo Delphius, pero si dejo sin marcar  DMmonitorenred.ZConmonred.Disconnect entonces el error vuelve a salir. Esto es asi aun despues de haber hecho los cambios que me indican y solo poner close en el boton de salir.



delphi
  1. procedure TFRMactivasred.FormCloseQuery(Sender: TObject;
  2.   var CanClose: Boolean);
  3.   var
  4.   f: TForm;
  5.   begin
  6.   f := Dialogs.CreateMessageDialog('REALMENTE DESEA SALIR', dialogs.mtInformation, dialogs.mbOKCancel);
  7.   f.Color := clBlue;
  8.   f.Font.Color := clLime;
  9.   if f.ShowModal = mrOk then
  10.     BEGIN
  11.       Timermonitoreo.Enabled:=false;
  12.   // DMmonitorenred.ZConmonred.Disconnect;
  13.       Application.Terminate;
  14.     END
  15.     else
  16.       canclose := false;
  17.   end;


  • 0

#15 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 10 enero 2011 - 10:03

Ummm... Habrá que mirar más profundo. ¿Y haciendo la traza en donde sale el error? Habría que ver si es que no hay otra parte del código que esté haciendo alguna liberación involuntaria.

Recuerden bien que el Terminate internamente libera todo los objetos (en realidad el objeto de la variable global Application). Luego Application derivaba las órdenes en sus forms.
Aquí ya depende del valor de la variable Action del OnClose. Si el valor de dicha variable es caFree se obliga al compilador a liberar toda la memoria (formularios y controles creados).
Quizá en parte el problema esté allí.

Ten en cuenta, además, de que los DataModules se crean ANTES que los forms (al menos de forma predeterminada), y el hacer un Terminate se fuerza a finalizar el sistema contra su voluntad y no seguir los cursos normales (sobre todo si los DataModules se crean de forma dinámica). En teoría al finalizar el formulario principal de forma abrupta corta el hilo principal de ejecución, con lo cual quedarían los DataModules sin liberar y por consiguiente sus controles.
La buena práctica indica que deben "cerrarse" y liberarse los DataModules PRIMERO y luego ya el form principal.

Habría que investigar mejor tu sistema luk2009 para saber donde está el problema... Haz una traza paso a paso y vuelve sobre tus pasos. Revisa tu código por si estás liberando algo... El principal motivo de un AccessViolation es un intento de acceder a una memoria liberada pero no es el único...

Hay que estudiarlo, sin tener más información... estaremos adivinando.

Saludos,
  • 0

#16 luk2009

luk2009

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.040 mensajes
  • LocationSanto Domingo

Escrito 10 enero 2011 - 10:35

voy a revisar lo que me dices y voy a liberar el datamodule primero y luego el form principal a ver que pasa. Si aun asi no funciona entonces voy a revisar paso a paso y te muestro la linea del error.

gracias por tu tiempo delphius. (y)
  • 0

#17 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 10 enero 2011 - 11:01

voy a revisar lo que me dices y voy a liberar el datamodule primero y luego el form principal a ver que pasa. Si aun asi no funciona entonces voy a revisar paso a paso y te muestro la linea del error.

gracias por tu tiempo delphius. (y)


O bien puedes ir al menu de Delphi --> Search --> Goto Address y en la ventana que te muestra poner la dirección $00590999, la cual te llevará a la línea donde está el error. Casi estoy seguro que en las versiones de Delphi hasta la 7 se llama Find Error, en las versiones 2006 en adelante Goto Address.

Tienes que pausar la ejecución del programa, puedes poner un Breakpoint y cuando se pause hacer lo que ya te mencioné.

Salud OS
  • 0

#18 luk2009

luk2009

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.040 mensajes
  • LocationSanto Domingo

Escrito 11 enero 2011 - 05:36



delphi
  1. function TZIBEventAlerter.GetPlainDriver: IZInterbasePlainDriver;
  2. begin
  3.   Result := (FConnection.DbcConnection as IZInterbase6Connection).GetPlainDriver;
  4. end;
  5.  
  6. { TIBEventThread }


Egostar la linea del result es la que se resalta con el find error.

  • 0

#19 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 11 enero 2011 - 07:30

Esto confirma que algunos componentes/objetos Zeos se están (o se han) liberando. Pero el problema no es porqué sale el error allí... sino porqué sale el error y desde donde se viene arrastrando.

¿Puedes rastrear la línea de TU código que lleva hacia ese error? Sigue los pasos que te comenta Egostar añadiendo breakpoints y ve línea a línea o algunos grupos de líneas ayudándote con las teclas F7, Shift+F7 y F8.

Acompañate de las ventanas de debug, y examina el resultado o contenido de algunas de las variables objeto.

Se que es un proceso tedioso y lento pero no hay otro modo, debes hacerlo desde tus unidades, viendo tu código para ver como se va propagando hasta llegar a las unidades Zeos.

El punto es que es NECESARIO encontrar la línea de tu código que lleva al error, y no la línea de la unidad Zeos que lo provoca.
Es evidente que el problema está en un componente Zeos, es fundamental hallar al culpable... puede ser el TZIBEventAlerter, o el FConnection o quizá el DbcConnection que está asociado...

Pero viendo esa línea de código es difícil... hay que rastrear justo la última línea de tu código que lleva a ese error y de allí empezar a rastrear al culpable hasta el lugar en el que es liberado. Porque de algún modo algún objeto es liberado...

Estamos ciegos luk2009, bastante ciegos. Sin tener una ojeada de tu código lo máximo que podemos hacer es tirar unos cuantos palos al aire para ver si de casualidad le pegamos a un transeúnte y le preguntamos ¿Che... vos sos el que está causando problemas?

Por ello te digo que vayas con las ventanas de debug, más que nada con la ventana Watches, y también la Evaluate/Modify.

Hay que salir de la biblioteca Zeos... hay que ver el problema desde tu código. No te vayas tan adelante.

Si el error está indicando en el método de TZIBEventAlerter es una buena elección empezar a rastrear todo lo que se hace con el componente; desde que se crea y donde se lo va utilizando, si es éste el que se libera en algún momento se debería llegar a un .Free.

Saludos,
  • 0

#20 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 11 enero 2011 - 07:39

También te recomendaría que hicieras esta prueba:



delphi
  1. if Assigned(ElObjetoX)
  2.   then showMessage('El objeto X está vivo')
  3.   else showMessage('El objeto X está muerto. Cuidado... utilizarlo provoca un AV');



Siendo ElObjetoX el nombre de tus componentes/objetos que utilices. Empieza con tus objetos TZIBEventAlerter y luego con otros objetos.

Si el error viene cuando se cierra la aplicación es conveniente que esa prueba se haga en OnClose o en OnCloseQuery.

Esta prueba sencilla podría ayudar a rastrear al desgraciado. Si es que realmente el AccessViolation es causado por un intento de utilizar un objeto ya liberado. Al menos el mensaje de error indica que el AV se presenta cuando se intenta leer una zona de memoria 0, eso indica que un componente o control está liberado.

Saludos,

  • 0




IP.Board spam blocked by CleanTalk.