PDA

Ver la Versión Completa : Stack Overflow


Mariana
23-10-2003, 16:59:19
hola a todos, quería preguntarles lo siguiente:

Hice un aplicación, y la instalé en la máquina del cliente...tiene una primer pantalla donde se cargan datos de personas...
y en la máquina del cliente cuando están cargando los datos aparece un mensaje de Stack Overflow y se cierra la aplicación(esto en mi máquina no lo hace), alguien me puede dar una idea de que se trata... (en las dos máquinas está Windows XP).
También cuando se activa el protector de pantalla (en la máquina dedl cliente se cuelga)...
Si alguien me puede dar una idea se lo voy a agradecer pq estoy desesperada..
Gracias.
Mariana

Viet
23-10-2003, 17:05:05
Hola mariana,

lo del protector de pantalla , ni idea... eso me suena mas a un error del XP.

Pero el error del Stack Overflow debe ser un problema de codigo en la carga de los datos o bien en la conexion...

Danos info sobre lo que hace tu aplicacion cuando se carga, asi vemos que puede ser

Mariana
23-10-2003, 17:16:46
les cuento un poco mas de la aplicación.

-usa tablas dbase for windows
-la carga el de datos personales (nombre, tel, dir, etc), y desde la aplicación lo hace con un append, genera un código para la persona que se está ingresando, pero no llega a grabarlo pq se cuelga antes.
- para instalarlo en la máquina del ciente hice un instalador con el InstallShield
- no se que más describir ya que no llega a hacer nada más que abrir una ventana, un append en una tabla, empiezan a cargar los datos y aparece el mensaje. pero lo más raro es que en mi máquina si funciona.
Espero que me puedan ayudar, gracias.
Mariana.

andres1569
23-10-2003, 18:37:20
Hola:

"Stack Overflow" o desbordamiento de pila, es un error frecuente, como se ha dicho en un hilo de hoy mismo, de cuando en una función se crea una recursión infinita, es decir, un bucle cerrado de llamadas a la misma función; la pila se va llenando de nuevas llamadas a la función, con su carga añadida de variables... etc, hasta que se desborda.

Para poder encontrar el error, haría falta por nuetra parte ver el código. El hecho de que se produzca en una máquina y no en otra, más aún teniendo el mismo SO, para el caso concreto que planteas, ¿pudiera estar relacionado con que en un caso se dispara un evento en el Append que ocasiona la llamada recursiva, y en el otro no se llama a Append, porque no precisa esos datos, por ejemplo? Son suposiciones, pero haría falta ver el código.

Mariana
24-10-2003, 05:10:04
Andres,

Este es el código (de la opción nuevo del main menú) de la unidad principal donde se llama a la segunda unidad, en la que el usuario carga los datos (en la que aparece el stack overflow).
En esa unidad hay dbedits para cada campo de la tabla que se carga y cuando están completando los datos es cuando se cuelga.

procedure TConsultorio.Nuevo1Click(Sender: TObject);
begin

//deshabilita todos los botones menos aceptar y salir pq es uno nuevo
Application.CreateForm(Tform2, form2);
form2.bborrar.enabled:=false;
form2.lborrar.enabled:=false;
form2.bmodif.enabled:=false;
form2.lmodif.enabled:=false;
form2.bmodif2.enabled:=false;
form2.lmodif2.enabled:=false;
form2.bderivacion.enabled:=false;
form2.lderivacion.enabled:=false;
form2.brecita.enabled:=false;
form2.lrecita.enabled:=false;
form2.bimprimir.enabled:=false;
form2.limprimir.enabled:=false;
form2.bhcimprimir.enabled:=false;
form2.lhcimprimir.enabled:=false;
form2.baceptar.Enabled:=true;
form2.laceptar.Enabled:=true;
form2.baceptar2.Enabled:=true;
form2.laceptar2.Enabled:=true;
form2.bplan.Enabled:=false;
form2.lplan.Enabled:=false;
form2.bhistorial.Enabled:=false;
form2.lhistorial.Enabled:=false;
//dehabilta derivacion
form2.Ldbderivacion.enabled:=false;
form2.dbderivacion.enabled:=false;
// marca nuevo
paciente.nuevo:=true;
form2.comboNyAp.Visible:=false;
form2.editNyAp.Visible:=true;
//generar codigo paciente nuevo
codigopaciente;
modulodatos.modat.Paciente.append;
modulodatos.modat.Paciente.edit;
modulodatos.modat.Paciente.FieldByName('codigop').asinteger:=codigop;
modulodatos.modat.HistoriaClinica.append;
modulodatos.modat.HistoriaClinica.edit;
modulodatos.modat.HistoriaClinica.FieldByName('codigop').asinteger:=codigop;
form2.ShowModal;
modulodatos.modat.Paciente.Refresh;
modulodatos.modat.HistoriaClinica.Refresh;
end;

