Ir al contenido



Foto

Error SIGSEGV controls.pp 2751


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

#1 Gaston

Gaston

    Advanced Member

  • Miembros
  • PipPipPip
  • 63 mensajes

Escrito 03 febrero 2017 - 09:12

Hola gente, les traigo un caso para el psiquiatra.

 

Como hago siempre, programo en Linux y una vez que está todo OK, me doy una vuelta por Windows y compilo, generalmente sin ningún problema, realmente funciona muy bien. Pero... hoy me encuentro con un error cuando compilo en Windows (en Linux marcha todo en orden): SIGSEGV controls.pp 2751 cuando compilo y ejecuto. Ahora, si ejecuto directamente el .exe el error pasa a ser "Access violation" pero si le doy "Aceptar" el programa sigue sin ningún problema.

 

Veamos el error que me marca:


delphi
  1. function BidiFlipAlignment(Alignment: TAlignment; Flip: Boolean): TAlignment;
  2. const
  3.   BidiAlignment: array[Boolean, TAlignment] of TAlignment =
  4.   (
  5.     ( taLeftJustify, taRightJustify, taCenter ),
  6.     ( taRightJustify, taLeftJustify, taCenter )
  7.   );
  8. begin
  9.   Result := BidiAlignment[Flip, Alignment]; //<---- Línea 2751 ahí tira el error
  10. end;     

Ahora vamos a mi código donde salta el error:


delphi
  1. DBGridAs.Enabled:=False;
  2. DMConta.ZQGridAS.DisableControls;
  3. try
  4. GraboTempAsientos;
  5. // ShowMessage('Hola');
  6. FormRegDiario:=TFormRegDiario.Create(nil);
  7. FormRegDiario.ShowModal;
  8. FreeAndNil(FormRegDiario);
  9. finally
  10. DMConta.ZQGridAS.SQL.Text:=sqlgrid;
  11. DMConta.ZQGridAS.Open;
  12. DMConta.ZQGridAS.EnableControls;
  13. end;
  14. DBGridAs.Enabled:=True;
  15. end;

Y aquí viene lo del psiquiatra, poniendo el showmessage para detectar el error. Como verán ShowMessage está como comentario, pero lo gracioso, es que si lo dejo,es decir lo activo, le quito //, no manda ningún error, claro no es la solución, muestra un "Hola" y el botón aceptar, pero entonces? Hay algo muy raro ahí, no puede un Showmessage solucionar un error, hasta donde sé.

 

Alguien sabe que puede suceder?

 

Saludos.


  • 0

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.441 mensajes
  • LocationMéxico

Escrito 04 febrero 2017 - 06:58

Hola.

Como estas cosas son del demonio, vamos a ver que pasa.

Coloca en lugar del shiwmesage una pausa de digamos 100 ms, en delphi de usa el sleep(100) no se en Lazarus.

Saludos
  • 1

#3 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.833 mensajes
  • LocationArgentina

Escrito 04 febrero 2017 - 12:24

Vamos por partes, hablas de un error, pero por tu descripción pareciera ser de dos: Uno en la función BidiFlipAligment y otro en el uso de ShowMessage.

 

Respecto a la función BidiFlipAligment, tengo un par de preguntas y dudas. ¿Cuál es el objetivo de esa función? ¿Y que valor debería devolverte en cada caso?

Ese código no debería poder compilarte porque esa forma de hacer array no es permitida. Un array necesita un rango para definir su índice y TAligment no lo es. Se puede usar los enumerativos pero así:


delphi
  1. const
  2. BidiAlignment: array[Boolean, taLeftJustify..taCenter] = (...);

O así:


delphi
  1. type
  2. TAligmentRange = taLeftJustify..taCenter;
  3.  
  4. const
  5. BidiAlignment: array[Boolean, TAligmentRange] = (...);

Tu error está en que TAligment sólo admite uno de 3 posibles valores, en cada momento. No está definido como sub rango. Esta es la declaración de TAligment:


delphi
  1. type
  2. TAlignment = (taLeftJustify, taRightJustify, taCenter);

