2009-12-03 19 views
5

Tengo una aplicación escrita en Delphi W32 que está en versión beta.Ejecutando un error de "desbordamiento de pila"

En la PC de prueba, al azar lanza un mensaje de 'desbordamiento de pila' después de unas horas de uso.

¿Cómo puedo interceptar el error y encontrar la causa?

¿Puedo aumentar el tamaño de la pila?

+0

elevar el tamaño de la pila casi seguramente retrasará la resistencia, quizás debería reducirla para detectar el problema más temprano? – Mawg

Respuesta

13

Obtenga madExcept y le dirá exactamente lo que está sucediendo en el momento de la falla. Verás la pila completa, y particularmente donde se está escapando.

+1

+1 También puede utilizar cualquier otro marco de seguimiento de excepciones, por supuesto (EurekaLog o JCL para nombrar solo dos). – jpfollenius

+0

+1. MadExcept y JclDebug son cosas que no puedes vivir sin ellas. –

+3

Ah, y ¿Has considerado recursion interminable? ¿Sus algoritmos recursivos verifican y generan excepciones a una profundidad máxima? –

6

que casi había dicen: ejecuta en el depurador; ^)

lo que solía hacer es añadir una función de entrada y salida de entrar en cada método. Con la sangría adecuada podría rastrear en el registro la ruta de la llamada.

Cuando un stackoverflow ocurriría realmente sería visible en el registro ya que el nivel de sangrado debe ser a través del techo

void someMethod() 
{ 
     logMethodEnter("someMethod"); 

     ... do stuff... 
     log("something") 
     ... do stuff... 

     logMethodLeave("someMethod"); 

} 

el registrador podría realizar un seguimiento de logdepth actual y registrar cosas como esta:

>someMethod 
    something 
<someMethod 
0

Puede aumentar el tamaño de la pila usando las opciones del enlazador del proyecto o la directiva del compilador $ M, pero no creo que resuelva el problema ya que la pila es realmente pequeña.

Si ejecuta la aplicación en el depurador, eventualmente se romperá en la excepción.

2

¿Tiene el IDE instalado en la máquina de prueba? Si es así, intente reproducir el problema desde el IDE. Cuando se produce el desbordamiento de la pila, observe la Pila de llamadas (Ver-> Depurar Windows-> Pila de llamadas). Es probable que tenga la misma función que se llama muchas veces, como esta:

FunctionA 
FunctionB 
FunctionA 
FunctionB 
FunctionA 
FunctionB 
... 

Si usted ve que, a continuación, usted sabe que estas funciones se llaman entre sí sin tener que concluir.

Si no tiene el IDE instalado en la máquina de prueba, puede hacerlo a través de la depuración remota. Si proporciona un poco más de información sobre su situación hipotética, podremos ayudarlo más.

Específicamente, puede ser útil saber:

  • ¿Puede reproducirlo?
  • ¿Está instalado el IDE en la máquina de prueba ?
  • ¿Qué versión de Delphi?
15

Debe REDUCIR el tamaño de la pila en las opciones del vinculador. Luego ejecútelo bajo el depurador y con suerte el problema aparecerá sin tener que esperar dos horas.

+0

Niiice idea !! Una forma muy inteligente de detectar el error más rápido. Aunque debe tener en cuenta el antiguo valor de la pila ... ;-) +1 –

0

Si está utilizando un hilo (no principal, por ejemplo, una conexión de calcetín) y el hilo principal para que compartan la misma pila. Resuelve de esta manera: simplemente crea un hilo con su propia pila para cada conexión.

Problema> cada llamada que usted hace llama a la pila para el marco (el problema tan grande compartido) ejemplo que llama proc aa (a, b: integer) por ejemplo al llamar siempre la misma función o una diferente;

Tiene un hilo de socket ejecutándose, y onconnect llama a proc a; y se queda haciendo algo, demora 5 segundos.

si alguien se conecta antes de la conexión de conexión directa (pila de liberación). Tiene las 2 clientes conectados (marcos de pila 2 diff con cada dato diferentes)

pila

empuje a, b (número entero); Valores 5,10 - desde 1 conn

push a, b (integer); Valores 7,3 - desde 2 conn

si el onconnect llama a las funciones a (5,10) y se queda haciendo algo durante aproximadamente 5 segundos. y alguien se conecta al servidor de nuevo, vuelve a llamar para volver a conectarse.

La pila antigua, el primer marco de llamada, aún no salió de proceso. Así que no apareció a, b de (5,10)

Es más complejo que esto si se vuelve a llamar, entonces sobrescribirá los datos en el 2 fotograma (variable de proc local de 2 conexiones) así que cuando 2 conexiones obtener datos de la pila ya está anulado por otra información para asegurarse. por lo que hará un comportamiento incorrecto.

Cuando la primera conexión está desconectada aparecerá a, b pero 7,3 (desde la segunda conexión) y no la 5,10 guardada. por lo tanto, acumulará desbordamiento no en el momento, pero más tarde con el programa ejecutándose y los errores de lanzamiento de la pila obtendrá finalmente una pila $FFFFFFFF $SP. por lo que tratará de $FFFFFFAA cuando llame a una función, por lo que es más grande que ya stack ex: $M 65536 y no 4 gigabytes como $FFFFFFAA.

Cuestiones relacionadas