Espero que con esto me puedas ayudar,
Muchas, Muchas Gracias
Mariana.

andres1569
24-10-2003, 12:17:13
Hola:

Del código que pones no veo donde pueda saltar un "Stack overflow", aunque sería bueno que indicases si tienes algún evento asociado a los Datasets que manejas.

Decirte además que si haces un Append, el Edit anterior es innecesario. Echo de menos el Post para validar la modificación, a ver si al no grabar y hacer el refresh se queda ese dato sin grabar y por eso se repite la operación (ahora mismo no estoy seguro ni lo puedo mirar, si el refresh aborta la edición sin validarla).

Otra consideración, que no tiene que ver con el problema planteado. Todas esas sentencias poniendo Enabled a FALSE sería mejor hacerlas dentro de la unit del Form2, mejor aún desde un procedimiento que recorriera los componentes:

for i:=0 to ComponentCount - 1 do
if Components[i] is TButton then // Y alguna condición más
TButton(Components[i]).Enabled := FALSE;
Aunque no entiendo, si ese código se ejecuta al crear un Form2, por qué no los deshabilitas en diseño.

A ver si esto te sirve, saludos

jachguate
24-10-2003, 12:36:26
Hola Mariana.

Quisiera recomendarte el uso de etiquetas [ code ] y [ /code ] cuando introduzcas código en un hilo. La diferencia es enorme...

procedure TConsultorio.Nuevo1Click(Sender: TObject);
begin

//deshabilita todos los botones menos aceptar y salir pq es uno nuevo
Application.CreateForm(Tform2, form2);
form2.bborrar.enabled:=false;
form2.lborrar.enabled:=false;
form2.bmodif.enabled:=false;

Vs:


procedure TConsultorio.Nuevo1Click(Sender: TObject);
begin
//deshabilita todos los botones menos aceptar y salir pq es uno nuevo
Application.CreateForm(Tform2, form2);
form2.bborrar.enabled:=false;
form2.lborrar.enabled:=false;
form2.bmodif.enabled:=false;
..
End;



Ves??.

Además, es realmente necesaria la llamada a Edit despues de append?? Me parece que no. Porque no aclaras un poco que eventos tenes relacionados a cada DataSet, quizas con las partes mas relevantes del código?...

Hasta luego.

;)

Mariana
24-10-2003, 14:45:05
Andres:

Gracias por tu respuesta,
- no tengo ningún evento asociado a los datasets que manejo, lo único que hago es cargar datos de la mima forma que mostré.
- El edit está puesto pq en algunas ocasiones al hacer el append no me permitía agregar los datos (el error decía que la tabla no estaba en modo de edit o insert ), y esta fue la única forma que encontré de solucionarlo.
- El Post se hace en el form2 antes de cerrarlo, por esto en el form principal después del showmodal hago el refresh de la tabla.
- Con respecto a la deshabilitación de los botones, es cierto lo que me indicas, pero el form2 lo llamo desde 2 ítems del main menú, en este caso los necesito dehabilitados, en el otro habilitados, de manera que si en diseño los pongo deshabilitados en la otra opción voy a tener que habilitarlos.


Jachguate:

Gracias por tu sugerencia, el tema del edit lo comenté arriba.

Gracias a todos.
Mariana.

andres1569
24-10-2003, 17:37:33
Hola:

Me resulta extraño que Append no te deje la tabla en estado de edición (en ese caso de inserción: dsInsert), la única razón que se me ocurre es que en el BeforeInsert de la tabla tuvieras algún código que "cerrara la edición".

Por otro lado, hay una llamada a un procedimiento "codigopaciente" que convendría ojear.

De todas formas, si te ocurre el error en otra máquina y en aquella no tienes instalado Delphi para debuguear, yo en tu caso pondría varios mensajes en puntos estratégicos de ese código, al estilo:

Form2.Tabla.Edit;
ShowMessage ('Paso 1');
codigopaciente;
ShowMessage ('Paso 2');

Aunque algo molesto, puede ayudarte a encontrar la línea que origina el error.