Este array que definí ahora si espera las 6 combinaciones posibles dadas por los valores false, true, taLeftJustify, taRightJustify y taCenter. Eso queda claro, lo que hace "ruido" es lo se espera almacenar en él y lo que se termina regresando en la función... Su implementación y uso suena confusa. Si la idea es que la función haga un "Flip" el parámetro boolean está demás. En todo caso sería "CanFlip". ¿Me explico?

Por ejemplo, Si el valor es false, no tiene que hacer un flip, por lo tanto debería regresar el propio valor, solamente tiene sentido devolver el "opuesto" cuando es true. Y encima aplica a 2 de los 3 posibles valores ya que taCenter no tiene "opuesto". El valor a devolver se dedude del propio valor, no tiene sentido guardar las combinaciones posibles.

 

Me parece a mi que podría encararse de forma más simple.

 

Ahora, por el segundo error:

Un ShowMessage me cuesta creer que ocasione un motivo por el que falle, sobre todo en Windows y no en Linux (tiene más sentido lo inverso convengamos). Más bien en lo que yo pensaría que está el problema es en la línea anterior: el procedimiento GraboTempAsientos.

¿Que hace ese procedimiento?

 

¿Crea algo? Un Access Violation es justamente un error debido a un intento de hacer uso de una memoria no reservada. Casos típicos de un objeto no instanciado... o que fue liberado y se está intentando acceder posteriormente. Y esto me hace mirar a las siguientes líneas, cuando creas ese form modal. ¿Ese form tiene algo en el evento OnClose y/o OnCloseQuery? ¿La variable FormRegDiario es global o local?

 

Y un detalle adicional, la forma en como estás pretendiendo usar las ventanas modales no cuadra. Estás pretendiendo liberar el form modal al momento de mostrarlo. Básicamente tu código dice:

Crea, Muestra y Libera todo de una vez. El try actúa modo de "transacción", o ejecuta todo bien, o nada. Las sentencias se realizan de forma atómica.

El problema está en que una llamada a ShowModal hace que la aplicación se ponga en "modo de espera" hasta que el usuario cierre ese form modal y por tanto el procedimiento que debería hacerse atómicamente está siendo pausado de manera forzada contra su voluntad.

 

La forma de usar try con ShowModal en todo caso es así:


delphi
  1. try
  2. Dialogo.ShowModal;
  3. finally
  4. Dialogo.Free;
  5. end;

Siendo Dialogo un form que se destinará como uso de form modal.

Ten muy presente cual es el propósito de una ventana modal. Como esto impide la ejecución normal de la aplicación y se queda esperando la intervención del usuario su uso principalmente está pensado para ventanas de diálogo y/o avisos y que requieren de una invertención forzoza de parte del usuario. Una vez aceptado/confirmado es que la aplicación puede continuar con la ejecución normal.

No hay que abusar de ventanas modales.

 

Deberías aclararnos bien que es lo que estás intentando hacer, y comentarnos todos los errores escritos en inglés.

Me extraña que digas que en Linux te deje trabajar y no en Windows por ese ShowMessage. Hay algo más profundo por analizar... Cuanto más nos puedas decir al respecto más fácil será asesorarte.

Te sugiero que hagas una traza a tu código, ayúdate del debug y los puntos de interrupción. Ve paso a paso por las líneas de código para detectar exactamente cual es el problema del Access Violation.

 

Saludos,


  • 1

#4 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.833 mensajes
  • LocationArgentina

Escrito 04 febrero 2017 - 12:57

Hay... caramba...

Debo estar dormido, la función BidiFlipAligment es propia de Lazarus, en la unidad Controls. Recién me doy cuenta. Entonces el código anterior es legal y debería por tanto funcionar. No hagas mucho caso a la primera parte de mi anterior post.

 

Veamos el problema del ShowMessage. Yo considero que debes revisar bien lo que hace ese GraboTempAsientos. Y también el uso de ese form modal.

 

Si por algún motivo la seguidilla de errores te lleva a la línea esa que dices (2751 de Controls) hay que ver pasos atrás que se hace como para que se haya invocado a esta función. Es posible que se esté intentando crear algún edit, label o algún otro control que tenga Aligment en algún form... y la memoria no está disponible.

 

Seguramente tenemos una versión diferente de Lazarus/CodeTyphon y por consiguiente diferentes versiones de la unidad Controls.