Mariana
27-10-2003, 04:54:10
Andres:

Gracias por tus respuestas, pero estoy empezando a pensar que no es problema del código, y mis preguntas ahora son:
- puede ser originado el problema por tener muchas ventanas activas a la vez?
- puede ser originado por algún problema de Windows XP?
Muchas Gracias
Mariana.

andres1569
27-10-2003, 10:29:22
Hola:

El "stack overflow" como dije anteriormente, tiene toda la pinta de saltar porque has entrado en un bucle infinito de llamadas recursivas, puede ser por otras razones, pero esa es, al menos, la que más veces he visto. Lo de tener varias ventanas no debe influir, en teoría, otra cosa es que llamen a funciones comunes y que éstas entren en recursividad.

Lo de ser debido a XP, bueno, tú dijiste que en dos máquinas XP, en una iba y en otra no, así que parece descartable esa posibilidad.

¿Has probado lo de poner "mensajes debugeadores", como te sugerí?

Saludos

Lepe
27-10-2003, 12:28:36
- El edit está puesto pq en algunas ocasiones al hacer el append no me permitía agregar los datos (el error decía que la tabla no estaba en modo de edit o insert ), y esta fue la única forma que encontré de solucionarlo.



if not ( modulodatos.modat.Paciente.State in dsEditModes) then
modulodatos.modat.Paciente.Edit;

Append deja el registro en modo de edición, si algunas veces no te deja, es que ha ocurrido algun error, por lo que deberias considerar el uso de los eventos de la tabla paciente para que, en caso de error, te avise. (OnPostError, OnEditError....)

codigopaciente;

Al parecer eso prepara algunos datos para crear el paciente, seria muy conveniente hacer uso del evento OnNewRecord de la tabla correspondiente para inicializar valores de los campos. Ya que es donde debe hacerse.

El Form2 es Modal, se permite cancelar el alta del registro???
si se permite, que pasa con el nuevo registro que ya has añadido ?

Lo que quiero decir, para saber si funciona bien, deberiamos saber que hace codigopaciente y el Form2

Saludos, y espero aclarar algo en lugar de liarlo más.

Mariana
30-10-2003, 05:20:58
Gracias por las respuestas, les contesto lo que me preguntan:

Andres: Con respecto a los mensajes no los puse aún porque todavía no volví a tener acceso a la máquina del cliente, pero de todos modos las sentencias que están allí las pasa porque el error surge en el form2.
No tengo ninguna función recursiva, de manera que no creo que se generen llamadas de este tipo.

Lepe: codigopaciente es una función que genera un código (usando la función random), fijándose que no este en la tabla (es la clave del nuevo registro).
En el form2, tiene la opción de cancelar (cancel de la tabla), o de guardar (post).

Gracias a todos por las respuestas, y si tiene alguna otra idea se los voy a agradecer.
Mariana.

Mariana
30-10-2003, 05:21:01
Gracias por las respuestas, les contesto lo que me preguntan:

Andres: Con respecto a los mensajes no los puse aún porque todavía no volví a tener acceso a la máquina del cliente, pero de todos modos las sentencias que están allí las pasa porque el error surge en el form2.
No tengo ninguna función recursiva, de manera que no creo que se generen llamadas de este tipo.

Lepe: codigopaciente es una función que genera un código (usando la función random), fijándose que no este en la tabla (es la clave del nuevo registro).
En el form2, tiene la opción de cancelar (cancel de la tabla), o de guardar (post).

Gracias a todos por las respuestas, y si tiene alguna otra idea se los voy a agradecer.
Mariana.

Lepe
30-10-2003, 11:37:47
No hace falta que haga llamadas recursivas, puedes provocarlas por un simple fallito, imagina esta secuencia.

Llamas a Append, y allí cambias el valor de un campo, y despues tienes puesto que en el Onchange de un campo haga tal o cual cosa.... ya se están provocando llamadas "silenciosas" que se te pueden pasar por alto. Sé que éste no es tu caso, ya que dices que no tienes eventos asignados, pero es un ejemplo de lo que puede ocurrir.

Fallos en una Base de datos puede haber miles y miles, si no tienes eventos asignados, se te puede ir por peteneras y no enterarte de nada :(

los ShowMessages es una alternativa cuando estas desarrollando el programa en tu ordenador, tambien podrías hacer un simple fichero de texto e ir añadiendo los mensajes a ese fichero. Siempre puedes enviar un millon de mensajes para que una sola ejecución, saber donde falla.

Suerte !!