Yo estoy con CT 5.9, y con éste la función BidiFlipAligment está implementada en la línea 2777 y la línea que tu dices que reporta el error es la 2785. En la 2751 observo otra cosa y pertenece al procedimiento AdjustBorderSpace().

 

Saludos,


  • 1

#5 Gaston

Gaston

    Advanced Member

  • Miembros
  • PipPipPip
  • 63 mensajes

Escrito 04 febrero 2017 - 04:25

Hola. egostar,

Como estas cosas son del demonio, vamos a ver que pasa.

Coloca en lugar del shiwmesage una pausa de digamos 100 ms, en delphi de usa el sleep(100) no se en Lazarus.

Saludos

 

Hola egostar, se me ocurrió eso en la madrugada, tampoco resulto, ahora cuento como lo solucioné.

 

Saludos.


  • 0

#6 Gaston

Gaston

    Advanced Member

  • Miembros
  • PipPipPip
  • 63 mensajes

Escrito 04 febrero 2017 - 04:42

Hay... caramba...

Debo estar dormido, la función BidiFlipAligment es propia de Lazarus, en la unidad Controls. Recién me doy cuenta. Entonces el código anterior es legal y debería por tanto funcionar. No hagas mucho caso a la primera parte de mi anterior post.

 

Veamos el problema del ShowMessage. Yo considero que debes revisar bien lo que hace ese GraboTempAsientos. Y también el uso de ese form modal.

 

Si por algún motivo la seguidilla de errores te lleva a la línea esa que dices (2751 de Controls) hay que ver pasos atrás que se hace como para que se haya invocado a esta función. Es posible que se esté intentando crear algún edit, label o algún otro control que tenga Aligment en algún form... y la memoria no está disponible.

 

Seguramente tenemos una versión diferente de Lazarus/CodeTyphon y por consiguiente diferentes versiones de la unidad Controls.

Yo estoy con CT 5.9, y con éste la función BidiFlipAligment está implementada en la línea 2777 y la línea que tu dices que reporta el error es la 2785. En la 2751 observo otra cosa y pertenece al procedimiento AdjustBorderSpace().

 

Saludos,

 

Hola Delphius, en realidad ShowMessage me solucionaba el problema en Windows, porque en Linux el programa funciona correctamente.

Como no soy miuy amigo de los try ... finally los quité pero eso tampoco solucionó nada. Ya ni recuerdo muy bien como, pero supuse que el problema era el DBGrid, entonces opté por agregarle un visible:=False y aunque no lo crean, eso sí funcionó, creo que debe ser un pequeño bug o que la forma correcta es además de inhabilitar el dbgird, hacerlo invisible.


delphi
  1. DBGridAs.Enabled:=False;
  2. DBGridAs.Visible:=False; //<-------------------Agregué esto
  3. DMConta.ZQGridAS.DisableControls;
  4. GraboTempAsientos;
  5. FormRegDiario:=TFormRegDiario.Create(nil);
  6. FormRegDiario.ShowModal;
  7. FreeAndNil(FormRegDiario);
  8. DMConta.ZQGridAS.SQL.Text:=sqlgrid;
  9. DMConta.ZQGridAS.Open;
  10. DMConta.ZQGridAS.EnableControls;
  11. DBGridAs.Enabled:=True;
  12. DBGridAs.Visible:=True;

Eso así funciona correctamente.

Ya de por sí era raro un error de BidiAligment porque nunca toco esa propiedad de ningún objeto.

 

Respecto de esto:


delphi
  1. FormRegDiario:=TFormRegDiario.Create(nil);
  2. FormRegDiario.ShowModal;
  3. FreeAndNil(FormRegDiario);

Es, digamos, un hábito que adquirí leyendo por ahí, lo uso para casi todos los formularios del programa (un programa contable) y me da muy buenos resultados. Lo que sí, al crearse así los Formularios, la única manera de mostrarlos es con showmodal, ya que con show no lo muestra, he leído las explicaciones de por qué no lo muestra, pero no encontré la solución, así que si quiero un Form que se pueda mostrar con el método Show y no showmodal, deberé dejar que se cree automáticamente al inicio, pero ya me estoy yendo de tema.

 

Gracias a todos por su ayuda.

 

Saludos.


  • 1